mirror of https://github.com/astral-sh/ruff
Complete the Pyflakes documention (#4787)
This commit is contained in:
parent
b7038cee13
commit
d9fdcebfc1
|
|
@ -3,6 +3,21 @@ use rustpython_parser::ast::{self, Ranged, Stmt};
|
|||
use ruff_diagnostics::{Diagnostic, 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]
|
||||
pub struct BreakOutsideLoop;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,21 @@ use rustpython_parser::ast::{self, Ranged, Stmt};
|
|||
use ruff_diagnostics::{Diagnostic, 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]
|
||||
pub struct ContinueOutsideLoop;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,44 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
use ruff_python_ast::helpers::except_range;
|
||||
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]
|
||||
pub struct DefaultExceptNotLast;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,27 @@
|
|||
use ruff_diagnostics::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]
|
||||
pub struct ForwardAnnotationSyntaxError {
|
||||
pub body: String,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,34 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
use crate::checkers::ast::Checker;
|
||||
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]
|
||||
pub struct RaiseNotImplemented;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,26 @@ use ruff_diagnostics::Violation;
|
|||
use ruff_macros::{derive_message_formats, violation};
|
||||
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]
|
||||
pub struct RedefinedWhileUnused {
|
||||
pub name: String,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,21 @@ use ruff_python_semantic::scope::ScopeKind;
|
|||
|
||||
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]
|
||||
pub struct ReturnOutsideFunction;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,36 @@ use ruff_diagnostics::{Diagnostic, Violation};
|
|||
use ruff_macros::{derive_message_formats, violation};
|
||||
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]
|
||||
pub struct UndefinedExport {
|
||||
name: String,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,31 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
|
||||
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]
|
||||
pub struct UndefinedLocal {
|
||||
name: String,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,26 @@
|
|||
use ruff_diagnostics::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]
|
||||
pub struct UndefinedName {
|
||||
pub name: String,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,21 @@ use ruff_python_semantic::scope::ScopeId;
|
|||
|
||||
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]
|
||||
pub struct UnusedAnnotation {
|
||||
name: String,
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
pub struct YieldOutsideFunction {
|
||||
keyword: DeferralKeyword,
|
||||
|
|
|
|||
Loading…
Reference in New Issue