Complete the Pyflakes documention (#4787)

This commit is contained in:
Tom Kuson 2023-06-01 21:25:32 +01:00 committed by GitHub
parent b7038cee13
commit d9fdcebfc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 257 additions and 0 deletions

View File

@ -3,6 +3,21 @@ use rustpython_parser::ast::{self, Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation}; use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
/// ## What it does
/// Checks for `break` statements outside of loops.
///
/// ## Why is this bad?
/// The use of a `break` statement outside of a `for` or `while` loop will
/// raise a `SyntaxError`.
///
/// ## Example
/// ```python
/// def foo():
/// break
/// ```
///
/// ## References
/// - [Python documentation: `break`](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement)
#[violation] #[violation]
pub struct BreakOutsideLoop; pub struct BreakOutsideLoop;

View File

@ -3,6 +3,21 @@ use rustpython_parser::ast::{self, Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation}; use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
/// ## What it does
/// Checks for `continue` statements outside of loops.
///
/// ## Why is this bad?
/// The use of a `continue` statement outside of a `for` or `while` loop will
/// raise a `SyntaxError`.
///
/// ## Example
/// ```python
/// def foo():
/// continue # SyntaxError
/// ```
///
/// ## References
/// - [Python documentation: `continue`](https://docs.python.org/3/reference/simple_stmts.html#the-continue-statement)
#[violation] #[violation]
pub struct ContinueOutsideLoop; pub struct ContinueOutsideLoop;

View File

@ -5,6 +5,44 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::except_range; use ruff_python_ast::helpers::except_range;
use ruff_python_ast::source_code::Locator; use ruff_python_ast::source_code::Locator;
/// ## What it does
/// Checks for `except` blocks that handle all exceptions, but are not the last
/// `except` block in a `try` statement.
///
/// ## Why is this bad?
/// When an exception is raised within a `try` block, the `except` blocks are
/// evaluated in order, and the first matching block is executed. If an `except`
/// block handles all exceptions, but isn't the last block, Python will raise a
/// `SyntaxError`, as the following blocks would never be executed.
///
/// ## Example
/// ```python
/// def reciprocal(n):
/// try:
/// reciprocal = 1 / n
/// except:
/// print("An exception occurred.")
/// except ZeroDivisionError:
/// print("Cannot divide by zero.")
/// else:
/// return reciprocal
/// ```
///
/// Use instead:
/// ```python
/// def reciprocal(n):
/// try:
/// reciprocal = 1 / n
/// except ZeroDivisionError:
/// print("Cannot divide by zero.")
/// except:
/// print("An exception occurred.")
/// else:
/// return reciprocal
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/reference/compound_stmts.html#except-clause)
#[violation] #[violation]
pub struct DefaultExceptNotLast; pub struct DefaultExceptNotLast;

View File

@ -1,6 +1,27 @@
use ruff_diagnostics::Violation; use ruff_diagnostics::Violation;
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
/// ## What it does
/// Checks for forward annotations that include invalid syntax.
///
///
/// ## Why is this bad?
/// In Python, type annotations can be quoted as strings literals to enable
/// references to types that have not yet been defined, known as "forward
/// references".
///
/// However, these quoted annotations must be valid Python expressions. The use
/// of invalid syntax in a quoted annotation won't raise a `SyntaxError`, but
/// will instead raise an error when type checking is performed.
///
/// ## Example
/// ```python
/// def foo() -> "/":
/// ...
/// ```
///
/// ## References
/// - [PEP 563](https://www.python.org/dev/peps/pep-0563/)
#[violation] #[violation]
pub struct ForwardAnnotationSyntaxError { pub struct ForwardAnnotationSyntaxError {
pub body: String, pub body: String,

View File

@ -6,6 +6,34 @@ use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
use crate::registry::AsRule; use crate::registry::AsRule;
/// ## What it does
/// Checks for `raise` statements that raise `NotImplemented`.
///
/// ## Why is this bad?
/// `NotImplemented` is an exception used by binary special methods to indicate
/// that an operation is not implemented with respect to a particular type.
///
/// `NotImplemented` should not be raised directly. Instead, raise
/// `NotImplementedError`, which is used to indicate that the method is
/// abstract or not implemented in the derived class.
///
/// ## Example
/// ```python
/// class Foo:
/// def bar(self):
/// raise NotImplemented
/// ```
///
/// Use instead:
/// ```python
/// class Foo:
/// def bar(self):
/// raise NotImplementedError
/// ```
///
/// ## References
/// - [Python documentation: `NotImplemented`](https://docs.python.org/3/library/constants.html#NotImplemented)
/// - [Python documentation: `NotImplementedError`](https://docs.python.org/3/library/exceptions.html#NotImplementedError)
#[violation] #[violation]
pub struct RaiseNotImplemented; pub struct RaiseNotImplemented;

View File

@ -2,6 +2,26 @@ use ruff_diagnostics::Violation;
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::source_code::OneIndexed; use ruff_python_ast::source_code::OneIndexed;
/// ## What it does
/// Checks for variable definitions that redefine (or "shadow") unused
/// variables.
///
/// ## Why is this bad?
/// Redefinitions of unused names are unnecessary and often indicative of a
/// mistake.
///
/// ## Example
/// ```python
/// import foo
/// import bar
/// import foo # Redefinition of unused `foo` from line 1
/// ```
///
/// Use instead:
/// ```python
/// import foo
/// import bar
/// ```
#[violation] #[violation]
pub struct RedefinedWhileUnused { pub struct RedefinedWhileUnused {
pub name: String, pub name: String,

View File

@ -6,6 +6,21 @@ use ruff_python_semantic::scope::ScopeKind;
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for `return` statements outside of functions.
///
/// ## Why is this bad?
/// The use of a `return` statement outside of a function will raise a
/// `SyntaxError`.
///
/// ## Example
/// ```python
/// class Foo:
/// return 1
/// ```
///
/// ## References
/// - [Python documentation: `return`](https://docs.python.org/3/reference/simple_stmts.html#the-return-statement)
#[violation] #[violation]
pub struct ReturnOutsideFunction; pub struct ReturnOutsideFunction;

View File

@ -4,6 +4,36 @@ use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
use ruff_python_semantic::scope::Scope; use ruff_python_semantic::scope::Scope;
/// ## What it does
/// Checks for undefined names in `__all__`.
///
/// ## Why is this bad?
/// In Python, the `__all__` variable is used to define the names that are
/// exported when a module is imported as a wildcard (e.g.,
/// `from foo import *`). The names in `__all__` must be defined in the module,
/// but are included as strings.
///
/// Including an undefined name in `__all__` is likely to raise `NameError` at
/// runtime, when the module is imported.
///
/// ## Example
/// ```python
/// from foo import bar
///
///
/// __all__ = ["bar", "baz"] # undefined name `baz` in `__all__`
/// ```
///
/// Use instead:
/// ```python
/// from foo import bar, baz
///
///
/// __all__ = ["bar", "baz"]
/// ```
///
/// ## References
/// - [Python documentation: `__all__`](https://docs.python.org/3/tutorial/modules.html#importing-from-a-package)
#[violation] #[violation]
pub struct UndefinedExport { pub struct UndefinedExport {
name: String, name: String,

View File

@ -5,6 +5,31 @@ use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for undefined local variables.
///
/// ## Why is this bad?
/// Referencing a local variable before it has been assigned will raise
/// an `UnboundLocalError` at runtime.
///
/// ## Example
/// ```python
/// x = 1
///
///
/// def foo():
/// x += 1
/// ```
///
/// Use instead:
/// ```python
/// x = 1
///
///
/// def foo():
/// global x
/// x += 1
/// ```
#[violation] #[violation]
pub struct UndefinedLocal { pub struct UndefinedLocal {
name: String, name: String,

View File

@ -1,6 +1,26 @@
use ruff_diagnostics::Violation; use ruff_diagnostics::Violation;
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
/// ## What it does
/// Checks for uses of undefined names.
///
/// ## Why is this bad?
/// An undefined name is likely to raise `NameError` at runtime.
///
/// ## Example
/// ```python
/// def double():
/// return n * 2 # raises `NameError` if `n` is undefined when `double` is called
/// ```
///
/// Use instead:
/// ```python
/// def double(n):
/// return n * 2
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/reference/executionmodel.html#naming-and-binding)
#[violation] #[violation]
pub struct UndefinedName { pub struct UndefinedName {
pub name: String, pub name: String,

View File

@ -4,6 +4,21 @@ use ruff_python_semantic::scope::ScopeId;
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for local variables that are annotated but never used.
///
/// ## Why is this bad?
/// Annotations are used to provide type hints to static type checkers. If a
/// variable is annotated but never used, the annotation is unnecessary.
///
/// ## Example
/// ```python
/// def foo():
/// bar: int
/// ```
///
/// ## References
/// - [PEP 484](https://peps.python.org/pep-0484/)
#[violation] #[violation]
pub struct UnusedAnnotation { pub struct UnusedAnnotation {
name: String, name: String,

View File

@ -25,6 +25,21 @@ impl fmt::Display for DeferralKeyword {
} }
} }
/// ## What it does
/// Checks for `yield` and `yield from` statements outside of functions.
///
/// ## Why is this bad?
/// The use of a `yield` or `yield from` statement outside of a function will
/// raise a `SyntaxError`.
///
/// ## Example
/// ```python
/// class Foo:
/// yield 1
/// ```
///
/// ## References
/// - [Python documentation: `yield`](https://docs.python.org/3/reference/simple_stmts.html#the-yield-statement)
#[violation] #[violation]
pub struct YieldOutsideFunction { pub struct YieldOutsideFunction {
keyword: DeferralKeyword, keyword: DeferralKeyword,