Add more Pyflakes docs (#4689)

This commit is contained in:
Tom Kuson 2023-05-28 23:29:03 +01:00 committed by GitHub
parent dbeadd99a8
commit 51f04ee6ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 202 additions and 0 deletions

View file

@ -5,6 +5,27 @@ use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for `assert` statements that use non-empty tuples as test
/// conditions.
///
/// ## Why is this bad?
/// Non-empty tuples are always `True`, so an `assert` statement with a
/// non-empty tuple as its test condition will always pass. This is likely a
/// mistake.
///
/// ## Example
/// ```python
/// assert (some_condition,)
/// ```
///
/// Use instead:
/// ```python
/// assert some_condition
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement)
#[violation] #[violation]
pub struct AssertTuple; pub struct AssertTuple;

View file

@ -5,6 +5,27 @@ use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for `if statements that use non-empty tuples as test conditions.
///
/// ## Why is this bad?
/// Non-empty tuples are always `True`, so an `if` statement with a non-empty
/// tuple as its test condition will always pass. This is likely a mistake.
///
/// ## Example
/// ```python
/// if (False,):
/// print("This will always run")
/// ```
///
/// Use instead:
/// ```python
/// if False:
/// print("This will never run")
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement)
#[violation] #[violation]
pub struct IfTuple; pub struct IfTuple;

View file

@ -27,6 +27,41 @@ impl From<&Cmpop> for IsCmpop {
} }
} }
/// ## What it does
/// Checks for `is` and `is not` comparisons against constant literals, like
/// integers and strings.
///
/// ## Why is this bad?
/// The `is` and `is not` comparators operate on identity, in that they check
/// whether two objects are the same object. If the objects are not the same
/// object, the comparison will always be `False`. Using `is` and `is not` with
/// constant literals often works "by accident", but are not guaranteed to produce
/// the expected result.
///
/// As of Python 3.8, using `is` and `is not` with constant literals will produce
/// a `SyntaxWarning`.
///
/// Instead, use `==` and `!=` to compare constant literals, which will compare
/// the values of the objects instead of their identities.
///
/// ## Example
/// ```python
/// x = 200
/// if x is 200:
/// print("It's 200!")
/// ```
///
/// Use instead:
/// ```python
/// x = 200
/// if x == 200:
/// print("It's 200!")
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/reference/expressions.html#is-not)
/// - [Python documentation](https://docs.python.org/3/reference/expressions.html#value-comparisons)
/// - [_Why does Python log a SyntaxWarning for is with literals?_ by Adam Johnson](https://adamj.eu/tech/2020/01/21/why-does-python-3-8-syntaxwarning-for-is-literal/)
#[violation] #[violation]
pub struct IsLiteral { pub struct IsLiteral {
cmpop: IsCmpop, cmpop: IsCmpop,

View file

@ -5,6 +5,46 @@ use ruff_macros::{derive_message_formats, violation};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for `print` statements that use the `>>` syntax.
///
/// ## Why is this bad?
/// In Python 2, the `print` statement can be used with the `>>` syntax to
/// print to a file-like object. This `print >> sys.stderr` syntax is
/// deprecated in Python 3.
///
/// Instead, use the `file` keyword argument to the `print` function, the
/// `sys.stderr.write` function, or the `logging` module.
///
/// ## Example
/// ```python
/// from __future__ import print_function
/// import sys
///
/// print >> sys.stderr, "Hello, world!"
/// ```
///
/// Use instead:
/// ```python
/// print("Hello, world!", file=sys.stderr)
/// ```
///
/// Or:
/// ```python
/// import sys
///
/// sys.stderr.write("Hello, world!\n")
/// ```
///
/// Or:
/// ```python
/// import logging
///
/// logging.error("Hello, world!")
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/library/functions.html#print)
#[violation] #[violation]
pub struct InvalidPrintSyntax; pub struct InvalidPrintSyntax;

View file

@ -10,6 +10,36 @@ use ruff_python_ast::comparable::{ComparableConstant, ComparableExpr};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
use crate::registry::{AsRule, Rule}; use crate::registry::{AsRule, Rule};
/// ## What it does
/// Checks for dictionary literals that associate multiple values with the
/// same key.
///
/// ## Why is this bad?
/// Dictionary keys should be unique. If a key is associated with multiple values,
/// the earlier values will be overwritten. Including multiple values for the
/// same key in a dictionary literal is likely a mistake.
///
/// ## Example
/// ```python
/// foo = {
/// "bar": 1,
/// "baz": 2,
/// "baz": 3,
/// }
/// foo["baz"] # 3
/// ```
///
/// Use instead:
/// ```python
/// foo = {
/// "bar": 1,
/// "baz": 2,
/// }
/// foo["baz"] # 2
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
#[violation] #[violation]
pub struct MultiValueRepeatedKeyLiteral { pub struct MultiValueRepeatedKeyLiteral {
name: String, name: String,
@ -37,6 +67,36 @@ impl Violation for MultiValueRepeatedKeyLiteral {
} }
} }
} }
/// ## What it does
/// Checks for dictionary keys that are repeated with different values.
///
/// ## Why is this bad?
/// Dictionary keys should be unique. If a key is repeated with a different
/// value, the first values will be overwritten and the key will correspond to
/// the last value. This is likely a mistake.
///
/// ## Example
/// ```python
/// foo = {
/// bar: 1,
/// baz: 2,
/// baz: 3,
/// }
/// foo[baz] # 3
/// ```
///
/// Use instead:
/// ```python
/// foo = {
/// bar: 1,
/// baz: 2,
/// }
/// foo[baz] # 2
/// ```
///
/// ## References
/// - [Python documentation](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
#[violation] #[violation]
pub struct MultiValueRepeatedKeyVariable { pub struct MultiValueRepeatedKeyVariable {
name: String, name: String,

View file

@ -4,6 +4,15 @@ use rustpython_parser::ast::Expr;
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 the use of too many expressions in starred assignment statements.
///
/// ## Why is this bad?
/// In assignment statements, starred expressions can be used to unpack iterables.
///
/// In Python 3, no more than 1 << 8 assignments are allowed before a starred
/// expression, and no more than 1 << 24 expressions are allowed after a starred
/// expression.
#[violation] #[violation]
pub struct ExpressionsInStarAssignment; pub struct ExpressionsInStarAssignment;
@ -14,6 +23,22 @@ impl Violation for ExpressionsInStarAssignment {
} }
} }
/// ## What it does
/// Checks for the use of multiple starred expressions in assignment statements.
///
/// ## Why is this bad?
/// In assignment statements, starred expressions can be used to unpack iterables.
/// Including more than one starred expression on the left-hand-side of an
/// assignment will cause a `SyntaxError`, as it is unclear which expression
/// should receive the remaining values.
///
/// ## Example
/// ```python
/// *foo, *bar, baz = (1, 2, 3)
/// ```
///
/// ## References
/// - [PEP 3132](https://peps.python.org/pep-3132/)
#[violation] #[violation]
pub struct MultipleStarredExpressions; pub struct MultipleStarredExpressions;