diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 6aeafc3c29..9bdcf80fc5 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -13,6 +13,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 + - name: "Install Rust toolchain" + run: rustup show + - uses: Swatinem/rust-cache@v1 - name: "Install dependencies" run: | pip install -r docs/requirements.txt diff --git a/docs/.gitignore b/docs/.gitignore index 1127295048..8efd6c8dd0 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,4 +1,3 @@ * -!rules !assets !requirements.txt diff --git a/docs/rules/any-type.md b/docs/rules/any-type.md deleted file mode 100644 index d70200e0e9..0000000000 --- a/docs/rules/any-type.md +++ /dev/null @@ -1,32 +0,0 @@ -# any-type (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 special type indicating an unconstrained type. When an -expression is annotated with type `Any`, type checkers will allow all -operations on it. - -It's better to be explicit about the type of an expression, and to use -`Any` as an "escape hatch" only when it is really needed. - -## Example -```python -def foo(x: Any): - ... -``` - -Use instead: -```python -def foo(x: int): - ... -``` - -## References -* [PEP 484](https://www.python.org/dev/peps/pep-0484/#the-any-type) -* [`typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any) -* [Mypy: The Any type](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-any-type) \ No newline at end of file diff --git a/docs/rules/assert-raises-exception.md b/docs/rules/assert-raises-exception.md deleted file mode 100644 index c8bc49c368..0000000000 --- a/docs/rules/assert-raises-exception.md +++ /dev/null @@ -1,23 +0,0 @@ -# assert-raises-exception (B017) - -Derived from the **flake8-bugbear** linter. - -## What it does -Checks for `self.assertRaises(Exception)`. - -## Why is this bad? -`assertRaises(Exception)` can lead to your test passing even if the -code being tested is never executed due to a typo. - -Either assert for a more specific exception (builtin or custom), use -`assertRaisesRegex` or the context manager form of `assertRaises`. - -## Example -```python -self.assertRaises(Exception, foo) -``` - -Use instead: -```python -self.assertRaises(SomeSpecificException, foo) -``` \ No newline at end of file diff --git a/docs/rules/avoidable-escaped-quote.md b/docs/rules/avoidable-escaped-quote.md deleted file mode 100644 index f2758e1d7e..0000000000 --- a/docs/rules/avoidable-escaped-quote.md +++ /dev/null @@ -1,23 +0,0 @@ -# avoidable-escaped-quote (Q003) - -Derived from the **flake8-quotes** linter. - -Autofix is always available. - -## What it does -Checks for strings that include escaped quotes, and suggests changing -the quote style to avoid the need to escape them. - -## Why is this bad? -It's preferable to avoid escaped quotes in strings. By changing the -outer quote style, you can avoid escaping inner quotes. - -## Example -```python -foo = 'bar\'s' -``` - -Use instead: -```python -foo = "bar's" -``` \ No newline at end of file diff --git a/docs/rules/bad-quotes-docstring.md b/docs/rules/bad-quotes-docstring.md deleted file mode 100644 index 1740936066..0000000000 --- a/docs/rules/bad-quotes-docstring.md +++ /dev/null @@ -1,33 +0,0 @@ -# bad-quotes-docstring (Q002) - -Derived from the **flake8-quotes** linter. - -Autofix is always available. - -## What it does -Checks for docstrings that use single quotes or double quotes, depending -on the value of the [`flake8-quotes.docstring-quotes`] setting. - -## Why is this bad? -Consistency is good. Use either single or double quotes for docstring -strings, but be consistent. - -## Options - -* [`flake8-quotes.docstring-quotes`] - -## Example -```python -''' -bar -''' -``` - -Assuming `docstring-quotes` is set to `double`, use instead: -```python -""" -bar -""" -``` - -[`flake8-quotes.docstring-quotes`]: ../../settings#docstring-quotes \ No newline at end of file diff --git a/docs/rules/bad-quotes-inline-string.md b/docs/rules/bad-quotes-inline-string.md deleted file mode 100644 index b0c64cb9ef..0000000000 --- a/docs/rules/bad-quotes-inline-string.md +++ /dev/null @@ -1,29 +0,0 @@ -# bad-quotes-inline-string (Q000) - -Derived from the **flake8-quotes** linter. - -Autofix is always available. - -## What it does -Checks for inline strings that use single quotes or double quotes, -depending on the value of the [`flake8-quotes.inline-quotes`] option. - -## Why is this bad? -Consistency is good. Use either single or double quotes for inline -strings, but be consistent. - -## Options - -* [`flake8-quotes.inline-quotes`] - -## Example -```python -foo = 'bar' -``` - -Assuming `inline-quotes` is set to `double`, use instead: -```python -foo = "bar" -``` - -[`flake8-quotes.inline-quotes`]: ../../settings#inline-quotes \ No newline at end of file diff --git a/docs/rules/bad-quotes-multiline-string.md b/docs/rules/bad-quotes-multiline-string.md deleted file mode 100644 index 3608a88c97..0000000000 --- a/docs/rules/bad-quotes-multiline-string.md +++ /dev/null @@ -1,34 +0,0 @@ -# bad-quotes-multiline-string (Q001) - -Derived from the **flake8-quotes** linter. - -Autofix is always available. - -## What it does -Checks for multiline strings that use single quotes or double quotes, -depending on the value of the [`flake8-quotes.multiline-quotes`] -setting. - -## Why is this bad? -Consistency is good. Use either single or double quotes for multiline -strings, but be consistent. - -## Options - -* [`flake8-quotes.multiline-quotes`] - -## Example -```python -foo = ''' -bar -''' -``` - -Assuming `multiline-quotes` is set to `double`, use instead: -```python -foo = """ -bar -""" -``` - -[`flake8-quotes.multiline-quotes`]: ../../settings#multiline-quotes \ No newline at end of file diff --git a/docs/rules/bad-string-format-type.md b/docs/rules/bad-string-format-type.md deleted file mode 100644 index 181be63ddb..0000000000 --- a/docs/rules/bad-string-format-type.md +++ /dev/null @@ -1,20 +0,0 @@ -# bad-string-format-type (PLE1307) - -Derived from the **Pylint** linter. - -## What it does -Checks for mismatched argument types in "old-style" format strings. - -## Why is this bad? -The format string is not checked at compile time, so it is easy to -introduce bugs by mistyping the format string. - -## Example -```python -print("%d" % "1") -``` - -Use instead: -```python -print("%d" % 1) -``` \ No newline at end of file diff --git a/docs/rules/banned-api.md b/docs/rules/banned-api.md deleted file mode 100644 index c9f028682c..0000000000 --- a/docs/rules/banned-api.md +++ /dev/null @@ -1,24 +0,0 @@ -# banned-api (TID251) - -Derived from the **flake8-tidy-imports** linter. - -## What it does -Checks for banned imports. - -## Why is this bad? -Projects may want to ensure that specific modules or module members are -not be imported or accessed. - -Security or other company policies may be a reason to impose -restrictions on importing external Python libraries. In some cases, -projects may adopt conventions around the use of certain modules or -module members that are not enforceable by the language itself. - -This rule enforces certain import conventions project-wide in an -automatic way. - -## Options -* [`flake8-tidy-imports.banned-api`] - - -[`flake8-tidy-imports.banned-api`]: ../../settings#banned-api \ No newline at end of file diff --git a/docs/rules/bare-except.md b/docs/rules/bare-except.md deleted file mode 100644 index 26427bbd77..0000000000 --- a/docs/rules/bare-except.md +++ /dev/null @@ -1,33 +0,0 @@ -# bare-except (E722) - -Derived from the **pycodestyle** linter. - -## What it does -Checks for bare `except` catches in `try`-`except` statements. - -## Why is this bad? -A bare `except` catches `BaseException` which includes -`KeyboardInterrupt`, `SystemExit`, `Exception`, and others. Catching -`BaseException` can make it hard to interrupt the program (e.g., with -Ctrl-C) and disguise other problems. - -## Example -```python -try: - raise(KeyboardInterrupt("You probably don't mean to break CTRL-C.")) -except: - print("But a bare `except` will ignore keyboard interrupts.") -``` - -Use instead: -```python -try: - do_something_that_might_break() -except MoreSpecificException as e: - handle_error(e) -``` - -## References -- [PEP 8](https://www.python.org/dev/peps/pep-0008/#programming-recommendations) -- [Python: "Exception hierarchy"](https://docs.python.org/3/library/exceptions.html#exception-hierarchy) -- [Google Python Style Guide: "Exceptions"](https://google.github.io/styleguide/pyguide.html#24-exceptions) \ No newline at end of file diff --git a/docs/rules/commented-out-code.md b/docs/rules/commented-out-code.md deleted file mode 100644 index 09f2e0aa6b..0000000000 --- a/docs/rules/commented-out-code.md +++ /dev/null @@ -1,17 +0,0 @@ -# commented-out-code (ERA001) - -Derived from the **eradicate** linter. - -Autofix is always available. - -## What it does -Checks for commented-out Python code. - -## Why is this bad? -Commented-out code is dead code, and is often included inadvertently. -It should be removed. - -## Example -```python -# print('foo') -``` \ No newline at end of file diff --git a/docs/rules/complex-structure.md b/docs/rules/complex-structure.md deleted file mode 100644 index 8e500c10b3..0000000000 --- a/docs/rules/complex-structure.md +++ /dev/null @@ -1,47 +0,0 @@ -# complex-structure (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. - -## Options - -* [`mccabe.max-complexity`] - -## 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 -``` - -[`mccabe.max-complexity`]: ../../settings#max-complexity \ No newline at end of file diff --git a/docs/rules/f-string-missing-placeholders.md b/docs/rules/f-string-missing-placeholders.md deleted file mode 100644 index 8134b32198..0000000000 --- a/docs/rules/f-string-missing-placeholders.md +++ /dev/null @@ -1,31 +0,0 @@ -# f-string-missing-placeholders (F541) - -Derived from the **Pyflakes** linter. - -Autofix is always available. - -## What it does -Checks for f-strings that do not contain any placeholder expressions. - -## Why is this bad? -F-strings are a convenient way to format strings, but they are not -necessary if there are no placeholder expressions to format. In this -case, a regular string should be used instead, as an f-string without -placeholders can be confusing for readers, who may expect such a -placeholder to be present. - -An f-string without any placeholders could also indicate that the -author forgot to add a placeholder expression. - -## Example -```python -f"Hello, world!" -``` - -Use instead: -```python -"Hello, world!" -``` - -## References -* [PEP 498](https://www.python.org/dev/peps/pep-0498/) \ No newline at end of file diff --git a/docs/rules/hardcoded-sql-expression.md b/docs/rules/hardcoded-sql-expression.md deleted file mode 100644 index ebf8d1491d..0000000000 --- a/docs/rules/hardcoded-sql-expression.md +++ /dev/null @@ -1,23 +0,0 @@ -# hardcoded-sql-expression (S608) - -Derived from the **flake8-bandit** linter. - -## What it does -Checks for strings that resemble SQL statements involved in some form -string building operation. - -## Why is this bad? -SQL injection is a common attack vector for web applications. Directly -interpolating user input into SQL statements should always be avoided. -Instead, favor parameterized queries, in which the SQL statement is -provided separately from its parameters, as supported by `psycopg3` -and other database drivers and ORMs. - -## Example -```python -query = "DELETE FROM foo WHERE id = '%s'" % identifier -``` - -## References -* [B608: Test for SQL injection](https://bandit.readthedocs.io/en/latest/plugins/b608_hardcoded_sql_expressions.html) -* [psycopg3: Server-side binding](https://www.psycopg.org/psycopg3/docs/basic/from_pg2.html#server-side-binding) \ No newline at end of file diff --git a/docs/rules/if-with-same-arms.md b/docs/rules/if-with-same-arms.md deleted file mode 100644 index 4fecf4251f..0000000000 --- a/docs/rules/if-with-same-arms.md +++ /dev/null @@ -1,24 +0,0 @@ -# if-with-same-arms (SIM114) - -Derived from the **flake8-simplify** linter. - -### What it does -Checks for `if` branches with identical arm bodies. - -### Why is this bad? -If multiple arms of an `if` statement have the same body, using `or` -better signals the intent of the statement. - -### Example -```python -if x = 1: - print("Hello") -elif x = 2: - print("Hello") -``` - -Use instead: -```python -if x = 1 or x = 2: - print("Hello") -``` \ No newline at end of file diff --git a/docs/rules/implicit-namespace-package.md b/docs/rules/implicit-namespace-package.md deleted file mode 100644 index f19d013c55..0000000000 --- a/docs/rules/implicit-namespace-package.md +++ /dev/null @@ -1,26 +0,0 @@ -# implicit-namespace-package (INP001) - -Derived from the **flake8-no-pep420** linter. - -## What it does -Checks for packages that are missing an `__init__.py` file. - -## Why is this bad? -Python packages are directories that contain a file named `__init__.py`. -The existence of this file indicates that the directory is a Python -package, and so it can be imported the same way a module can be -imported. - -Directories that lack an `__init__.py` file can still be imported, but -they're indicative of a special kind of package, known as a "namespace -package" (see: [PEP 420](https://www.python.org/dev/peps/pep-0420/)). -Namespace packages are less widely used, so a package that lacks an -`__init__.py` file is typically meant to be a regular package, and -the absence of the `__init__.py` file is probably an oversight. - -## Options - -* [`namespace-packages`] - - -[`namespace-packages`]: ../../settings#namespace-packages \ No newline at end of file diff --git a/docs/rules/missing-required-import.md b/docs/rules/missing-required-import.md deleted file mode 100644 index 9de1b90200..0000000000 --- a/docs/rules/missing-required-import.md +++ /dev/null @@ -1,26 +0,0 @@ -# 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 deleted file mode 100644 index 2d4e1e0f38..0000000000 --- a/docs/rules/missing-return-type-class-method.md +++ /dev/null @@ -1,27 +0,0 @@ -# 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 deleted file mode 100644 index 6d7ec5335d..0000000000 --- a/docs/rules/missing-return-type-private-function.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index 0ef9fa77c6..0000000000 --- a/docs/rules/missing-return-type-public-function.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index e3041b9f58..0000000000 --- a/docs/rules/missing-return-type-special-method.md +++ /dev/null @@ -1,38 +0,0 @@ -# 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 deleted file mode 100644 index d952c5c726..0000000000 --- a/docs/rules/missing-return-type-static-method.md +++ /dev/null @@ -1,27 +0,0 @@ -# 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 deleted file mode 100644 index ce110ba94f..0000000000 --- a/docs/rules/missing-type-args.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index ea960f0cff..0000000000 --- a/docs/rules/missing-type-cls.md +++ /dev/null @@ -1,30 +0,0 @@ -# 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 deleted file mode 100644 index 3ffd588d57..0000000000 --- a/docs/rules/missing-type-function-argument.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index 9baa68afa9..0000000000 --- a/docs/rules/missing-type-kwargs.md +++ /dev/null @@ -1,23 +0,0 @@ -# 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 deleted file mode 100644 index a3fa287192..0000000000 --- a/docs/rules/missing-type-self.md +++ /dev/null @@ -1,28 +0,0 @@ -# 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/model-without-dunder-str.md b/docs/rules/model-without-dunder-str.md deleted file mode 100644 index 69b638dfe4..0000000000 --- a/docs/rules/model-without-dunder-str.md +++ /dev/null @@ -1,33 +0,0 @@ -# model-without-dunder-str (DJ008) - -Derived from the **flake8-django** linter. - -## What it does -Checks that `__str__` method is defined in Django models. - -## Why is this bad? -Django models should define `__str__` method to return a string representation -of the model instance, as Django calls this method to display the object in -the Django Admin and elsewhere. - -Models without `__str__` method will display a non-meaningful representation -of the object in the Django Admin. - -## Example -```python -from django.db import models - -class MyModel(models.Model): - field = models.CharField(max_length=255) -``` - -Use instead: -```python -from django.db import models - -class MyModel(models.Model): - field = models.CharField(max_length=255) - - def __str__(self): - return f"{self.field}" -``` \ No newline at end of file diff --git a/docs/rules/non-leading-receiver-decorator.md b/docs/rules/non-leading-receiver-decorator.md deleted file mode 100644 index e9c9edea91..0000000000 --- a/docs/rules/non-leading-receiver-decorator.md +++ /dev/null @@ -1,35 +0,0 @@ -# non-leading-receiver-decorator (DJ013) - -Derived from the **flake8-django** linter. - -## What it does -Checks that Django's `@receiver` decorator is listed first, prior to -any other decorators. - -## Why is this bad? -Django's `@receiver` decorator is special in that it does not return -a wrapped function. Rather, `@receiver` connects the decorated function -to a signal. If any other decorators are listed before `@receiver`, -the decorated function will not be connected to the signal. - -## Example -```python -from django.dispatch import receiver -from django.db.models.signals import post_save - -@transaction.atomic -@receiver(post_save, sender=MyModel) -def my_handler(sender, instance, created, **kwargs): - pass -``` - -Use instead: -```python -from django.dispatch import receiver -from django.db.models.signals import post_save - -@receiver(post_save, sender=MyModel) -@transaction.atomic -def my_handler(sender, instance, created, **kwargs): - pass -``` \ No newline at end of file diff --git a/docs/rules/nullable-model-string-field.md b/docs/rules/nullable-model-string-field.md deleted file mode 100644 index 1e5ee11765..0000000000 --- a/docs/rules/nullable-model-string-field.md +++ /dev/null @@ -1,32 +0,0 @@ -# nullable-model-string-field (DJ001) - -Derived from the **flake8-django** linter. - -## What it does -Checks nullable string-based fields (like `CharField` and `TextField`) -in Django models. - -## Why is this bad? -If a string-based field is nullable, then your model will have two possible -representations for "no data": `None` and the empty string. This can lead to -confusion, as clients of the API have to check for both `None` and the -empty string when trying to determine if the field has data. - -The Django convention is to use the empty string in lieu of `None` for -string-based fields. - -## Example -```python -from django.db import models - -class MyModel(models.Model): - field = models.CharField(max_length=255, null=True) -``` - -Use instead: -```python -from django.db import models - -class MyModel(models.Model): - field = models.CharField(max_length=255, default="") -``` \ No newline at end of file diff --git a/docs/rules/prefix-type-params.md b/docs/rules/prefix-type-params.md deleted file mode 100644 index 738e0478bd..0000000000 --- a/docs/rules/prefix-type-params.md +++ /dev/null @@ -1,25 +0,0 @@ -# prefix-type-params (PYI001) - -Derived from the **flake8-pyi** linter. - -## What it does -Checks that type `TypeVar`, `ParamSpec`, and `TypeVarTuple` definitions in -stubs are prefixed with `_`. - -## Why is this bad? -By prefixing type parameters with `_`, we can avoid accidentally exposing -names internal to the stub. - -## Example -```python -from typing import TypeVar - -T = TypeVar("T") -``` - -Use instead: -```python -from typing import TypeVar - -_T = TypeVar("_T") -``` \ No newline at end of file diff --git a/docs/rules/raise-vanilla-class.md b/docs/rules/raise-vanilla-class.md deleted file mode 100644 index 1023336649..0000000000 --- a/docs/rules/raise-vanilla-class.md +++ /dev/null @@ -1,45 +0,0 @@ -# raise-vanilla-class (TRY002) - -Derived from the **tryceratops** linter. - -## What it does -Checks for code that raises `Exception` directly. - -## Why is this bad? -Handling such exceptions requires the use of `except Exception`, which -captures _any_ raised exception, including failed assertions, -division by zero, and more. - -Prefer to raise your own exception, or a more specific built-in -exception, so that you can avoid over-capturing exceptions that you -don't intend to handle. - -## Example -```python -def main_function(): - if not cond: - raise Exception() -def consumer_func(): - try: - do_step() - prepare() - main_function() - except Exception: - logger.error("Oops") -``` - -Use instead: -```python -def main_function(): - if not cond: - raise CustomException() -def consumer_func(): - try: - do_step() - prepare() - main_function() - except CustomException: - logger.error("Main function failed") - except Exception: - logger.error("Oops") -``` \ No newline at end of file diff --git a/docs/rules/relative-imports.md b/docs/rules/relative-imports.md deleted file mode 100644 index d75487cdce..0000000000 --- a/docs/rules/relative-imports.md +++ /dev/null @@ -1,41 +0,0 @@ -# relative-imports (TID252) - -Derived from the **flake8-tidy-imports** linter. - -Autofix is sometimes available. - -## What it does -Checks for relative imports. - -## Why is this bad? -Absolute imports, or relative imports from siblings, are recommended by [PEP 8](https://peps.python.org/pep-0008/#imports): - -> Absolute imports are recommended, as they are usually more readable and tend to be better behaved... -> ```python -> import mypkg.sibling -> from mypkg import sibling -> from mypkg.sibling import example -> ``` -> However, explicit relative imports are an acceptable alternative to absolute imports, -> especially when dealing with complex package layouts where using absolute imports would be -> unnecessarily verbose: -> ```python -> from . import sibling -> from .sibling import example -> ``` - -## Options - -* [`flake8-tidy-imports.ban-relative-imports`] - -## Example -```python -from .. import foo -``` - -Use instead: -```python -from mypkg import foo -``` - -[`flake8-tidy-imports.ban-relative-imports`]: ../../settings#ban-relative-imports \ No newline at end of file diff --git a/docs/rules/unconventional-import-alias.md b/docs/rules/unconventional-import-alias.md deleted file mode 100644 index 8ac9f60ce8..0000000000 --- a/docs/rules/unconventional-import-alias.md +++ /dev/null @@ -1,25 +0,0 @@ -# unconventional-import-alias (ICN001) - -Derived from the **flake8-import-conventions** linter. - -## What it does -Checks for imports that are typically imported using a common convention, -like `import pandas as pd`, and enforces that convention. - -## Why is this bad? -Consistency is good. Use a common convention for imports to make your code -more readable and idiomatic. - -For example, `import pandas as pd` is a common -convention for importing the `pandas` library, and users typically expect -Pandas to be aliased as `pd`. - -## Example -```python -import pandas -``` - -Use instead: -```python -import pandas as pd -``` \ No newline at end of file diff --git a/docs/rules/unnecessary-call-around-sorted.md b/docs/rules/unnecessary-call-around-sorted.md deleted file mode 100644 index 890ea0dc3e..0000000000 --- a/docs/rules/unnecessary-call-around-sorted.md +++ /dev/null @@ -1,29 +0,0 @@ -# unnecessary-call-around-sorted (C413) - -Derived from the **flake8-comprehensions** linter. - -Autofix is always available. - -## What it does -Checks for unnecessary `list` or `reversed` calls around `sorted` -calls. - -## Why is this bad? -It is unnecessary to use `list` around `sorted`, as the latter already -returns a list. - -It is also unnecessary to use `reversed` around `sorted`, as the latter -has a `reverse` argument that can be used in lieu of an additional -`reversed` call. - -In both cases, it's clearer to avoid the redundant call. - -## Examples -```python -reversed(sorted(iterable)) -``` - -Use instead: -```python -sorted(iterable, reverse=True) -``` \ No newline at end of file diff --git a/docs/rules/unnecessary-double-cast-or-process.md b/docs/rules/unnecessary-double-cast-or-process.md deleted file mode 100644 index bde28534d8..0000000000 --- a/docs/rules/unnecessary-double-cast-or-process.md +++ /dev/null @@ -1,40 +0,0 @@ -# unnecessary-double-cast-or-process (C414) - -Derived from the **flake8-comprehensions** linter. - -Autofix is always available. - -## What it does -Checks for unnecessary `list`, `reversed`, `set`, `sorted`, and `tuple` -call within `list`, `set`, `sorted`, and `tuple` calls. - -## Why is this bad? -It's unnecessary to double-cast or double-process iterables by wrapping -the listed functions within an additional `list`, `set`, `sorted`, or -`tuple` call. Doing so is redundant and can be confusing for readers. - -## Examples -```python -list(tuple(iterable)) -``` - -Use instead: -```python -list(iterable) -``` - -This rule applies to a variety of functions, including `list`, `reversed`, -`set`, `sorted`, and `tuple`. For example: -* Instead of `list(list(iterable))`, use `list(iterable)`. -* Instead of `list(tuple(iterable))`, use `list(iterable)`. -* Instead of `tuple(list(iterable))`, use `tuple(iterable)`. -* Instead of `tuple(tuple(iterable))`, use `tuple(iterable)`. -* Instead of `set(set(iterable))`, use `set(iterable)`. -* Instead of `set(list(iterable))`, use `set(iterable)`. -* Instead of `set(tuple(iterable))`, use `set(iterable)`. -* Instead of `set(sorted(iterable))`, use `set(iterable)`. -* Instead of `set(reversed(iterable))`, use `set(iterable)`. -* Instead of `sorted(list(iterable))`, use `sorted(iterable)`. -* Instead of `sorted(tuple(iterable))`, use `sorted(iterable)`. -* Instead of `sorted(sorted(iterable))`, use `sorted(iterable)`. -* Instead of `sorted(reversed(iterable))`, use `sorted(iterable)`. \ No newline at end of file diff --git a/docs/rules/unnecessary-generator-dict.md b/docs/rules/unnecessary-generator-dict.md deleted file mode 100644 index c8220429cd..0000000000 --- a/docs/rules/unnecessary-generator-dict.md +++ /dev/null @@ -1,24 +0,0 @@ -# unnecessary-generator-dict (C402) - -Derived from the **flake8-comprehensions** linter. - -Autofix is always available. - -## What it does -Checks for unnecessary generators that can be rewritten as `dict` -comprehensions. - -## Why is this bad? -It is unnecessary to use `dict` around a generator expression, since -there are equivalent comprehensions for these types. Using a -comprehension is clearer and more idiomatic. - -## Examples -```python -dict((x, f(x)) for x in foo) -``` - -Use instead: -```python -{x: f(x) for x in foo} -``` \ No newline at end of file diff --git a/docs/rules/unnecessary-generator-list.md b/docs/rules/unnecessary-generator-list.md deleted file mode 100644 index df595115eb..0000000000 --- a/docs/rules/unnecessary-generator-list.md +++ /dev/null @@ -1,24 +0,0 @@ -# unnecessary-generator-list (C400) - -Derived from the **flake8-comprehensions** linter. - -Autofix is always available. - -## What it does -Checks for unnecessary generators that can be rewritten as `list` -comprehensions. - -## Why is this bad? -It is unnecessary to use `list` around a generator expression, since -there are equivalent comprehensions for these types. Using a -comprehension is clearer and more idiomatic. - -## Examples -```python -list(f(x) for x in foo) -``` - -Use instead: -```python -[f(x) for x in foo] -``` \ No newline at end of file diff --git a/docs/rules/unnecessary-generator-set.md b/docs/rules/unnecessary-generator-set.md deleted file mode 100644 index ea5bc2c593..0000000000 --- a/docs/rules/unnecessary-generator-set.md +++ /dev/null @@ -1,24 +0,0 @@ -# unnecessary-generator-set (C401) - -Derived from the **flake8-comprehensions** linter. - -Autofix is always available. - -## What it does -Checks for unnecessary generators that can be rewritten as `set` -comprehensions. - -## Why is this bad? -It is unnecessary to use `set` around a generator expression, since -there are equivalent comprehensions for these types. Using a -comprehension is clearer and more idiomatic. - -## Examples -```python -set(f(x) for x in foo) -``` - -Use instead: -```python -{f(x) for x in foo} -``` \ No newline at end of file diff --git a/docs/rules/unnecessary-map.md b/docs/rules/unnecessary-map.md deleted file mode 100644 index 847f2a4533..0000000000 --- a/docs/rules/unnecessary-map.md +++ /dev/null @@ -1,32 +0,0 @@ -# unnecessary-map (C417) - -Derived from the **flake8-comprehensions** linter. - -Autofix is sometimes available. - -## What it does -Checks for unnecessary `map` calls with `lambda` functions. - -## Why is this bad? -Using `map(func, iterable)` when `func` is a `lambda` is slower than -using a generator expression or a comprehension, as the latter approach -avoids the function call overhead, in addition to being more readable. - -## Examples -```python -map(lambda x: x + 1, iterable) -``` - -Use instead: -```python -(x + 1 for x in iterable) -``` - -This rule also applies to `map` calls within `list`, `set`, and `dict` -calls. For example: -* Instead of `list(map(lambda num: num * 2, nums))`, use - `[num * 2 for num in nums]`. -* Instead of `set(map(lambda num: num % 2 == 0, nums))`, use - `{num % 2 == 0 for num in nums}`. -* Instead of `dict(map(lambda v: (v, v ** 2), values))`, use - `{v: v ** 2 for v in values}`. \ No newline at end of file diff --git a/docs/rules/unrecognized-platform-check.md b/docs/rules/unrecognized-platform-check.md deleted file mode 100644 index d77eac1cb5..0000000000 --- a/docs/rules/unrecognized-platform-check.md +++ /dev/null @@ -1,33 +0,0 @@ -# unrecognized-platform-check (PYI007) - -Derived from the **flake8-pyi** linter. - -## What it does -Check for unrecognized `sys.platform` checks. Platform checks should be -simple string comparisons. - -**Note**: this rule is only enabled in `.pyi` stub files. - -## Why is this bad? -Some `sys.platform` checks are too complex for type checkers to -understand, and thus result in false positives. `sys.platform` checks -should be simple string comparisons, like `sys.platform == "linux"`. - -## Example -```python -if sys.platform.startswith("linux"): - # Linux specific definitions -else: - # Posix specific definitions -``` - -Instead, use a simple string comparison, such as `==` or `!=`: -```python -if sys.platform == "linux": - # Linux specific definitions -else: - # Posix specific definitions -``` - -## References -- [PEP 484](https://peps.python.org/pep-0484/#version-and-platform-checking) \ No newline at end of file diff --git a/docs/rules/unrecognized-platform-name.md b/docs/rules/unrecognized-platform-name.md deleted file mode 100644 index db21e68195..0000000000 --- a/docs/rules/unrecognized-platform-name.md +++ /dev/null @@ -1,30 +0,0 @@ -# unrecognized-platform-name (PYI008) - -Derived from the **flake8-pyi** linter. - -## What it does -Check for unrecognized platform names in `sys.platform` checks. - -**Note**: this rule is only enabled in `.pyi` stub files. - -## Why is this bad? -If a `sys.platform` check compares to a platform name outside of a -small set of known platforms (e.g. "linux", "win32", etc.), it's likely -a typo or a platform name that is not recognized by type checkers. - -The list of known platforms is: "linux", "win32", "cygwin", "darwin". - -## Example -```python -if sys.platform == "linus": - ... -``` - -Use instead: -```python -if sys.platform == "linux": - ... -``` - -## References -- [PEP 484](https://peps.python.org/pep-0484/#version-and-platform-checking) \ No newline at end of file diff --git a/docs/rules/unsorted-imports.md b/docs/rules/unsorted-imports.md deleted file mode 100644 index 570087b8f9..0000000000 --- a/docs/rules/unsorted-imports.md +++ /dev/null @@ -1,24 +0,0 @@ -# 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 diff --git a/docs/rules/unused-variable.md b/docs/rules/unused-variable.md deleted file mode 100644 index 45b480977d..0000000000 --- a/docs/rules/unused-variable.md +++ /dev/null @@ -1,37 +0,0 @@ -# unused-variable (F841) - -Derived from the **Pyflakes** linter. - -Autofix is always available. - -## What it does -Checks for the presence of unused variables in function scopes. - -## Why is this bad? -A variable that is defined but not used is likely a mistake, and should be -removed to avoid confusion. - -If a variable is intentionally defined-but-not-used, it should be -prefixed with an underscore, or some other value that adheres to the -[`dummy-variable-rgx`] pattern. - -## Options - -* [`dummy-variable-rgx`] - -## Example -```python -def foo(): - x = 1 - y = 2 - return x -``` - -Use instead: -```python -def foo(): - x = 1 - return x -``` - -[`dummy-variable-rgx`]: ../../settings#dummy-variable-rgx \ No newline at end of file diff --git a/docs/rules/use-of-inplace-argument.md b/docs/rules/use-of-inplace-argument.md deleted file mode 100644 index ffad4a6510..0000000000 --- a/docs/rules/use-of-inplace-argument.md +++ /dev/null @@ -1,30 +0,0 @@ -# use-of-inplace-argument (PD002) - -Derived from the **pandas-vet** linter. - -Autofix is always available. - -## What it does -Checks for `inplace=True` usages in `pandas` function and method -calls. - -## Why is this bad? -Using `inplace=True` encourages mutation rather than immutable data, -which is harder to reason about and may cause bugs. It also removes the -ability to use the method chaining style for `pandas` operations. - -Further, in many cases, `inplace=True` does not provide a performance -benefit, as `pandas` will often copy `DataFrames` in the background. - -## Example -```python -df.sort_values("col1", inplace=True) -``` - -Use instead: -```python -sorted_df = df.sort_values("col1") -``` - -## References -- [Why You Should Probably Never Use pandas inplace=True](https://towardsdatascience.com/why-you-should-probably-never-use-pandas-inplace-true-9f9f211849e4) \ No newline at end of file diff --git a/docs/rules/yield-in-init.md b/docs/rules/yield-in-init.md deleted file mode 100644 index 77ce46c953..0000000000 --- a/docs/rules/yield-in-init.md +++ /dev/null @@ -1,25 +0,0 @@ -# yield-in-init (PLE0100) - -Derived from the **Pylint** linter. - -## What it does -Checks for `__init__` methods that are turned into generators by the -inclusion of `yield` or `yield from` expressions. - -## Why is this bad? -The `__init__` method is the constructor for a given Python class, -responsible for initializing, rather than creating, new objects. - -The `__init__` method has to return `None`. By including a `yield` or -`yield from` expression in an `__init__`, the method will return a -generator object when called at runtime, resulting in a runtime error. - -## Example -```python -class InitIsGenerator: - def __init__(self, i): - yield i -``` - -## References -* [`py-init-method-is-generator`](https://codeql.github.com/codeql-query-help/python/py-init-method-is-generator/) \ No newline at end of file diff --git a/scripts/generate_mkdocs.py b/scripts/generate_mkdocs.py index b2bba42d74..a6c289e6e4 100644 --- a/scripts/generate_mkdocs.py +++ b/scripts/generate_mkdocs.py @@ -1,6 +1,7 @@ """Generate an MkDocs-compatible `docs` and `mkdocs.yml` from the README.md.""" import argparse import shutil +import subprocess from pathlib import Path import yaml @@ -27,6 +28,9 @@ FATHOM_SCRIPT: str = ( def main() -> None: """Generate an MkDocs-compatible `docs` and `mkdocs.yml`.""" + + subprocess.run(["cargo", "dev", "generate-docs"], check=True) + with Path("README.md").open(encoding="utf8") as fp: content = fp.read() diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml index 8918745865..a354951341 100644 --- a/scripts/pyproject.toml +++ b/scripts/pyproject.toml @@ -11,6 +11,7 @@ ignore = [ "PL", # pylint "S101", # assert-used "EM", # errmgs + "D202", # no-blank-line-after-function ] unfixable = [ "RUF100", # unused-noqa