diff --git a/README.md b/README.md index 231f866294..c37868c1fa 100644 --- a/README.md +++ b/README.md @@ -748,7 +748,7 @@ For more, see [mccabe](https://pypi.org/project/mccabe/) on PyPI. | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| C901 | function-is-too-complex | `{name}` is too complex ({complexity}) | | +| C901 | [function-is-too-complex](https://github.com/charliermarsh/ruff/blob/main/docs/rules/function-is-too-complex.md) | `{name}` is too complex ({complexity}) | | ### isort (I) @@ -756,8 +756,8 @@ For more, see [isort](https://pypi.org/project/isort/) on PyPI. | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| I001 | unsorted-imports | Import block is un-sorted or un-formatted | 🛠 | -| I002 | missing-required-import | Missing required import: `{name}` | 🛠 | +| I001 | [unsorted-imports](https://github.com/charliermarsh/ruff/blob/main/docs/rules/unsorted-imports.md) | Import block is un-sorted or un-formatted | 🛠 | +| I002 | [missing-required-import](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-required-import.md) | Missing required import: `{name}` | 🛠 | ### pep8-naming (N) @@ -899,17 +899,17 @@ For more, see [flake8-annotations](https://pypi.org/project/flake8-annotations/) | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| ANN001 | missing-type-function-argument | Missing type annotation for function argument `{name}` | | -| ANN002 | missing-type-args | Missing type annotation for `*{name}` | | -| ANN003 | missing-type-kwargs | Missing type annotation for `**{name}` | | -| ANN101 | missing-type-self | Missing type annotation for `{name}` in method | | -| ANN102 | missing-type-cls | Missing type annotation for `{name}` in classmethod | | -| ANN201 | missing-return-type-public-function | Missing return type annotation for public function `{name}` | | -| ANN202 | missing-return-type-private-function | Missing return type annotation for private function `{name}` | | -| ANN204 | missing-return-type-special-method | Missing return type annotation for special method `{name}` | 🛠 | -| ANN205 | missing-return-type-static-method | Missing return type annotation for staticmethod `{name}` | | -| ANN206 | missing-return-type-class-method | Missing return type annotation for classmethod `{name}` | | -| ANN401 | dynamically-typed-expression | Dynamically typed expressions (typing.Any) are disallowed in `{name}` | | +| ANN001 | [missing-type-function-argument](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-type-function-argument.md) | Missing type annotation for function argument `{name}` | | +| ANN002 | [missing-type-args](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-type-args.md) | Missing type annotation for `*{name}` | | +| ANN003 | [missing-type-kwargs](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-type-kwargs.md) | Missing type annotation for `**{name}` | | +| ANN101 | [missing-type-self](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-type-self.md) | Missing type annotation for `{name}` in method | | +| ANN102 | [missing-type-cls](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-type-cls.md) | Missing type annotation for `{name}` in classmethod | | +| ANN201 | [missing-return-type-public-function](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-return-type-public-function.md) | Missing return type annotation for public function `{name}` | | +| ANN202 | [missing-return-type-private-function](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-return-type-private-function.md) | Missing return type annotation for private function `{name}` | | +| ANN204 | [missing-return-type-special-method](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-return-type-special-method.md) | Missing return type annotation for special method `{name}` | 🛠 | +| ANN205 | [missing-return-type-static-method](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-return-type-static-method.md) | Missing return type annotation for staticmethod `{name}` | | +| ANN206 | [missing-return-type-class-method](https://github.com/charliermarsh/ruff/blob/main/docs/rules/missing-return-type-class-method.md) | Missing return type annotation for classmethod `{name}` | | +| ANN401 | [dynamically-typed-expression](https://github.com/charliermarsh/ruff/blob/main/docs/rules/dynamically-typed-expression.md) | Dynamically typed expressions (typing.Any) are disallowed in `{name}` | | ### flake8-bandit (S) diff --git a/crates/ruff/src/rules/flake8_annotations/rules.rs b/crates/ruff/src/rules/flake8_annotations/rules.rs index fefc3fdc8d..22dd4d2d6f 100644 --- a/crates/ruff/src/rules/flake8_annotations/rules.rs +++ b/crates/ruff/src/rules/flake8_annotations/rules.rs @@ -16,6 +16,25 @@ use crate::visibility; use crate::visibility::Visibility; define_violation!( + /// ### What it does + /// Checks that function arguments have type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the types of function arguments. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any provided arguments match expectation. + /// + /// ### Example + /// ```python + /// def foo(x): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// def foo(x: int): + /// ... + /// ``` pub struct MissingTypeFunctionArgument { pub name: String, } @@ -29,6 +48,25 @@ impl Violation for MissingTypeFunctionArgument { } define_violation!( + /// ### What it does + /// Checks that function `*args` arguments have type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the types of function arguments. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any provided arguments match expectation. + /// + /// ### Example + /// ```python + /// def foo(*args): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// def foo(*args: int): + /// ... + /// ``` pub struct MissingTypeArgs { pub name: String, } @@ -42,6 +80,25 @@ impl Violation for MissingTypeArgs { } define_violation!( + /// ### What it does + /// Checks that function `**kwargs` arguments have type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the types of function arguments. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any provided arguments match expectation. + /// + /// ### Example + /// ```python + /// def foo(**kwargs): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// def foo(**kwargs: int): + /// ... + /// ``` pub struct MissingTypeKwargs { pub name: String, } @@ -55,6 +112,30 @@ impl Violation for MissingTypeKwargs { } define_violation!( + /// ### What it does + /// Checks that instance method `self` arguments have type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the types of function arguments. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any provided arguments match expectation. + /// + /// Note that many type checkers will infer the type of `self` automatically, so this + /// annotation is not strictly necessary. + /// + /// ### Example + /// ```python + /// class Foo: + /// def bar(self): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// class Foo: + /// def bar(self: "Foo"): + /// ... + /// ``` pub struct MissingTypeSelf { pub name: String, } @@ -68,6 +149,32 @@ impl Violation for MissingTypeSelf { } define_violation!( + /// ### What it does + /// Checks that class method `cls` arguments have type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the types of function arguments. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any provided arguments match expectation. + /// + /// Note that many type checkers will infer the type of `cls` automatically, so this + /// annotation is not strictly necessary. + /// + /// ### Example + /// ```python + /// class Foo: + /// @classmethod + /// def bar(cls): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// class Foo: + /// @classmethod + /// def bar(cls: Type["Foo"]): + /// ... + /// ``` pub struct MissingTypeCls { pub name: String, } @@ -81,6 +188,25 @@ impl Violation for MissingTypeCls { } define_violation!( + /// ### What it does + /// Checks that public functions and methods have return type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the return types of functions. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any returned values, and the types expected by callers, match expectation. + /// + /// ### Example + /// ```python + /// def add(a, b): + /// return a + b + /// ``` + /// + /// Use instead: + /// ```python + /// def add(a: int, b: int) -> int: + /// return a + b + /// ``` pub struct MissingReturnTypePublicFunction { pub name: String, } @@ -94,6 +220,25 @@ impl Violation for MissingReturnTypePublicFunction { } define_violation!( + /// ### What it does + /// Checks that private functions and methods have return type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the return types of functions. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any returned values, and the types expected by callers, match expectation. + /// + /// ### Example + /// ```python + /// def _add(a, b): + /// return a + b + /// ``` + /// + /// Use instead: + /// ```python + /// def _add(a: int, b: int) -> int: + /// return a + b + /// ``` pub struct MissingReturnTypePrivateFunction { pub name: String, } @@ -107,6 +252,38 @@ impl Violation for MissingReturnTypePrivateFunction { } define_violation!( + /// ### What it does + /// Checks that "special" methods, like `__init__`, `__new__`, and `__call__`, have + /// return type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the return types of functions. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any returned values, and the types expected by callers, match expectation. + /// + /// Note that type checkers often allow you to omit the return type annotation for + /// `__init__` methods, as long as at least one argument has a type annotation. To + /// opt-in to this behavior, use the `mypy-init-return` setting in your `pyproject.toml` + /// or `ruff.toml` file: + /// + /// ```toml + /// [tool.ruff.flake8-annotations] + /// mypy-init-return = true + /// ``` + /// + /// ### Example + /// ```python + /// class Foo: + /// def __init__(self, x: int): + /// self.x = x + /// ``` + /// + /// Use instead: + /// ```python + /// class Foo: + /// def __init__(self, x: int) -> None: + /// self.x = x + /// ``` pub struct MissingReturnTypeSpecialMethod { pub name: String, } @@ -124,6 +301,29 @@ impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod { } define_violation!( + /// ### What it does + /// Checks that static methods have return type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the return types of functions. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any returned values, and the types expected by callers, match expectation. + /// + /// ### Example + /// ```python + /// class Foo: + /// @staticmethod + /// def bar(): + /// return 1 + /// ``` + /// + /// Use instead: + /// ```python + /// class Foo: + /// @staticmethod + /// def bar() -> int: + /// return 1 + /// ``` pub struct MissingReturnTypeStaticMethod { pub name: String, } @@ -137,6 +337,29 @@ impl Violation for MissingReturnTypeStaticMethod { } define_violation!( + /// ### What it does + /// Checks that class methods have return type annotations. + /// + /// ### Why is this bad? + /// Type annotations are a good way to document the return types of functions. They also + /// help catch bugs, when used alongside a type checker, by ensuring that the types of + /// any returned values, and the types expected by callers, match expectation. + /// + /// ### Example + /// ```python + /// class Foo: + /// @classmethod + /// def bar(cls): + /// return 1 + /// ``` + /// + /// Use instead: + /// ```python + /// class Foo: + /// @classmethod + /// def bar(cls) -> int: + /// return 1 + /// ``` pub struct MissingReturnTypeClassMethod { pub name: String, } @@ -150,6 +373,25 @@ impl Violation for MissingReturnTypeClassMethod { } define_violation!( + /// ### What it does + /// Checks that an expression is annotated with a more specific type than `Any`. + /// + /// ### Why is this bad? + /// `Any` is a type that can be anything, and it is the default type for + /// unannotated expressions. It is better to be explicit about the type of an + /// expression, and to use `Any` only when it is really needed. + /// + /// ### Example + /// ```python + /// def foo(x: Any): + /// ... + /// ``` + /// + /// Use instead: + /// ```python + /// def foo(x: int): + /// ... + /// ``` pub struct DynamicallyTypedExpression { pub name: String, } diff --git a/crates/ruff/src/rules/isort/rules/add_required_imports.rs b/crates/ruff/src/rules/isort/rules/add_required_imports.rs index d844744e4c..ad41c5c50a 100644 --- a/crates/ruff/src/rules/isort/rules/add_required_imports.rs +++ b/crates/ruff/src/rules/isort/rules/add_required_imports.rs @@ -15,6 +15,26 @@ use crate::source_code::{Locator, Stylist}; use crate::violation::AlwaysAutofixableViolation; define_violation!( + /// ### What it does + /// Adds any required imports, as specified by the user, to the top of the file. + /// + /// ### Why is this bad? + /// In some projects, certain imports are required to be present in all files. For + /// example, some projects assume that `from __future__ import annotations` is enabled, + /// and thus require that import to be present in all files. Omitting a "required" import + /// (as specified by the user) can cause errors or unexpected behavior. + /// + /// ### Example + /// ```python + /// import typing + /// ``` + /// + /// Use instead: + /// ```python + /// from __future__ import annotations + /// + /// import typing + /// ``` pub struct MissingRequiredImport(pub String); ); impl AlwaysAutofixableViolation for MissingRequiredImport { diff --git a/crates/ruff/src/rules/isort/rules/organize_imports.rs b/crates/ruff/src/rules/isort/rules/organize_imports.rs index a549fd7f3b..1fa40f796c 100644 --- a/crates/ruff/src/rules/isort/rules/organize_imports.rs +++ b/crates/ruff/src/rules/isort/rules/organize_imports.rs @@ -19,6 +19,24 @@ use crate::source_code::{Indexer, Locator, Stylist}; use crate::violation::AlwaysAutofixableViolation; define_violation!( + /// ### What it does + /// De-duplicates, groups, and sorts imports based on the provided `isort` settings. + /// + /// ### Why is this bad? + /// Consistency is good. Use a common convention for imports to make your code + /// more readable and idiomatic. + /// + /// ### Example + /// ```python + /// import pandas + /// import numpy as np + /// ``` + /// + /// Use instead: + /// ```python + /// import numpy as np + /// import pandas + /// ``` pub struct UnsortedImports; ); impl AlwaysAutofixableViolation for UnsortedImports { diff --git a/crates/ruff/src/rules/mccabe/rules.rs b/crates/ruff/src/rules/mccabe/rules.rs index 1a273d184c..62c50d51bc 100644 --- a/crates/ruff/src/rules/mccabe/rules.rs +++ b/crates/ruff/src/rules/mccabe/rules.rs @@ -7,6 +7,43 @@ use crate::source_code::Locator; use crate::violation::Violation; define_violation!( + /// ### What it does + /// Checks for functions with a high `McCabe` complexity. + /// + /// The `McCabe` complexity of a function is a measure of the complexity of the + /// control flow graph of the function. It is calculated by adding one to the + /// number of decision points in the function. A decision point is a place in + /// the code where the program has a choice of two or more paths to follow. + /// + /// ### Why is this bad? + /// Functions with a high complexity are hard to understand and maintain. + /// + /// ### Example + /// ```python + /// def foo(a, b, c): + /// if a: + /// if b: + /// if c: + /// return 1 + /// else: + /// return 2 + /// else: + /// return 3 + /// else: + /// return 4 + /// ``` + /// + /// Use instead: + /// ```python + /// def foo(a, b, c): + /// if not a: + /// return 4 + /// if not b: + /// return 3 + /// if not c: + /// return 2 + /// return 1 + /// ``` pub struct FunctionIsTooComplex { pub name: String, pub complexity: usize, diff --git a/crates/ruff_macros/src/define_violation.rs b/crates/ruff_macros/src/define_violation.rs index 1d8e307d90..fcce73cc8a 100644 --- a/crates/ruff_macros/src/define_violation.rs +++ b/crates/ruff_macros/src/define_violation.rs @@ -30,20 +30,13 @@ impl Parse for LintMeta { fn parse(input: ParseStream) -> Result { let attrs = input.call(Attribute::parse_outer)?; - let mut in_code = false; let mut explanation = String::new(); for attr in &attrs { if let Some(lit) = parse_attr(["doc"], attr) { let value = lit.value(); let line = value.strip_prefix(' ').unwrap_or(&value); - if line.starts_with("```") { - explanation += line; - explanation.push('\n'); - in_code = !in_code; - } else if !(in_code && line.starts_with("# ")) { - explanation += line; - explanation.push('\n'); - } + explanation.push_str(line); + explanation.push('\n'); } else { return Err(Error::new_spanned(attr, "unexpected attribute")); } diff --git a/docs/rules/commented-out-code.md b/docs/rules/commented-out-code.md index 88aa4947a5..a61abc4e93 100644 --- a/docs/rules/commented-out-code.md +++ b/docs/rules/commented-out-code.md @@ -13,4 +13,5 @@ It should be removed. ### Example ```python +# print('foo') ``` \ No newline at end of file diff --git a/docs/rules/dynamically-typed-expression.md b/docs/rules/dynamically-typed-expression.md new file mode 100644 index 0000000000..e5ea737dcd --- /dev/null +++ b/docs/rules/dynamically-typed-expression.md @@ -0,0 +1,23 @@ +# dynamically-typed-expression (ANN401) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that an expression is annotated with a more specific type than `Any`. + +### Why is this bad? +`Any` is a type that can be anything, and it is the default type for +unannotated expressions. It is better to be explicit about the type of an +expression, and to use `Any` only when it is really needed. + +### Example +```python +def foo(x: Any): + ... +``` + +Use instead: +```python +def foo(x: int): + ... +``` \ No newline at end of file diff --git a/docs/rules/function-is-too-complex.md b/docs/rules/function-is-too-complex.md new file mode 100644 index 0000000000..3e09f63f11 --- /dev/null +++ b/docs/rules/function-is-too-complex.md @@ -0,0 +1,41 @@ +# function-is-too-complex (C901) + +Derived from the **mccabe** linter. + +### What it does +Checks for functions with a high `McCabe` complexity. + +The `McCabe` complexity of a function is a measure of the complexity of the +control flow graph of the function. It is calculated by adding one to the +number of decision points in the function. A decision point is a place in +the code where the program has a choice of two or more paths to follow. + +### Why is this bad? +Functions with a high complexity are hard to understand and maintain. + +### Example +```python +def foo(a, b, c): + if a: + if b: + if c: + return 1 + else: + return 2 + else: + return 3 + else: + return 4 +``` + +Use instead: +```python +def foo(a, b, c): + if not a: + return 4 + if not b: + return 3 + if not c: + return 2 + return 1 +``` \ No newline at end of file diff --git a/docs/rules/missing-required-import.md b/docs/rules/missing-required-import.md new file mode 100644 index 0000000000..c76b0c249e --- /dev/null +++ b/docs/rules/missing-required-import.md @@ -0,0 +1,26 @@ +# missing-required-import (I002) + +Derived from the **isort** linter. + +Autofix is always available. + +### What it does +Adds any required imports, as specified by the user, to the top of the file. + +### Why is this bad? +In some projects, certain imports are required to be present in all files. For +example, some projects assume that `from __future__ import annotations` is enabled, +and thus require that import to be present in all files. Omitting a "required" import +(as specified by the user) can cause errors or unexpected behavior. + +### Example +```python +import typing +``` + +Use instead: +```python +from __future__ import annotations + +import typing +``` \ No newline at end of file diff --git a/docs/rules/missing-return-type-class-method.md b/docs/rules/missing-return-type-class-method.md new file mode 100644 index 0000000000..ac2bbf91da --- /dev/null +++ b/docs/rules/missing-return-type-class-method.md @@ -0,0 +1,27 @@ +# missing-return-type-class-method (ANN206) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that class methods have return type annotations. + +### Why is this bad? +Type annotations are a good way to document the return types of functions. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any returned values, and the types expected by callers, match expectation. + +### Example +```python +class Foo: + @classmethod + def bar(cls): + return 1 +``` + +Use instead: +```python +class Foo: + @classmethod + def bar(cls) -> int: + return 1 +``` \ No newline at end of file diff --git a/docs/rules/missing-return-type-private-function.md b/docs/rules/missing-return-type-private-function.md new file mode 100644 index 0000000000..58b401f9d6 --- /dev/null +++ b/docs/rules/missing-return-type-private-function.md @@ -0,0 +1,23 @@ +# missing-return-type-private-function (ANN202) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that private functions and methods have return type annotations. + +### Why is this bad? +Type annotations are a good way to document the return types of functions. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any returned values, and the types expected by callers, match expectation. + +### Example +```python +def _add(a, b): + return a + b +``` + +Use instead: +```python +def _add(a: int, b: int) -> int: + return a + b +``` \ No newline at end of file diff --git a/docs/rules/missing-return-type-public-function.md b/docs/rules/missing-return-type-public-function.md new file mode 100644 index 0000000000..7048c12732 --- /dev/null +++ b/docs/rules/missing-return-type-public-function.md @@ -0,0 +1,23 @@ +# missing-return-type-public-function (ANN201) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that public functions and methods have return type annotations. + +### Why is this bad? +Type annotations are a good way to document the return types of functions. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any returned values, and the types expected by callers, match expectation. + +### Example +```python +def add(a, b): + return a + b +``` + +Use instead: +```python +def add(a: int, b: int) -> int: + return a + b +``` \ No newline at end of file diff --git a/docs/rules/missing-return-type-special-method.md b/docs/rules/missing-return-type-special-method.md new file mode 100644 index 0000000000..ca78f5d732 --- /dev/null +++ b/docs/rules/missing-return-type-special-method.md @@ -0,0 +1,38 @@ +# missing-return-type-special-method (ANN204) + +Derived from the **flake8-annotations** linter. + +Autofix is always available. + +### What it does +Checks that "special" methods, like `__init__`, `__new__`, and `__call__`, have +return type annotations. + +### Why is this bad? +Type annotations are a good way to document the return types of functions. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any returned values, and the types expected by callers, match expectation. + +Note that type checkers often allow you to omit the return type annotation for +`__init__` methods, as long as at least one argument has a type annotation. To +opt-in to this behavior, use the `mypy-init-return` setting in your `pyproject.toml` +or `ruff.toml` file: + +```toml +[tool.ruff.flake8-annotations] +mypy-init-return = true +``` + +### Example +```python +class Foo: + def __init__(self, x: int): + self.x = x +``` + +Use instead: +```python +class Foo: + def __init__(self, x: int) -> None: + self.x = x +``` \ No newline at end of file diff --git a/docs/rules/missing-return-type-static-method.md b/docs/rules/missing-return-type-static-method.md new file mode 100644 index 0000000000..cf44fc27b4 --- /dev/null +++ b/docs/rules/missing-return-type-static-method.md @@ -0,0 +1,27 @@ +# missing-return-type-static-method (ANN205) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that static methods have return type annotations. + +### Why is this bad? +Type annotations are a good way to document the return types of functions. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any returned values, and the types expected by callers, match expectation. + +### Example +```python +class Foo: + @staticmethod + def bar(): + return 1 +``` + +Use instead: +```python +class Foo: + @staticmethod + def bar() -> int: + return 1 +``` \ No newline at end of file diff --git a/docs/rules/missing-type-args.md b/docs/rules/missing-type-args.md new file mode 100644 index 0000000000..2a8355630c --- /dev/null +++ b/docs/rules/missing-type-args.md @@ -0,0 +1,23 @@ +# missing-type-args (ANN002) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that function `*args` arguments have type annotations. + +### Why is this bad? +Type annotations are a good way to document the types of function arguments. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any provided arguments match expectation. + +### Example +```python +def foo(*args): + ... +``` + +Use instead: +```python +def foo(*args: int): + ... +``` \ No newline at end of file diff --git a/docs/rules/missing-type-cls.md b/docs/rules/missing-type-cls.md new file mode 100644 index 0000000000..7f571d3b71 --- /dev/null +++ b/docs/rules/missing-type-cls.md @@ -0,0 +1,30 @@ +# missing-type-cls (ANN102) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that class method `cls` arguments have type annotations. + +### Why is this bad? +Type annotations are a good way to document the types of function arguments. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any provided arguments match expectation. + +Note that many type checkers will infer the type of `cls` automatically, so this +annotation is not strictly necessary. + +### Example +```python +class Foo: + @classmethod + def bar(cls): + ... +``` + +Use instead: +```python +class Foo: + @classmethod + def bar(cls: Type["Foo"]): + ... +``` \ No newline at end of file diff --git a/docs/rules/missing-type-function-argument.md b/docs/rules/missing-type-function-argument.md new file mode 100644 index 0000000000..9d5676efaf --- /dev/null +++ b/docs/rules/missing-type-function-argument.md @@ -0,0 +1,23 @@ +# missing-type-function-argument (ANN001) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that function arguments have type annotations. + +### Why is this bad? +Type annotations are a good way to document the types of function arguments. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any provided arguments match expectation. + +### Example +```python +def foo(x): + ... +``` + +Use instead: +```python +def foo(x: int): + ... +``` \ No newline at end of file diff --git a/docs/rules/missing-type-kwargs.md b/docs/rules/missing-type-kwargs.md new file mode 100644 index 0000000000..899e6f0d7c --- /dev/null +++ b/docs/rules/missing-type-kwargs.md @@ -0,0 +1,23 @@ +# missing-type-kwargs (ANN003) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that function `**kwargs` arguments have type annotations. + +### Why is this bad? +Type annotations are a good way to document the types of function arguments. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any provided arguments match expectation. + +### Example +```python +def foo(**kwargs): + ... +``` + +Use instead: +```python +def foo(**kwargs: int): + ... +``` \ No newline at end of file diff --git a/docs/rules/missing-type-self.md b/docs/rules/missing-type-self.md new file mode 100644 index 0000000000..fd31facd5f --- /dev/null +++ b/docs/rules/missing-type-self.md @@ -0,0 +1,28 @@ +# missing-type-self (ANN101) + +Derived from the **flake8-annotations** linter. + +### What it does +Checks that instance method `self` arguments have type annotations. + +### Why is this bad? +Type annotations are a good way to document the types of function arguments. They also +help catch bugs, when used alongside a type checker, by ensuring that the types of +any provided arguments match expectation. + +Note that many type checkers will infer the type of `self` automatically, so this +annotation is not strictly necessary. + +### Example +```python +class Foo: + def bar(self): + ... +``` + +Use instead: +```python +class Foo: + def bar(self: "Foo"): + ... +``` \ No newline at end of file diff --git a/docs/rules/unsorted-imports.md b/docs/rules/unsorted-imports.md new file mode 100644 index 0000000000..7ce576509f --- /dev/null +++ b/docs/rules/unsorted-imports.md @@ -0,0 +1,24 @@ +# unsorted-imports (I001) + +Derived from the **isort** linter. + +Autofix is always available. + +### What it does +De-duplicates, groups, and sorts imports based on the provided `isort` settings. + +### Why is this bad? +Consistency is good. Use a common convention for imports to make your code +more readable and idiomatic. + +### Example +```python +import pandas +import numpy as np +``` + +Use instead: +```python +import numpy as np +import pandas +``` \ No newline at end of file