Run automatically format code blocks with Black (#3191)

This commit is contained in:
Jonathan Plasse 2023-02-27 16:14:05 +01:00 committed by GitHub
parent 386ca7c9a1
commit d285f5c90a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 420 additions and 394 deletions

View file

@ -5,6 +5,14 @@ repos:
hooks:
- id: validate-pyproject
- repo: https://github.com/executablebooks/mdformat
rev: 0.7.16
hooks:
- id: mdformat
additional_dependencies:
- mdformat-black
- black==23.1.0 # Must be the latest version of Black
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.33.0
hooks:

View file

@ -20,8 +20,7 @@ the intention of adding a stable public API in the future.
### `select`, `extend-select`, `ignore`, and `extend-ignore` have new semantics ([#2312](https://github.com/charliermarsh/ruff/pull/2312))
Previously, the interplay between `select` and its related options could lead to unexpected
behavior. For example, `ruff --select E501 --ignore ALL` and `ruff --select E501 --extend-ignore
ALL` behaved differently. (See [#2312](https://github.com/charliermarsh/ruff/pull/2312) for more
behavior. For example, `ruff --select E501 --ignore ALL` and `ruff --select E501 --extend-ignore ALL` behaved differently. (See [#2312](https://github.com/charliermarsh/ruff/pull/2312) for more
examples.)
When Ruff determines the enabled rule set, it has to reconcile `select` and `ignore` from a variety
@ -74,7 +73,7 @@ ruff rule E402 --format json # Works! (And preferred.)
This change is largely backwards compatible -- most users should experience
no change in behavior. However, please note the following exceptions:
* Subcommands will now fail when invoked with unsupported arguments, instead
- Subcommands will now fail when invoked with unsupported arguments, instead
of silently ignoring them. For example, the following will now fail:
```console
@ -83,16 +82,16 @@ no change in behavior. However, please note the following exceptions:
(the `clean` command doesn't support `--respect-gitignore`.)
* The semantics of `ruff <arg>` have changed slightly when `<arg>` is a valid subcommand.
- The semantics of `ruff <arg>` have changed slightly when `<arg>` is a valid subcommand.
For example, prior to this release, running `ruff rule` would run `ruff` over a file or
directory called `rule`. Now, `ruff rule` would invoke the `rule` subcommand. This should
only impact projects with files or directories named `rule`, `check`, `explain`, `clean`,
or `generate-shell-completion`.
* Scripts that invoke ruff should supply `--` before any positional arguments.
- Scripts that invoke ruff should supply `--` before any positional arguments.
(The semantics of `ruff -- <arg>` have not changed.)
* `--explain` previously treated `--format grouped` as a synonym for `--format text`.
- `--explain` previously treated `--format grouped` as a synonym for `--format text`.
This is no longer supported; instead, use `--format text`.
## 0.0.226

View file

@ -1,16 +1,16 @@
# Contributor Covenant Code of Conduct
* [Our Pledge](#our-pledge)
* [Our Standards](#our-standards)
* [Enforcement Responsibilities](#enforcement-responsibilities)
* [Scope](#scope)
* [Enforcement](#enforcement)
* [Enforcement Guidelines](#enforcement-guidelines)
* [1. Correction](#1-correction)
* [2. Warning](#2-warning)
* [3. Temporary Ban](#3-temporary-ban)
* [4. Permanent Ban](#4-permanent-ban)
* [Attribution](#attribution)
- [Our Pledge](#our-pledge)
- [Our Standards](#our-standards)
- [Enforcement Responsibilities](#enforcement-responsibilities)
- [Scope](#scope)
- [Enforcement](#enforcement)
- [Enforcement Guidelines](#enforcement-guidelines)
- [1. Correction](#1-correction)
- [2. Warning](#2-warning)
- [3. Temporary Ban](#3-temporary-ban)
- [4. Permanent Ban](#4-permanent-ban)
- [Attribution](#attribution)
## Our Pledge
@ -29,23 +29,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@ -132,7 +132,7 @@ version 2.0, available [here](https://www.contributor-covenant.org/version/2/0/c
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the [FAQ](https://www.contributor-covenant.org/faq).
Translations are available [here](https://www.contributor-covenant.org/translations).
[homepage]: https://www.contributor-covenant.org

View file

@ -2,16 +2,16 @@
Welcome! We're happy to have you here. Thank you in advance for your contribution to Ruff.
* [The Basics](#the-basics)
* [Prerequisites](#prerequisites)
* [Development](#development)
* [Project Structure](#project-structure)
* [Example: Adding a new lint rule](#example-adding-a-new-lint-rule)
* [Rule naming convention](#rule-naming-convention)
* [Example: Adding a new configuration option](#example-adding-a-new-configuration-option)
* [MkDocs](#mkdocs)
* [Release Process](#release-process)
* [Benchmarks](#benchmarks)
- [The Basics](#the-basics)
- [Prerequisites](#prerequisites)
- [Development](#development)
- [Project Structure](#project-structure)
- [Example: Adding a new lint rule](#example-adding-a-new-lint-rule)
- [Rule naming convention](#rule-naming-convention)
- [Example: Adding a new configuration option](#example-adding-a-new-configuration-option)
- [MkDocs](#mkdocs)
- [Release Process](#release-process)
- [Benchmarks](#benchmarks)
## The Basics
@ -91,27 +91,27 @@ The vast majority of the code, including all lint rules, lives in the `ruff` cra
At time of writing, the repository includes the following crates:
* `crates/ruff`: library crate containing all lint rules and the core logic for running them.
* `crates/ruff_cli`: binary crate containing Ruff's command-line interface.
* `crates/ruff_dev`: binary crate containing utilities used in the development of Ruff itself (e.g., `cargo dev generate-all`).
* `crates/ruff_macros`: library crate containing macros used by Ruff.
* `crates/ruff_python`: library crate implementing Python-specific functionality (e.g., lists of standard library modules by versionb).
* `crates/flake8_to_ruff`: binary crate for generating Ruff configuration from Flake8 configuration.
- `crates/ruff`: library crate containing all lint rules and the core logic for running them.
- `crates/ruff_cli`: binary crate containing Ruff's command-line interface.
- `crates/ruff_dev`: binary crate containing utilities used in the development of Ruff itself (e.g., `cargo dev generate-all`).
- `crates/ruff_macros`: library crate containing macros used by Ruff.
- `crates/ruff_python`: library crate implementing Python-specific functionality (e.g., lists of standard library modules by versionb).
- `crates/flake8_to_ruff`: binary crate for generating Ruff configuration from Flake8 configuration.
### Example: Adding a new lint rule
At a high level, the steps involved in adding a new lint rule are as follows:
1. Determine a name for the new rule as per our [rule naming convention](#rule-naming-convention).
2. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`).
3. In that file, define a violation struct. You can grep for `define_violation!` to see examples.
4. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
5. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast.rs` (for AST-based
1. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`).
1. In that file, define a violation struct. You can grep for `define_violation!` to see examples.
1. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
1. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast.rs` (for AST-based
checks), `crates/ruff/src/checkers/tokens.rs` (for token-based checks), `crates/ruff/src/checkers/lines.rs`
(for text-based checks), or `crates/ruff/src/checkers/filesystem.rs` (for filesystem-based
checks).
6. Add a test fixture.
7. Update the generated files (documentation and generated code).
1. Add a test fixture.
1. Update the generated files (documentation and generated code).
To define the violation, start by creating a dedicated file for your rule under the appropriate
rule linter (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`). That file should
@ -147,9 +147,9 @@ The rule name should make sense when read as "allow _rule-name_" or "allow _rule
This implies that rule names:
* should state the bad thing being checked for
- should state the bad thing being checked for
* should not contain instructions on what you what you should use instead
- should not contain instructions on what you what you should use instead
(these belong in the rule documentation and the `autofix_title` for rules that have autofix)
When re-implementing rules from other linters, this convention is given more importance than
@ -191,13 +191,13 @@ To preview any changes to the documentation locally:
pip install -r docs/requirements.txt
```
2. Generate the MkDocs site with:
1. Generate the MkDocs site with:
```shell
python scripts/generate_mkdocs.py
```
3. Run the development server with:
1. Run the development server with:
```shell
mkdocs serve

116
README.md
View file

@ -24,17 +24,17 @@ An extremely fast Python linter, written in Rust.
<i>Linting the CPython codebase from scratch.</i>
</p>
* ⚡️ 10-100x faster than existing linters
* 🐍 Installable via `pip`
* 🛠️ `pyproject.toml` support
* 🤝 Python 3.11 compatibility
* 📦 Built-in caching, to avoid re-analyzing unchanged files
* 🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports)
* 📏 Over [500 built-in rules](https://beta.ruff.rs/docs/rules/) (and growing)
* ⚖️ [Near-parity](https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8) with the built-in Flake8 rule set
* 🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
* ⌨️ First-party editor integrations for [VS Code](https://github.com/charliermarsh/ruff-vscode) and [more](https://github.com/charliermarsh/ruff-lsp)
* 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://beta.ruff.rs/docs/configuration/#pyprojecttoml-discovery)
- ⚡️ 10-100x faster than existing linters
- 🐍 Installable via `pip`
- 🛠️ `pyproject.toml` support
- 🤝 Python 3.11 compatibility
- 📦 Built-in caching, to avoid re-analyzing unchanged files
- 🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports)
- 📏 Over [500 built-in rules](https://beta.ruff.rs/docs/rules/) (and growing)
- ⚖️ [Near-parity](https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8) with the built-in Flake8 rule set
- 🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
- ⌨️ First-party editor integrations for [VS Code](https://github.com/charliermarsh/ruff-vscode) and [more](https://github.com/charliermarsh/ruff-lsp)
- 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://beta.ruff.rs/docs/configuration/#pyprojecttoml-discovery)
Ruff aims to be orders of magnitude faster than alternative tools while integrating more
functionality behind a single, common interface.
@ -47,11 +47,11 @@ all while executing tens or hundreds of times faster than any individual tool.
Ruff is extremely actively developed and used in major open-source projects like:
* [pandas](https://github.com/pandas-dev/pandas)
* [FastAPI](https://github.com/tiangolo/fastapi)
* [Transformers (Hugging Face)](https://github.com/huggingface/transformers)
* [Apache Airflow](https://github.com/apache/airflow)
* [SciPy](https://github.com/scipy/scipy)
- [pandas](https://github.com/pandas-dev/pandas)
- [FastAPI](https://github.com/tiangolo/fastapi)
- [Transformers (Hugging Face)](https://github.com/huggingface/transformers)
- [Apache Airflow](https://github.com/apache/airflow)
- [SciPy](https://github.com/scipy/scipy)
...and many more.
@ -98,13 +98,13 @@ developer of [Zulip](https://github.com/zulip/zulip):
For more, see the [documentation](https://beta.ruff.rs/docs/).
1. [Getting Started](#getting-started)
2. [Configuration](#configuration)
3. [Rules](#rules)
4. [Contributing](#contributing)
5. [Support](#support)
6. [Acknowledgements](#acknowledgements)
7. [Who's Using Ruff?](#whos-using-ruff)
8. [License](#license)
1. [Configuration](#configuration)
1. [Rules](#rules)
1. [Contributing](#contributing)
1. [Support](#support)
1. [Acknowledgements](#acknowledgements)
1. [Who's Using Ruff?](#whos-using-ruff)
1. [License](#license)
## Getting Started
@ -269,41 +269,41 @@ Ruff is released under the MIT license.
Ruff is used in a number of major open-source projects, including:
* [pandas](https://github.com/pandas-dev/pandas)
* [FastAPI](https://github.com/tiangolo/fastapi)
* [Transformers (Hugging Face)](https://github.com/huggingface/transformers)
* [Diffusers (Hugging Face)](https://github.com/huggingface/diffusers)
* [Apache Airflow](https://github.com/apache/airflow)
* [SciPy](https://github.com/scipy/scipy)
* [Zulip](https://github.com/zulip/zulip)
* [Bokeh](https://github.com/bokeh/bokeh)
* [Pydantic](https://github.com/pydantic/pydantic)
* [Dagster](https://github.com/dagster-io/dagster)
* [Dagger](https://github.com/dagger/dagger)
* [Sphinx](https://github.com/sphinx-doc/sphinx)
* [Hatch](https://github.com/pypa/hatch)
* [PDM](https://github.com/pdm-project/pdm)
* [Jupyter](https://github.com/jupyter-server/jupyter_server)
* [Great Expectations](https://github.com/great-expectations/great_expectations)
* [ONNX](https://github.com/onnx/onnx)
* [Polars](https://github.com/pola-rs/polars)
* [Ibis](https://github.com/ibis-project/ibis)
* [Synapse (Matrix)](https://github.com/matrix-org/synapse)
* [SnowCLI (Snowflake)](https://github.com/Snowflake-Labs/snowcli)
* [Dispatch (Netflix)](https://github.com/Netflix/dispatch)
* [Saleor](https://github.com/saleor/saleor)
* [Pynecone](https://github.com/pynecone-io/pynecone)
* [OpenBB](https://github.com/OpenBB-finance/OpenBBTerminal)
* [Home Assistant](https://github.com/home-assistant/core)
* [Pylint](https://github.com/PyCQA/pylint)
* [Cryptography (PyCA)](https://github.com/pyca/cryptography)
* [cibuildwheel (PyPA)](https://github.com/pypa/cibuildwheel)
* [build (PyPA)](https://github.com/pypa/build)
* [Babel](https://github.com/python-babel/babel)
* [featuretools](https://github.com/alteryx/featuretools)
* [meson-python](https://github.com/mesonbuild/meson-python)
* [ZenML](https://github.com/zenml-io/zenml)
* [delta-rs](https://github.com/delta-io/delta-rs)
- [pandas](https://github.com/pandas-dev/pandas)
- [FastAPI](https://github.com/tiangolo/fastapi)
- [Transformers (Hugging Face)](https://github.com/huggingface/transformers)
- [Diffusers (Hugging Face)](https://github.com/huggingface/diffusers)
- [Apache Airflow](https://github.com/apache/airflow)
- [SciPy](https://github.com/scipy/scipy)
- [Zulip](https://github.com/zulip/zulip)
- [Bokeh](https://github.com/bokeh/bokeh)
- [Pydantic](https://github.com/pydantic/pydantic)
- [Dagster](https://github.com/dagster-io/dagster)
- [Dagger](https://github.com/dagger/dagger)
- [Sphinx](https://github.com/sphinx-doc/sphinx)
- [Hatch](https://github.com/pypa/hatch)
- [PDM](https://github.com/pdm-project/pdm)
- [Jupyter](https://github.com/jupyter-server/jupyter_server)
- [Great Expectations](https://github.com/great-expectations/great_expectations)
- [ONNX](https://github.com/onnx/onnx)
- [Polars](https://github.com/pola-rs/polars)
- [Ibis](https://github.com/ibis-project/ibis)
- [Synapse (Matrix)](https://github.com/matrix-org/synapse)
- [SnowCLI (Snowflake)](https://github.com/Snowflake-Labs/snowcli)
- [Dispatch (Netflix)](https://github.com/Netflix/dispatch)
- [Saleor](https://github.com/saleor/saleor)
- [Pynecone](https://github.com/pynecone-io/pynecone)
- [OpenBB](https://github.com/OpenBB-finance/OpenBBTerminal)
- [Home Assistant](https://github.com/home-assistant/core)
- [Pylint](https://github.com/PyCQA/pylint)
- [Cryptography (PyCA)](https://github.com/pyca/cryptography)
- [cibuildwheel (PyPA)](https://github.com/pypa/cibuildwheel)
- [build (PyPA)](https://github.com/pypa/build)
- [Babel](https://github.com/python-babel/babel)
- [featuretools](https://github.com/alteryx/featuretools)
- [meson-python](https://github.com/mesonbuild/meson-python)
- [ZenML](https://github.com/zenml-io/zenml)
- [delta-rs](https://github.com/delta-io/delta-rs)
## License

View file

@ -84,7 +84,7 @@ flake8-to-ruff path/to/.flake8 --plugin flake8-builtins --plugin flake8-quotes
1. Ruff only supports a subset of the Flake configuration options. `flake8-to-ruff` will warn on and
ignore unsupported options in the `.flake8` file (or equivalent). (Similarly, Ruff has a few
configuration options that don't exist in Flake8.)
2. Ruff will omit any rule codes that are unimplemented or unsupported by Ruff, including rule
1. Ruff will omit any rule codes that are unimplemented or unsupported by Ruff, including rule
codes from unsupported plugins. (See the [Ruff README](https://github.com/charliermarsh/ruff#user-content-how-does-ruff-compare-to-flake8)
for the complete list of supported plugins.)

View file

@ -398,9 +398,9 @@ define_violation!(
/// ```
///
/// ## 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)
/// - [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)
pub struct AnyType {
pub name: String,
}

View file

@ -37,8 +37,8 @@ pub struct Options {
/// Whether to suppress `ANN200`-level violations for functions that meet
/// either of the following criteria:
///
/// * Contain no `return` statement.
/// * Explicit `return` statement(s) all return `None` (explicitly or
/// - Contain no `return` statement.
/// - Explicit `return` statement(s) all return `None` (explicitly or
/// implicitly).
pub suppress_none_returning: Option<bool>,
#[option(

View file

@ -33,8 +33,8 @@ define_violation!(
/// ```
///
/// ## 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)
/// - [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)
pub struct HardcodedSQLExpression;
);
impl Violation for HardcodedSQLExpression {

View file

@ -23,7 +23,7 @@ define_violation!(
///
/// ## Options
///
/// * `flake8-builtins.builtins-ignorelist`
/// - `flake8-builtins.builtins-ignorelist`
///
/// ## Example
/// ```python
@ -45,7 +45,7 @@ define_violation!(
/// return result
/// ```
///
/// * [Why is it a bad idea to name a variable `id` in Python?_](https://stackoverflow.com/questions/77552/id-is-a-bad-variable-name-in-python)
/// - [_Why is it a bad idea to name a variable `id` in Python?_](https://stackoverflow.com/questions/77552/id-is-a-bad-variable-name-in-python)
pub struct BuiltinVariableShadowing {
pub name: String,
}
@ -73,7 +73,7 @@ define_violation!(
///
/// ## Options
///
/// * `flake8-builtins.builtins-ignorelist`
/// - `flake8-builtins.builtins-ignorelist`
///
/// ## Example
/// ```python
@ -128,7 +128,7 @@ define_violation!(
///
/// ## Options
///
/// * `flake8-builtins.builtins-ignorelist`
/// - `flake8-builtins.builtins-ignorelist`
///
/// ## Example
/// ```python

View file

@ -32,19 +32,19 @@ define_violation!(
///
/// 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)`.
/// - 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)`.
pub struct UnnecessaryDoubleCastOrProcess {
pub inner: String,
pub outer: String,

View file

@ -32,11 +32,11 @@ define_violation!(
///
/// 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
/// - 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
/// - 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
/// - Instead of `dict(map(lambda v: (v, v ** 2), values))`, use
/// `{v: v ** 2 for v in values}`.
pub struct UnnecessaryMap {
pub obj_type: String,

View file

@ -20,6 +20,7 @@ define_violation!(
/// ```python
/// from django.forms import ModelForm
///
///
/// class PostForm(ModelForm):
/// class Meta:
/// model = Post
@ -30,6 +31,7 @@ define_violation!(
/// ```python
/// from django.forms import ModelForm
///
///
/// class PostForm(ModelForm):
/// class Meta:
/// model = Post

View file

@ -26,19 +26,21 @@ define_violation!(
/// ```python
/// from django.db import models
///
///
/// class MyModel(models.Model):
/// field = models.CharField(max_length=255)
/// 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}"
/// class MyModel(models.Model):
/// field = models.CharField(max_length=255)
///
/// def __str__(self):
/// return f"{self.field}"
/// ```
pub struct ModelWithoutDunderStr;
);

View file

@ -22,10 +22,11 @@ define_violation!(
/// 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
/// pass
/// ```
///
/// Use instead:
@ -33,6 +34,7 @@ define_violation!(
/// 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):

View file

@ -28,14 +28,16 @@ define_violation!(
/// ```python
/// from django.db import models
///
///
/// class MyModel(models.Model):
/// field = models.CharField(max_length=255, null=True)
/// 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="")
/// ```

View file

@ -24,7 +24,7 @@ define_violation!(
/// ```
///
/// Python will produce a traceback like:
/// ```python
/// ```console
/// Traceback (most recent call last):
/// File "tmp.py", line 2, in <module>
/// raise RuntimeError("Some value is incorrect")
@ -38,7 +38,7 @@ define_violation!(
/// ```
///
/// Which will produce a traceback like:
/// ```python
/// ```console
/// Traceback (most recent call last):
/// File "tmp.py", line 3, in <module>
/// raise RuntimeError(msg)
@ -72,7 +72,7 @@ define_violation!(
/// ```
///
/// Python will produce a traceback like:
/// ```python
/// ```console
/// Traceback (most recent call last):
/// File "tmp.py", line 2, in <module>
/// raise RuntimeError(f"{sub!r} is incorrect")
@ -87,8 +87,7 @@ define_violation!(
/// ```
///
/// Which will produce a traceback like:
/// ```python
/// Traceback (most recent call last):
/// ```console
/// File "tmp.py", line 3, in <module>
/// raise RuntimeError(msg)
/// RuntimeError: 'Some value' is incorrect
@ -122,7 +121,7 @@ define_violation!(
/// ```
///
/// Python will produce a traceback like:
/// ```python
/// ```console
/// Traceback (most recent call last):
/// File "tmp.py", line 2, in <module>
/// raise RuntimeError("'{}' is incorrect".format(sub))
@ -137,7 +136,7 @@ define_violation!(
/// ```
///
/// Which will produce a traceback like:
/// ```python
/// ```console
/// Traceback (most recent call last):
/// File "tmp.py", line 3, in <module>
/// raise RuntimeError(msg)

View file

@ -56,7 +56,7 @@ define_violation!(
/// to `false`.
///
/// ## Options
/// * `flake8-implicit-str-concat.allow-multiline`
/// - `flake8-implicit-str-concat.allow-multiline`
///
/// ## Example
/// ```python
@ -73,7 +73,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [PEP 8](https://peps.python.org/pep-0008/#maximum-line-length)
/// - [PEP 8](https://peps.python.org/pep-0008/#maximum-line-length)
pub struct MultiLineImplicitStringConcatenation;
);
impl Violation for MultiLineImplicitStringConcatenation {

View file

@ -25,7 +25,7 @@ define_violation!(
/// the absence of the `__init__.py` file is probably an oversight.
///
/// ## Options
/// * `namespace-packages`
/// - `namespace-packages`
pub struct ImplicitNamespacePackage {
pub filename: String,
}

View file

@ -72,7 +72,7 @@ define_violation!(
/// For example, compare the performance of `all` with a list comprehension against that
/// of a generator (~40x faster here):
///
/// ```python
/// ```console
/// In [1]: %timeit all([i for i in range(1000)])
/// 8.14 µs ± 25.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
///

View file

@ -22,21 +22,25 @@ define_violation!(
/// ## Example
/// ```python
/// if sys.platform.startswith("linux"):
/// # Linux specific definitions
/// # Linux specific definitions
/// ...
/// else:
/// # Posix specific definitions
/// # 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)
/// - [PEP 484](https://peps.python.org/pep-0484/#version-and-platform-checking)
pub struct UnrecognizedPlatformCheck;
);
impl Violation for UnrecognizedPlatformCheck {
@ -68,11 +72,11 @@ define_violation!(
/// Use instead:
/// ```python
/// if sys.platform == "linux":
/// ...
/// ...
/// ```
///
/// ## References
/// * [PEP 484](https://peps.python.org/pep-0484/#version-and-platform-checking)
/// - [PEP 484](https://peps.python.org/pep-0484/#version-and-platform-checking)
pub struct UnrecognizedPlatformName {
pub platform: String,
}

View file

@ -39,6 +39,7 @@ define_violation!(
/// def test_foo():
/// assert something and something_else
///
///
/// def test_bar():
/// assert not (something or something_else)
/// ```
@ -49,6 +50,7 @@ define_violation!(
/// assert something
/// assert something_else
///
///
/// def test_bar():
/// assert not something
/// assert not something_else

View file

@ -48,11 +48,11 @@ pub struct Options {
/// Expected type for multiple argument names in `@pytest.mark.parametrize`.
/// The following values are supported:
///
/// * `csv` — a comma-separated list, e.g.
/// - `csv` — a comma-separated list, e.g.
/// `@pytest.mark.parametrize('name1,name2', ...)`
/// * `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'),
/// ...)`
/// * `list` — e.g. `@pytest.mark.parametrize(['name1', 'name2'], ...)`
/// - `tuple` (default) — e.g.
/// `@pytest.mark.parametrize(('name1', 'name2'), ...)`
/// - `list` — e.g. `@pytest.mark.parametrize(['name1', 'name2'], ...)`
pub parametrize_names_type: Option<types::ParametrizeNameType>,
#[option(
default = "list",
@ -62,8 +62,8 @@ pub struct Options {
/// Expected type for the list of values rows in `@pytest.mark.parametrize`.
/// The following values are supported:
///
/// * `tuple` — e.g. `@pytest.mark.parametrize('name', (1, 2, 3))`
/// * `list` (default) — e.g. `@pytest.mark.parametrize('name', [1, 2, 3])`
/// - `tuple` — e.g. `@pytest.mark.parametrize('name', (1, 2, 3))`
/// - `list` (default) — e.g. `@pytest.mark.parametrize('name', [1, 2, 3])`
pub parametrize_values_type: Option<types::ParametrizeValuesType>,
#[option(
default = "tuple",
@ -73,10 +73,10 @@ pub struct Options {
/// Expected type for each row of values in `@pytest.mark.parametrize` in
/// case of multiple parameters. The following values are supported:
///
/// * `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'),
/// [(1, 2), (3, 4)])`
/// * `list` — e.g. `@pytest.mark.parametrize(('name1', 'name2'), [[1, 2],
/// [3, 4]])`
/// - `tuple` (default) — e.g.
/// `@pytest.mark.parametrize(('name1', 'name2'), [(1, 2), (3, 4)])`
/// - `list` — e.g.
/// `@pytest.mark.parametrize(('name1', 'name2'), [[1, 2], [3, 4]])`
pub parametrize_values_row_type: Option<types::ParametrizeValuesRowType>,
#[option(
default = r#"["BaseException", "Exception", "ValueError", "OSError", "IOError", "EnvironmentError", "socket.error"]"#,

View file

@ -22,7 +22,7 @@ define_violation!(
/// strings, but be consistent.
///
/// ## Options
/// * `flake8-quotes.inline-quotes`
/// - `flake8-quotes.inline-quotes`
///
/// ## Example
/// ```python
@ -67,7 +67,7 @@ define_violation!(
/// strings, but be consistent.
///
/// ## Options
/// * `flake8-quotes.multiline-quotes`
/// - `flake8-quotes.multiline-quotes`
///
/// ## Example
/// ```python
@ -115,7 +115,7 @@ define_violation!(
/// strings, but be consistent.
///
/// ## Options
/// * `flake8-quotes.docstring-quotes`
/// - `flake8-quotes.docstring-quotes`
///
/// ## Example
/// ```python

View file

@ -23,7 +23,7 @@ define_violation!(
/// behavior. Instead, use the class's public interface.
///
/// ## Options
/// * `flake8-self.ignore-names`
/// - `flake8-self.ignore-names`
///
/// ## Example
/// ```python
@ -31,6 +31,7 @@ define_violation!(
/// def __init__(self):
/// self._private_member = "..."
///
///
/// var = Class()
/// print(var._private_member)
/// ```
@ -41,12 +42,13 @@ define_violation!(
/// def __init__(self):
/// self.public_member = "..."
///
///
/// var = Class()
/// print(var.public_member)
/// ```
///
/// ## References
/// * [_What is the meaning of single or double underscores before an object name?_](https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-single-and-double-underscore-before-an-object-name)
/// - [_What is the meaning of single or double underscores before an object name?_](https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-single-and-double-underscore-before-an-object-name)
pub struct PrivateMemberAccess {
pub access: String,
}

View file

@ -38,8 +38,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [Python: "isinstance"](https://docs.python.org/3/library/functions.html#isinstance)
/// ```
/// - [Python: "isinstance"](https://docs.python.org/3/library/functions.html#isinstance)
pub struct DuplicateIsinstanceCall {
pub name: String,
}

View file

@ -76,20 +76,20 @@ impl Violation for NeedlessBool {
}
define_violation!(
/// ### What it does
/// ## What it does
/// Checks for three or more consecutive if-statements with direct returns
///
/// ### Why is this bad?
/// ## Why is this bad?
/// These can be simplified by using a dictionary
///
/// ### Example
/// ## Example
/// ```python
/// if x == 1:
/// return "Hello"
/// elif x == 2:
/// return "Goodbye"
/// else:
/// return "Goodnight"
/// return "Goodnight"
/// ```
///
/// Use instead:
@ -129,14 +129,14 @@ impl Violation for UseTernaryOperator {
}
define_violation!(
/// ### What it does
/// ## What it does
/// Checks for `if` branches with identical arm bodies.
///
/// ### Why is this bad?
/// ## 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
/// ## Example
/// ```python
/// if x == 1:
/// print("Hello")

View file

@ -38,7 +38,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [Python: "The with statement"](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)
/// - [Python: "The with statement"](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)
pub struct MultipleWithStatements {
pub fixable: bool,
}

View file

@ -36,7 +36,7 @@ define_violation!(
/// automatic way.
///
/// ## Options
/// * `flake8-tidy-imports.banned-api`
/// - `flake8-tidy-imports.banned-api`
pub struct BannedApi {
pub name: String,
pub message: String,

View file

@ -47,7 +47,7 @@ define_violation!(
/// > ```
///
/// ## Options
/// * `flake8-tidy-imports.ban-relative-imports`
/// - `flake8-tidy-imports.ban-relative-imports`
///
/// ## Example
/// ```python

View file

@ -22,8 +22,9 @@ define_violation!(
///
/// ## 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
/// 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.
///

View file

@ -180,8 +180,8 @@ pub struct Options {
///
/// The default ("furthest-to-closest") is equivalent to isort's
/// `reverse-relative` default (`reverse-relative = false`); setting
/// this to "closest-to-furthest" is equivalent to isort's `reverse-relative
/// = true`.
/// this to "closest-to-furthest" is equivalent to isort's
/// `reverse-relative = true`.
pub relative_imports_order: Option<RelativeImportsOrder>,
#[option(
default = r#"[]"#,

View file

@ -20,7 +20,7 @@ define_violation!(
/// Functions with a high complexity are hard to understand and maintain.
///
/// ## Options
/// * `mccabe.max-complexity`
/// - `mccabe.max-complexity`
///
/// ## Example
/// ```python

View file

@ -31,7 +31,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [_Why You Should Probably Never Use pandas inplace=True_](https://towardsdatascience.com/why-you-should-probably-never-use-pandas-inplace-true-9f9f211849e4)
/// - [_Why You Should Probably Never Use pandas inplace=True_](https://towardsdatascience.com/why-you-should-probably-never-use-pandas-inplace-true-9f9f211849e4)
pub struct UseOfInplaceArgument;
);
impl AlwaysAutofixableViolation for UseOfInplaceArgument {

View file

@ -17,7 +17,7 @@ define_violation!(
///
/// > ..."magic" objects or attributes that live in user-controlled
/// > namespaces. E.g. `__init__`, `__import__` or `__file__`. Never invent
/// such names; only use them as documented.
/// > such names; only use them as documented.
///
/// ## Example
/// ```python

View file

@ -16,16 +16,16 @@ define_violation!(
/// [PEP 8] recommends the use of `cls` as the first argument for all class
/// methods:
///
/// > Always use cls for the first argument to class methods.
/// > Always use `cls` for the first argument to class methods.
/// >
/// > If a function arguments name clashes with a reserved keyword, it is generally better to
/// > append a single trailing underscore rather than use an abbreviation or spelling corruption.
/// > Thus class_ is better than clss. (Perhaps better is to avoid such clashes by using a synonym.)
/// > Thus `class_` is better than `clss`. (Perhaps better is to avoid such clashes by using a synonym.)
///
/// ## Options
/// * `pep8-naming.classmethod-decorators`
/// * `pep8-naming.staticmethod-decorators`
/// * `pep8-naming.ignore-names`
/// - `pep8-naming.classmethod-decorators`
/// - `pep8-naming.staticmethod-decorators`
/// - `pep8-naming.ignore-names`
///
/// ## Example
/// ```python

View file

@ -20,12 +20,12 @@ define_violation!(
/// >
/// > If a function arguments name clashes with a reserved keyword, it is generally better to
/// > append a single trailing underscore rather than use an abbreviation or spelling corruption.
/// > Thus class_ is better than clss. (Perhaps better is to avoid such clashes by using a synonym.)
/// > Thus `class_` is better than `clss`. (Perhaps better is to avoid such clashes by using a synonym.)
///
/// ## Options
/// * `pep8-naming.classmethod-decorators`
/// * `pep8-naming.staticmethod-decorators`
/// * `pep8-naming.ignore-names`
/// - `pep8-naming.classmethod-decorators`
/// - `pep8-naming.staticmethod-decorators`
/// - `pep8-naming.ignore-names`
///
/// ## Example
/// ```python

View file

@ -19,7 +19,7 @@ define_violation!(
/// > prevailing style (e.g. threading.py), to retain backwards compatibility.
///
/// ## Options
/// * `pep8-naming.ignore-names`
/// - `pep8-naming.ignore-names`
///
/// ## Example
/// ```python

View file

@ -25,8 +25,8 @@ define_violation!(
/// > a leading underscore (e.g. `_socket`).
///
/// ## Example
/// * Instead of `example-module-name` or `example module name`, use `example_module_name`.
/// * Instead of `ExampleModule`, use `example_module`.
/// - Instead of `example-module-name` or `example module name`, use `example_module_name`.
/// - Instead of `ExampleModule`, use `example_module`.
///
/// [PEP 8]: https://peps.python.org/pep-0008/#package-and-module-names
pub struct InvalidModuleName {

View file

@ -17,10 +17,10 @@ define_violation!(
/// > Function names should be lowercase, with words separated by underscores as necessary to
/// > improve readability. Variable names follow the same convention as function names. mixedCase
/// > is allowed only in contexts where that's already the prevailing style (e.g. threading.py),
/// to retain backwards compatibility.
/// > to retain backwards compatibility.
///
/// ## Options
/// * `pep8-naming.ignore-names`
/// - `pep8-naming.ignore-names`
///
/// ## Example
/// ```python

View file

@ -19,7 +19,7 @@ define_violation!(
/// ## Example
/// ```python
/// try:
/// raise(KeyboardInterrupt("You probably don't mean to break CTRL-C."))
/// raise KeyboardInterrupt("You probably don't mean to break CTRL-C.")
/// except:
/// print("But a bare `except` will ignore keyboard interrupts.")
/// ```
@ -33,9 +33,9 @@ define_violation!(
/// ```
///
/// ## 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)
/// - [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)
pub struct BareExcept;
);
impl Violation for BareExcept {

View file

@ -27,8 +27,8 @@ pub struct Options {
"#
)]
/// Whether line-length violations (`E501`) should be triggered for
/// comments starting with `task-tags` (by default: ["TODO", "FIXME",
/// and "XXX"]).
/// comments starting with `task-tags` (by default: \["TODO", "FIXME",
/// and "XXX"\]).
pub ignore_overlong_task_comments: Option<bool>,
}

View file

@ -33,7 +33,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [PEP 498](https://www.python.org/dev/peps/pep-0498/)
/// - [PEP 498](https://www.python.org/dev/peps/pep-0498/)
pub struct FStringMissingPlaceholders;
);
impl AlwaysAutofixableViolation for FStringMissingPlaceholders {

View file

@ -26,7 +26,7 @@ define_violation!(
/// [`dummy-variable-rgx`] pattern.
///
/// ## Options
/// * `dummy-variable-rgx`
/// - `dummy-variable-rgx`
///
/// ## Example
/// ```python

View file

@ -24,7 +24,7 @@ define_violation!(
/// try:
/// function()
/// except Exception as e:
/// logging.error('%s error occurred: %s', e) # [logging-too-few-args]
/// logging.error("%s error occurred: %s", e)
/// raise
/// ```
///
@ -35,7 +35,7 @@ define_violation!(
/// try:
/// function()
/// except Exception as e:
/// logging.error('%s error occurred: %s', type(e), e)
/// logging.error("%s error occurred: %s", type(e), e)
/// raise
/// ```
pub struct LoggingTooFewArgs;
@ -61,7 +61,7 @@ define_violation!(
/// try:
/// function()
/// except Exception as e:
/// logging.error('Error occurred: %s', type(e), e) # [logging-too-many-args]
/// logging.error("Error occurred: %s", type(e), e)
/// raise
/// ```
///
@ -72,7 +72,7 @@ define_violation!(
/// try:
/// function()
/// except Exception as e:
/// logging.error('%s error occurred: %s', type(e), e)
/// logging.error("%s error occurred: %s", type(e), e)
/// raise
/// ```
pub struct LoggingTooManyArgs;

View file

@ -29,12 +29,12 @@ define_violation!(
/// Use instead:
/// ```python
/// class Example:
/// def __init__(self):
/// self.value = []
/// def __init__(self):
/// self.value = []
/// ```
///
/// ## References
/// * [CodeQL: `py-explicit-return-in-init`](https://codeql.github.com/codeql-query-help/python/py-explicit-return-in-init/)
/// - [CodeQL: `py-explicit-return-in-init`](https://codeql.github.com/codeql-query-help/python/py-explicit-return-in-init/)
pub struct ReturnInInit;
);
impl Violation for ReturnInInit {

View file

@ -28,7 +28,7 @@ define_violation!(
/// ```
///
/// ## References
/// * [CodeQL: `py-init-method-is-generator`](https://codeql.github.com/codeql-query-help/python/py-init-method-is-generator/)
/// - [CodeQL: `py-init-method-is-generator`](https://codeql.github.com/codeql-query-help/python/py-init-method-is-generator/)
pub struct YieldInInit;
);

View file

@ -22,8 +22,8 @@ pub struct Options {
"#
)]
/// Whether to avoid PEP 585 (`List[int]` -> `list[int]`) and PEP 604
/// (`Optional[str]` -> `str | None`) rewrites even if a file imports `from
/// __future__ import annotations`. Note that this setting is only
/// (`Optional[str]` -> `str | None`) rewrites even if a file imports
/// `from __future__ import annotations`. Note that this setting is only
/// applicable when the target Python version is below 3.9 and 3.10
/// respectively, and enabling it is equivalent to disabling
/// `use-pep585-annotation` (`UP006`) and `use-pep604-annotation`

View file

@ -25,9 +25,9 @@ define_violation!(
/// import asyncio
///
/// for i in range(10):
/// # This creates a weak reference to the task, which may be garbage
/// # collected at any time.
/// asyncio.create_task(some_coro(param=i))
/// # This creates a weak reference to the task, which may be garbage
/// # collected at any time.
/// asyncio.create_task(some_coro(param=i))
/// ```
///
/// Use instead:
@ -49,8 +49,8 @@ define_violation!(
/// ```
///
/// ## References
/// * [_The Heisenbug lurking in your async code_](https://textual.textualize.io/blog/2023/02/11/the-heisenbug-lurking-in-your-async-code/)
/// * [The Python Standard Library](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)
/// - [_The Heisenbug lurking in your async code_](https://textual.textualize.io/blog/2023/02/11/the-heisenbug-lurking-in-your-async-code/)
/// - [The Python Standard Library](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)
pub struct AsyncioDanglingTask {
pub method: Method,
}

View file

@ -24,6 +24,8 @@ define_violation!(
/// def main_function():
/// if not cond:
/// raise Exception()
///
///
/// def consumer_func():
/// try:
/// do_step()
@ -38,6 +40,8 @@ define_violation!(
/// def main_function():
/// if not cond:
/// raise CustomException()
///
///
/// def consumer_func():
/// try:
/// do_step()

View file

@ -11,15 +11,15 @@ use crate::rules::tryceratops::helpers::LoggerCandidateVisitor;
use crate::violation::Violation;
define_violation!(
/// ### What it does
/// ## What it does
/// Checks for excessive logging of exception objects.
///
/// ### Why is this bad?
/// ## Why is this bad?
/// When logging exceptions via `logging.exception`, the exception object
/// is logged automatically. Including the exception object in the log
/// message is redundant and can lead to excessive logging.
///
/// ### Example
/// ## Example
/// ```python
/// try:
/// ...

View file

@ -80,10 +80,10 @@ pub struct Options {
///
/// Exclusions are based on globs, and can be either:
///
/// * Single-path patterns, like `.mypy_cache` (to exclude any directory
/// - Single-path patterns, like `.mypy_cache` (to exclude any directory
/// named `.mypy_cache` in the tree), `foo.py` (to exclude any file named
/// `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ).
/// * Relative patterns, like `directory/foo.py` (to exclude that specific
/// - Relative patterns, like `directory/foo.py` (to exclude that specific
/// file) or `directory/*.py` (to exclude any Python files in
/// `directory`). Note that these paths are relative to the project root
/// (e.g., the directory containing your `pyproject.toml`).
@ -124,10 +124,10 @@ pub struct Options {
///
/// Exclusions are based on globs, and can be either:
///
/// * Single-path patterns, like `.mypy_cache` (to exclude any directory
/// - Single-path patterns, like `.mypy_cache` (to exclude any directory
/// named `.mypy_cache` in the tree), `foo.py` (to exclude any file named
/// `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ).
/// * Relative patterns, like `directory/foo.py` (to exclude that specific
/// - Relative patterns, like `directory/foo.py` (to exclude that specific
/// file) or `directory/*.py` (to exclude any Python files in
/// `directory`). Note that these paths are relative to the project root
/// (e.g., the directory containing your `pyproject.toml`).
@ -346,13 +346,13 @@ pub struct Options {
/// bar.py
/// ```
///
/// The `src` directory should be included in the `src` option (e.g., `src =
/// ["src"]`), such that when resolving imports, `my_package.foo` is
/// considered a first-party import.
/// The `src` directory should be included in the `src` option
/// (e.g., `src = ["src"]`), such that when resolving imports,
/// `my_package.foo` is considered a first-party import.
///
/// This field supports globs. For example, if you have a series of Python
/// packages in a `python_modules` directory, `src =
/// ["python_modules/*"]` would expand to incorporate all of the
/// packages in a `python_modules` directory, `src = ["python_modules/*"]`
/// would expand to incorporate all of the
/// packages in that directory. User home directory and environment
/// variables will also be expanded.
pub src: Option<Vec<String>>,

View file

@ -78,7 +78,7 @@ fn process_documentation(documentation: &str, out: &mut String) {
if line.starts_with("## ") {
in_options = line == "## Options\n";
} else if in_options {
if let Some(rest) = line.strip_prefix("* `") {
if let Some(rest) = line.strip_prefix("- `") {
let option = rest.trim_end().trim_end_matches('`');
assert!(
@ -87,7 +87,7 @@ fn process_documentation(documentation: &str, out: &mut String) {
);
let anchor = option.rsplit('.').next().unwrap();
out.push_str(&format!("* [`{option}`][{option}]\n"));
out.push_str(&format!("- [`{option}`][{option}]\n"));
after.push_str(&format!("[{option}]: ../../settings#{anchor}"));
continue;
@ -100,6 +100,7 @@ fn process_documentation(documentation: &str, out: &mut String) {
out.push_str("\n\n");
out.push_str(&after);
}
out.push('\n');
}
#[cfg(test)]
@ -116,7 +117,7 @@ Something [`else`][other].
## Options
* `mccabe.max-complexity`
- `mccabe.max-complexity`
[other]: http://example.com.",
&mut out,
@ -129,11 +130,11 @@ Something [`else`][other].
## Options
* [`mccabe.max-complexity`][mccabe.max-complexity]
- [`mccabe.max-complexity`][mccabe.max-complexity]
[other]: http://example.com.
[mccabe.max-complexity]: ../../settings#max-complexity"
[mccabe.max-complexity]: ../../settings#max-complexity\n"
);
}
}

View file

@ -433,8 +433,8 @@ where
/// A Buffer that removes any soft line breaks.
///
/// * Removes [`lines`](FormatElement::Line) with the mode [`Soft`](LineMode::Soft).
/// * Replaces [`lines`](FormatElement::Line) with the mode [`Soft`](LineMode::SoftOrSpace) with a [`Space`](FormatElement::Space)
/// - Removes [`lines`](FormatElement::Line) with the mode [`Soft`](LineMode::Soft).
/// - Replaces [`lines`](FormatElement::Line) with the mode [`Soft`](LineMode::SoftOrSpace) with a [`Space`](FormatElement::Space)
///
/// # Examples
///

View file

@ -602,8 +602,8 @@ impl<Context> std::fmt::Debug for Indent<'_, Context> {
}
/// It reduces the indention for the given content depending on the closest [indent] or [align] parent element.
/// * [align] Undoes the spaces added by [align]
/// * [indent] Reduces the indention level by one
/// - [align] Undoes the spaces added by [align]
/// - [indent] Reduces the indention level by one
///
/// This is a No-op if the indention level is zero.
///
@ -774,8 +774,8 @@ where
///
/// You can see that:
///
/// * the printer indents the function's `}` by two spaces because it is inside of an `align`.
/// * the block `console.log` gets indented by two tabs.
/// - the printer indents the function's `}` by two spaces because it is inside of an `align`.
/// - the block `console.log` gets indented by two tabs.
/// This is because `align` increases the indention level by one (same as `indent`)
/// if you nest an `indent` inside an `align`.
/// Meaning that, `align > ... > indent` results in the same indention as `indent > ... > indent`.
@ -825,8 +825,8 @@ where
/// The printing of `align` differs if using spaces as indention sequence *and* it contains an `indent`.
/// You can see the difference when comparing the indention of the `console.log(...)` expression to the previous example:
///
/// * tab indention: Printer indents the expression with two tabs because the `align` increases the indention level.
/// * space indention: Printer indents the expression by 4 spaces (one indention level) **and** 2 spaces for the align.
/// - tab indention: Printer indents the expression with two tabs because the `align` increases the indention level.
/// - space indention: Printer indents the expression by 4 spaces (one indention level) **and** 2 spaces for the align.
pub fn align<Content, Context>(count: u8, content: &Content) -> Align<Context>
where
Content: Format<Context>,

View file

@ -81,9 +81,9 @@ pub enum InvalidDocumentError {
StartTagMissing { kind: TagKind },
/// Expected a specific start tag but instead is:
/// * at the end of the document
/// * at another start tag
/// * at an end tag
/// - at the end of the document
/// - at another start tag
/// - at an end tag
ExpectedStart {
expected_start: TagKind,
actual: ActualStart,

View file

@ -328,8 +328,8 @@ impl std::fmt::Debug for BestFitting {
pub trait FormatElements {
/// Returns true if this [FormatElement] is guaranteed to break across multiple lines by the printer.
/// This is the case if this format element recursively contains a:
/// * [crate::builders::empty_line] or [crate::builders::hard_line_break]
/// * A token containing '\n'
/// - [crate::builders::empty_line] or [crate::builders::hard_line_break]
/// - A token containing '\n'
///
/// Use this with caution, this is only a heuristic and the printer may print the element over multiple
/// lines if this element is part of a group and the group doesn't fit on a single line.
@ -339,12 +339,12 @@ pub trait FormatElements {
fn has_label(&self, label: LabelId) -> bool;
/// Returns the start tag of `kind` if:
/// * the last element is an end tag of `kind`.
/// * there's a matching start tag in this document (may not be true if this slice is an interned element and the `start` is in the document storing the interned element).
/// - the last element is an end tag of `kind`.
/// - there's a matching start tag in this document (may not be true if this slice is an interned element and the `start` is in the document storing the interned element).
fn start_tag(&self, kind: TagKind) -> Option<&Tag>;
/// Returns the end tag if:
/// * the last element is an end tag of `kind`
/// - the last element is an end tag of `kind`
fn end_tag(&self, kind: TagKind) -> Option<&Tag>;
}

View file

@ -21,9 +21,9 @@ pub struct Document {
impl Document {
/// Sets [`expand`](tag::Group::expand) to [`GroupMode::Propagated`] if the group contains any of:
/// * a group with [`expand`](tag::Group::expand) set to [GroupMode::Propagated] or [GroupMode::Expand].
/// * a non-soft [line break](FormatElement::Line) with mode [LineMode::Hard], [LineMode::Empty], or [LineMode::Literal].
/// * a [FormatElement::ExpandParent]
/// - a group with [`expand`](tag::Group::expand) set to [GroupMode::Propagated] or [GroupMode::Expand].
/// - a non-soft [line break](FormatElement::Line) with mode [LineMode::Hard], [LineMode::Empty], or [LineMode::Literal].
/// - a [FormatElement::ExpandParent]
///
/// [`BestFitting`] elements act as expand boundaries, meaning that the fact that a
/// [`BestFitting`]'s content expands is not propagated past the [`BestFitting`] element.

View file

@ -29,8 +29,8 @@ pub enum Tag {
EndDedent,
/// Creates a logical group where its content is either consistently printed:
/// * on a single line: Omitting `LineMode::Soft` line breaks and printing spaces for `LineMode::SoftOrSpace`
/// * on multiple lines: Printing all line breaks
/// - on a single line: Omitting `LineMode::Soft` line breaks and printing spaces for `LineMode::SoftOrSpace`
/// - on multiple lines: Printing all line breaks
///
/// See [crate::builders::group] for documentation and examples.
StartGroup(Group),
@ -203,8 +203,8 @@ pub enum DedentMode {
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Condition {
/// * Flat -> Omitted if the enclosing group is a multiline group, printed for groups fitting on a single line
/// * Multiline -> Omitted if the enclosing group fits on a single line, printed if the group breaks over multiple lines.
/// - Flat -> Omitted if the enclosing group is a multiline group, printed for groups fitting on a single line
/// - Multiline -> Omitted if the enclosing group fits on a single line, printed if the group breaks over multiple lines.
pub(crate) mode: PrintMode,
/// The id of the group for which it should check if it breaks or not. The group must appear in the document

View file

@ -147,8 +147,8 @@ macro_rules! format {
/// Provides multiple different alternatives and the printer picks the first one that fits.
/// Use this as last resort because it requires that the printer must try all variants in the worst case.
/// The passed variants must be in the following order:
/// * First: The variant that takes up most space horizontally
/// * Last: The variant that takes up the least space horizontally by splitting the content over multiple lines.
/// - First: The variant that takes up most space horizontally
/// - Last: The variant that takes up the least space horizontally by splitting the content over multiple lines.
///
/// ## Examples
///
@ -306,9 +306,9 @@ macro_rules! format {
///
/// ## Complexity
/// Be mindful of using this IR element as it has a considerable performance penalty:
/// * There are multiple representation for the same content. This results in increased memory usage
/// - There are multiple representation for the same content. This results in increased memory usage
/// and traversal time in the printer.
/// * The worst case complexity is that the printer tires each variant. This can result in quadratic
/// - The worst case complexity is that the printer tires each variant. This can result in quadratic
/// complexity if used in nested structures.
///
/// ## Behavior

View file

@ -435,15 +435,15 @@ impl<'a> Printer<'a> {
///
/// The implementation handles the following 5 cases:
///
/// * The *item*, *separator*, and the *next item* fit on the same line.
/// - The *item*, *separator*, and the *next item* fit on the same line.
/// Print the *item* and *separator* in flat mode.
/// * The *item* and *separator* fit on the line but there's not enough space for the *next item*.
/// - The *item* and *separator* fit on the line but there's not enough space for the *next item*.
/// Print the *item* in flat mode and the *separator* in expanded mode.
/// * The *item* fits on the line but the *separator* does not in flat mode.
/// - The *item* fits on the line but the *separator* does not in flat mode.
/// Print the *item* in flat mode and the *separator* in expanded mode.
/// * The *item* fits on the line but the *separator* does not in flat **NOR** expanded mode.
/// - The *item* fits on the line but the *separator* does not in flat **NOR** expanded mode.
/// Print the *item* and *separator* in expanded mode.
/// * The *item* does not fit on the line.
/// - The *item* does not fit on the line.
/// Print the *item* and *separator* in expanded mode.
fn print_fill_entries(
&mut self,
@ -777,8 +777,8 @@ impl Indention {
/// Increments the level by one.
///
/// The behaviour depends on the [`indent_style`][IndentStyle] if this is an [Indent::Align]:
/// * **Tabs**: `align` is converted into an indent. This results in `level` increasing by two: once for the align, once for the level increment
/// * **Spaces**: Increments the `level` by one and keeps the `align` unchanged.
/// - **Tabs**: `align` is converted into an indent. This results in `level` increasing by two: once for the align, once for the level increment
/// - **Spaces**: Increments the `level` by one and keeps the `align` unchanged.
/// Keeps any the current value is [Indent::Align] and increments the level by one.
fn increment_level(self, indent_style: IndentStyle) -> Self {
match self {
@ -796,8 +796,8 @@ impl Indention {
}
/// Decrements the indent by one by:
/// * Reducing the level by one if this is [Indent::Level]
/// * Removing the `align` if this is [Indent::Align]
/// - Reducing the level by one if this is [Indent::Level]
/// - Removing the `align` if this is [Indent::Align]
///
/// No-op if the level is already zero.
fn decrement(self) -> Self {

View file

@ -106,13 +106,13 @@ formats. Ruff will automatically disable any conflicting rules when `ALL` is ena
If you're wondering how to configure Ruff, here are some **recommended guidelines**:
* Prefer `select` and `ignore` over `extend-select` and `extend-ignore`, to make your rule set
- Prefer `select` and `ignore` over `extend-select` and `extend-ignore`, to make your rule set
explicit.
* Use `ALL` with discretion. Enabling `ALL` will implicitly enable new rules whenever you upgrade.
* Start with a small set of rules (`select = ["E", "F"]`) and add a category at-a-time. For example,
- Use `ALL` with discretion. Enabling `ALL` will implicitly enable new rules whenever you upgrade.
- Start with a small set of rules (`select = ["E", "F"]`) and add a category at-a-time. For example,
you might consider expanding to `select = ["E", "F", "B"]` to enable the popular flake8-bugbear
extension.
* By default, Ruff's autofix is aggressive. If you find that it's too aggressive for your liking,
- By default, Ruff's autofix is aggressive. If you find that it's too aggressive for your liking,
consider turning off autofix for specific rules or categories (see [_FAQ_](faq.md#ruff-tried-to-fix-something--but-it-broke-my-code)).
## Using `ruff.toml`
@ -277,15 +277,15 @@ There are a few exceptions to these rules:
1. In locating the "closest" `pyproject.toml` file for a given path, Ruff ignores any
`pyproject.toml` files that lack a `[tool.ruff]` section.
2. If a configuration file is passed directly via `--config`, those settings are used for across
1. If a configuration file is passed directly via `--config`, those settings are used for across
files. Any relative paths in that configuration file (like `exclude` globs or `src` paths) are
resolved relative to the _current working directory_.
3. If no `pyproject.toml` file is found in the filesystem hierarchy, Ruff will fall back to using
1. If no `pyproject.toml` file is found in the filesystem hierarchy, Ruff will fall back to using
a default configuration. If a user-specific configuration file exists
at `${config_dir}/ruff/pyproject.toml`, that file will be used instead of the default
configuration, with `${config_dir}` being determined via the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html)
crate, and all relative paths being again resolved relative to the _current working directory_.
4. Any `pyproject.toml`-supported settings that are provided on the command-line (e.g., via
1. Any `pyproject.toml`-supported settings that are provided on the command-line (e.g., via
`--select`) will override the settings in _every_ resolved configuration file.
Unlike [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy),
@ -428,17 +428,17 @@ for more.
By default, Ruff exits with the following status codes:
* `0` if no violations were found, or if all present violations were fixed automatically.
* `1` if violations were found.
* `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an internal error.
- `0` if no violations were found, or if all present violations were fixed automatically.
- `1` if violations were found.
- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an internal error.
This convention mirrors that of tools like ESLint, Prettier, and RuboCop.
Ruff supports two command-line flags that alter its exit code behavior:
* `--exit-zero` will cause Ruff to exit with a status code of `0` even if violations were found.
- `--exit-zero` will cause Ruff to exit with a status code of `0` even if violations were found.
Note that Ruff will still exit with a status code of `2` if it terminates abnormally.
* `--exit-non-zero-on-fix` will cause Ruff to exit with a status code of `1` if violations were
- `--exit-non-zero-on-fix` will cause Ruff to exit with a status code of `1` if violations were
found, _even if_ all such violations were fixed automatically. Note that the use of
`--exit-non-zero-on-fix` can result in a non-zero exit code even if no violations remain after
autofixing.

View file

@ -23,49 +23,49 @@ implements all of the `F` rules (which originate from Pyflakes), along with a su
Ruff also re-implements some of the most popular Flake8 plugins and related code quality tools
natively, including:
* [autoflake](https://pypi.org/project/autoflake/)
* [eradicate](https://pypi.org/project/eradicate/)
* [flake8-2020](https://pypi.org/project/flake8-2020/)
* [flake8-annotations](https://pypi.org/project/flake8-annotations/)
* [flake8-bandit](https://pypi.org/project/flake8-bandit/) ([#1646](https://github.com/charliermarsh/ruff/issues/1646))
* [flake8-blind-except](https://pypi.org/project/flake8-blind-except/)
* [flake8-boolean-trap](https://pypi.org/project/flake8-boolean-trap/)
* [flake8-bugbear](https://pypi.org/project/flake8-bugbear/)
* [flake8-builtins](https://pypi.org/project/flake8-builtins/)
* [flake8-commas](https://pypi.org/project/flake8-commas/)
* [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/)
* [flake8-datetimez](https://pypi.org/project/flake8-datetimez/)
* [flake8-debugger](https://pypi.org/project/flake8-debugger/)
* [flake8-django](https://pypi.org/project/flake8-django/) ([#2817](https://github.com/charliermarsh/ruff/issues/2817))
* [flake8-docstrings](https://pypi.org/project/flake8-docstrings/)
* [flake8-eradicate](https://pypi.org/project/flake8-eradicate/)
* [flake8-errmsg](https://pypi.org/project/flake8-errmsg/)
* [flake8-executable](https://pypi.org/project/flake8-executable/)
* [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
* [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
* [flake8-logging-format](https://pypi.org/project/flake8-logging-format/)
* [flake8-no-pep420](https://pypi.org/project/flake8-no-pep420)
* [flake8-pie](https://pypi.org/project/flake8-pie/)
* [flake8-print](https://pypi.org/project/flake8-print/)
* [flake8-pyi](https://pypi.org/project/flake8-pyi/)
* [flake8-pytest-style](https://pypi.org/project/flake8-pytest-style/)
* [flake8-quotes](https://pypi.org/project/flake8-quotes/)
* [flake8-raise](https://pypi.org/project/flake8-raise/)
* [flake8-return](https://pypi.org/project/flake8-return/)
* [flake8-self](https://pypi.org/project/flake8-self/)
* [flake8-simplify](https://pypi.org/project/flake8-simplify/)
* [flake8-super](https://pypi.org/project/flake8-super/)
* [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
* [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
* [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
* [isort](https://pypi.org/project/isort/)
* [mccabe](https://pypi.org/project/mccabe/)
* [pandas-vet](https://pypi.org/project/pandas-vet/)
* [pep8-naming](https://pypi.org/project/pep8-naming/)
* [pydocstyle](https://pypi.org/project/pydocstyle/)
* [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) ([#980](https://github.com/charliermarsh/ruff/issues/980))
* [pyupgrade](https://pypi.org/project/pyupgrade/)
* [yesqa](https://github.com/asottile/yesqa)
- [autoflake](https://pypi.org/project/autoflake/)
- [eradicate](https://pypi.org/project/eradicate/)
- [flake8-2020](https://pypi.org/project/flake8-2020/)
- [flake8-annotations](https://pypi.org/project/flake8-annotations/)
- [flake8-bandit](https://pypi.org/project/flake8-bandit/) ([#1646](https://github.com/charliermarsh/ruff/issues/1646))
- [flake8-blind-except](https://pypi.org/project/flake8-blind-except/)
- [flake8-boolean-trap](https://pypi.org/project/flake8-boolean-trap/)
- [flake8-bugbear](https://pypi.org/project/flake8-bugbear/)
- [flake8-builtins](https://pypi.org/project/flake8-builtins/)
- [flake8-commas](https://pypi.org/project/flake8-commas/)
- [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/)
- [flake8-datetimez](https://pypi.org/project/flake8-datetimez/)
- [flake8-debugger](https://pypi.org/project/flake8-debugger/)
- [flake8-django](https://pypi.org/project/flake8-django/) ([#2817](https://github.com/charliermarsh/ruff/issues/2817))
- [flake8-docstrings](https://pypi.org/project/flake8-docstrings/)
- [flake8-eradicate](https://pypi.org/project/flake8-eradicate/)
- [flake8-errmsg](https://pypi.org/project/flake8-errmsg/)
- [flake8-executable](https://pypi.org/project/flake8-executable/)
- [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
- [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
- [flake8-logging-format](https://pypi.org/project/flake8-logging-format/)
- [flake8-no-pep420](https://pypi.org/project/flake8-no-pep420)
- [flake8-pie](https://pypi.org/project/flake8-pie/)
- [flake8-print](https://pypi.org/project/flake8-print/)
- [flake8-pyi](https://pypi.org/project/flake8-pyi/)
- [flake8-pytest-style](https://pypi.org/project/flake8-pytest-style/)
- [flake8-quotes](https://pypi.org/project/flake8-quotes/)
- [flake8-raise](https://pypi.org/project/flake8-raise/)
- [flake8-return](https://pypi.org/project/flake8-return/)
- [flake8-self](https://pypi.org/project/flake8-self/)
- [flake8-simplify](https://pypi.org/project/flake8-simplify/)
- [flake8-super](https://pypi.org/project/flake8-super/)
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
- [isort](https://pypi.org/project/isort/)
- [mccabe](https://pypi.org/project/mccabe/)
- [pandas-vet](https://pypi.org/project/pandas-vet/)
- [pep8-naming](https://pypi.org/project/pep8-naming/)
- [pydocstyle](https://pypi.org/project/pydocstyle/)
- [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) ([#980](https://github.com/charliermarsh/ruff/issues/980))
- [pyupgrade](https://pypi.org/project/pyupgrade/)
- [yesqa](https://github.com/asottile/yesqa)
Note that, in some cases, Ruff uses different rule codes and prefixes than would be found in the
originating Flake8 plugins. For example, Ruff uses `TID252` to represent the `I252` rule from
@ -76,13 +76,13 @@ conflicts with the isort rules, like `I001`).
Beyond the rule set, Ruff suffers from the following limitations vis-à-vis Flake8:
1. Ruff does not yet support structural pattern matching.
2. Flake8 has a plugin architecture and supports writing custom lint rules. (Instead, popular Flake8
1. Flake8 has a plugin architecture and supports writing custom lint rules. (Instead, popular Flake8
plugins are re-implemented in Rust as part of Ruff itself.)
There are a few other minor incompatibilities between Ruff and the originating Flake8 plugins:
* Ruff doesn't implement all the "opinionated" lint rules from flake8-bugbear.
* Depending on your project structure, Ruff and isort can differ in their detection of first-party
- Ruff doesn't implement all the "opinionated" lint rules from flake8-bugbear.
- Depending on your project structure, Ruff and isort can differ in their detection of first-party
code. (This is often solved by modifying the `src` property, e.g., to `src = ["src"]`, if your
code is nested in a `src` directory.)
@ -124,42 +124,42 @@ feedback on type errors.
Today, Ruff can be used to replace Flake8 when used with any of the following plugins:
* [flake8-2020](https://pypi.org/project/flake8-2020/)
* [flake8-annotations](https://pypi.org/project/flake8-annotations/)
* [flake8-bandit](https://pypi.org/project/flake8-bandit/) ([#1646](https://github.com/charliermarsh/ruff/issues/1646))
* [flake8-blind-except](https://pypi.org/project/flake8-blind-except/)
* [flake8-boolean-trap](https://pypi.org/project/flake8-boolean-trap/)
* [flake8-bugbear](https://pypi.org/project/flake8-bugbear/)
* [flake8-builtins](https://pypi.org/project/flake8-builtins/)
* [flake8-commas](https://pypi.org/project/flake8-commas/)
* [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/)
* [flake8-datetimez](https://pypi.org/project/flake8-datetimez/)
* [flake8-debugger](https://pypi.org/project/flake8-debugger/)
* [flake8-django](https://pypi.org/project/flake8-django/) ([#2817](https://github.com/charliermarsh/ruff/issues/2817))
* [flake8-docstrings](https://pypi.org/project/flake8-docstrings/)
* [flake8-eradicate](https://pypi.org/project/flake8-eradicate/)
* [flake8-errmsg](https://pypi.org/project/flake8-errmsg/)
* [flake8-executable](https://pypi.org/project/flake8-executable/)
* [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
* [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
* [flake8-logging-format](https://pypi.org/project/flake8-logging-format/)
* [flake8-no-pep420](https://pypi.org/project/flake8-no-pep420)
* [flake8-pie](https://pypi.org/project/flake8-pie/)
* [flake8-print](https://pypi.org/project/flake8-print/)
* [flake8-pytest-style](https://pypi.org/project/flake8-pytest-style/)
* [flake8-quotes](https://pypi.org/project/flake8-quotes/)
* [flake8-raise](https://pypi.org/project/flake8-raise/)
* [flake8-return](https://pypi.org/project/flake8-return/)
* [flake8-self](https://pypi.org/project/flake8-self/)
* [flake8-simplify](https://pypi.org/project/flake8-simplify/)
* [flake8-super](https://pypi.org/project/flake8-super/)
* [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
* [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
* [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
* [mccabe](https://pypi.org/project/mccabe/)
* [pandas-vet](https://pypi.org/project/pandas-vet/)
* [pep8-naming](https://pypi.org/project/pep8-naming/)
* [pydocstyle](https://pypi.org/project/pydocstyle/)
- [flake8-2020](https://pypi.org/project/flake8-2020/)
- [flake8-annotations](https://pypi.org/project/flake8-annotations/)
- [flake8-bandit](https://pypi.org/project/flake8-bandit/) ([#1646](https://github.com/charliermarsh/ruff/issues/1646))
- [flake8-blind-except](https://pypi.org/project/flake8-blind-except/)
- [flake8-boolean-trap](https://pypi.org/project/flake8-boolean-trap/)
- [flake8-bugbear](https://pypi.org/project/flake8-bugbear/)
- [flake8-builtins](https://pypi.org/project/flake8-builtins/)
- [flake8-commas](https://pypi.org/project/flake8-commas/)
- [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/)
- [flake8-datetimez](https://pypi.org/project/flake8-datetimez/)
- [flake8-debugger](https://pypi.org/project/flake8-debugger/)
- [flake8-django](https://pypi.org/project/flake8-django/) ([#2817](https://github.com/charliermarsh/ruff/issues/2817))
- [flake8-docstrings](https://pypi.org/project/flake8-docstrings/)
- [flake8-eradicate](https://pypi.org/project/flake8-eradicate/)
- [flake8-errmsg](https://pypi.org/project/flake8-errmsg/)
- [flake8-executable](https://pypi.org/project/flake8-executable/)
- [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
- [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
- [flake8-logging-format](https://pypi.org/project/flake8-logging-format/)
- [flake8-no-pep420](https://pypi.org/project/flake8-no-pep420)
- [flake8-pie](https://pypi.org/project/flake8-pie/)
- [flake8-print](https://pypi.org/project/flake8-print/)
- [flake8-pytest-style](https://pypi.org/project/flake8-pytest-style/)
- [flake8-quotes](https://pypi.org/project/flake8-quotes/)
- [flake8-raise](https://pypi.org/project/flake8-raise/)
- [flake8-return](https://pypi.org/project/flake8-return/)
- [flake8-self](https://pypi.org/project/flake8-self/)
- [flake8-simplify](https://pypi.org/project/flake8-simplify/)
- [flake8-super](https://pypi.org/project/flake8-super/)
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
- [mccabe](https://pypi.org/project/mccabe/)
- [pandas-vet](https://pypi.org/project/pandas-vet/)
- [pep8-naming](https://pypi.org/project/pep8-naming/)
- [pydocstyle](https://pypi.org/project/pydocstyle/)
Ruff can also replace [isort](https://pypi.org/project/isort/),
[yesqa](https://github.com/asottile/yesqa), [eradicate](https://pypi.org/project/eradicate/), and

View file

@ -4,10 +4,10 @@ In-browser playground for Ruff. Available [https://play.ruff.rs/](https://play.r
## Getting started
* To build the WASM module, run `wasm-pack build ../crates/ruff --target web --out-dir ../../playground/src/pkg`
- To build the WASM module, run `wasm-pack build ../crates/ruff --target web --out-dir ../../playground/src/pkg`
from the `./playground` directory.
* Install TypeScript dependencies with: `npm install`.
* Start the development server with: `npm run dev`.
- Install TypeScript dependencies with: `npm install`.
- Start the development server with: `npm run dev`.
## Implementation

14
ruff.schema.json generated
View file

@ -40,7 +40,7 @@
]
},
"exclude": {
"description": "A list of file patterns to exclude from linting.\n\nExclusions are based on globs, and can be either:\n\n* Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). * Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).\n\nNote that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify the excluded paths.",
"description": "A list of file patterns to exclude from linting.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).\n\nNote that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify the excluded paths.",
"type": [
"array",
"null"
@ -57,7 +57,7 @@
]
},
"extend-exclude": {
"description": "A list of file patterns to omit from linting, in addition to those specified by `exclude`.\n\nExclusions are based on globs, and can be either:\n\n* Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). * Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).",
"description": "A list of file patterns to omit from linting, in addition to those specified by `exclude`.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).",
"type": [
"array",
"null"
@ -592,7 +592,7 @@
]
},
"suppress-none-returning": {
"description": "Whether to suppress `ANN200`-level violations for functions that meet either of the following criteria:\n\n* Contain no `return` statement. * Explicit `return` statement(s) all return `None` (explicitly or implicitly).",
"description": "Whether to suppress `ANN200`-level violations for functions that meet either of the following criteria:\n\n- Contain no `return` statement. - Explicit `return` statement(s) all return `None` (explicitly or implicitly).",
"type": [
"boolean",
"null"
@ -751,7 +751,7 @@
]
},
"parametrize-names-type": {
"description": "Expected type for multiple argument names in `@pytest.mark.parametrize`. The following values are supported:\n\n* `csv` — a comma-separated list, e.g. `@pytest.mark.parametrize('name1,name2', ...)` * `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'), ...)` * `list` — e.g. `@pytest.mark.parametrize(['name1', 'name2'], ...)`",
"description": "Expected type for multiple argument names in `@pytest.mark.parametrize`. The following values are supported:\n\n- `csv` — a comma-separated list, e.g. `@pytest.mark.parametrize('name1,name2', ...)` - `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'), ...)` - `list` — e.g. `@pytest.mark.parametrize(['name1', 'name2'], ...)`",
"anyOf": [
{
"$ref": "#/definitions/ParametrizeNameType"
@ -762,7 +762,7 @@
]
},
"parametrize-values-row-type": {
"description": "Expected type for each row of values in `@pytest.mark.parametrize` in case of multiple parameters. The following values are supported:\n\n* `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'), [(1, 2), (3, 4)])` * `list` — e.g. `@pytest.mark.parametrize(('name1', 'name2'), [[1, 2], [3, 4]])`",
"description": "Expected type for each row of values in `@pytest.mark.parametrize` in case of multiple parameters. The following values are supported:\n\n- `tuple` (default) — e.g. `@pytest.mark.parametrize(('name1', 'name2'), [(1, 2), (3, 4)])` - `list` — e.g. `@pytest.mark.parametrize(('name1', 'name2'), [[1, 2], [3, 4]])`",
"anyOf": [
{
"$ref": "#/definitions/ParametrizeValuesRowType"
@ -773,7 +773,7 @@
]
},
"parametrize-values-type": {
"description": "Expected type for the list of values rows in `@pytest.mark.parametrize`. The following values are supported:\n\n* `tuple` — e.g. `@pytest.mark.parametrize('name', (1, 2, 3))` * `list` (default) — e.g. `@pytest.mark.parametrize('name', [1, 2, 3])`",
"description": "Expected type for the list of values rows in `@pytest.mark.parametrize`. The following values are supported:\n\n- `tuple` — e.g. `@pytest.mark.parametrize('name', (1, 2, 3))` - `list` (default) — e.g. `@pytest.mark.parametrize('name', [1, 2, 3])`",
"anyOf": [
{
"$ref": "#/definitions/ParametrizeValuesType"
@ -1227,7 +1227,7 @@
"type": "object",
"properties": {
"ignore-overlong-task-comments": {
"description": "Whether line-length violations (`E501`) should be triggered for comments starting with `task-tags` (by default: [\"TODO\", \"FIXME\", and \"XXX\"]).",
"description": "Whether line-length violations (`E501`) should be triggered for comments starting with `task-tags` (by default: \\[\"TODO\", \"FIXME\", and \"XXX\"\\]).",
"type": [
"boolean",
"null"

View file

@ -6,8 +6,7 @@ Utilities for benchmarking Ruff.
Run `./scripts/benchmarks/run.sh` to clone the benchmarking target (CPython).
If you're looking to benchmark Ruff against other tools, you'll also need to run `poetry
install` to create a virtual environment with the required dependencies.
If you're looking to benchmark Ruff against other tools, you'll also need to run `poetry install` to create a virtual environment with the required dependencies.
## Running Benchmarks