Generate JSON schema for Ruff options (#1329)

This commit is contained in:
Edgar R. M 2022-12-24 13:10:22 -06:00 committed by GitHub
parent 0dc523b081
commit 4888afd423
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1825 additions and 406 deletions

View file

@ -42,6 +42,9 @@ jobs:
- run: ./target/release/ruff_dev generate-check-code-prefix
- run: git diff --quiet src/checks_gen.rs || echo "::error file=src/checks_gen.rs::This file is outdated. You may have to rerun 'cargo dev generate-check-code-prefix'."
- run: git diff --exit-code -- README.md src/checks_gen.rs
- run: ./target/release/ruff_dev generate-json-schema
- run: git diff --quiet ruff.schema.json || echo "::error file=ruff.schema.json::This file is outdated. You may have to rerun 'cargo dev generate-json-schema'."
- run: git diff --exit-code -- ruff.schema.json
cargo_fmt:
name: "cargo fmt"

View file

@ -105,7 +105,8 @@ You may also want to add the new configuration option to the `flake8-to-ruff` to
responsible for converting `flake8` configuration files to Ruff's TOML format. This logic
lives in `flake8_to_ruff/src/converter.rs`.
To update the documentation for supported configuration options, run `cargo dev generate-options`.
Run `cargo dev generate-options` to update the documentation for supported configuration options,
and `cargo dev generate-json-schema` to update the JSON schema for `tool.ruff` in `pyproject.toml`.
## Release process

50
Cargo.lock generated
View file

@ -644,6 +644,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dyn-clone"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60"
[[package]]
name = "either"
version = "1.8.0"
@ -1888,6 +1894,7 @@ dependencies = [
"rustpython-ast",
"rustpython-common",
"rustpython-parser",
"schemars",
"serde",
"serde_json",
"shellexpand",
@ -1916,6 +1923,8 @@ dependencies = [
"rustpython-ast",
"rustpython-common",
"rustpython-parser",
"schemars",
"serde_json",
"strum",
"strum_macros",
]
@ -2058,6 +2067,30 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schemars"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307"
dependencies = [
"dyn-clone",
"schemars_derive",
"serde",
"serde_json",
]
[[package]]
name = "schemars_derive"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -2107,10 +2140,21 @@ dependencies = [
]
[[package]]
name = "serde_json"
version = "1.0.89"
name = "serde_derive_internals"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa",
"ryu",

View file

@ -48,6 +48,7 @@ rustc-hash = { version = "1.1.0" }
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
schemars = { version = "0.8.11" }
serde = { version = "1.0.147", features = ["derive"] }
serde_json = { version = "1.0.87" }
shellexpand = { version = "3.0.0" }

242
README.md
View file

@ -1581,8 +1581,8 @@ Summary
#### [`allowed-confusables`](#allowed-confusables)
A list of allowed "confusable" Unicode characters to ignore when enforcing `RUF001`,
`RUF002`, and `RUF003`.
A list of allowed "confusable" Unicode characters to ignore when
enforcing `RUF001`, `RUF002`, and `RUF003`.
**Default value**: `[]`
@ -1603,13 +1603,14 @@ allowed-confusables = ["", "ρ", ""]
A path to the cache directory.
By default, Ruff stores cache results in a `.ruff_cache` directory in the current
project root.
By default, Ruff stores cache results in a `.ruff_cache` directory in
the current project root.
However, Ruff will also respect the `RUFF_CACHE_DIR` environment variable, which takes
precedence over that default.
However, Ruff will also respect the `RUFF_CACHE_DIR` environment
variable, which takes precedence over that default.
This setting will override even the `RUFF_CACHE_DIR` environment variable, if set.
This setting will override even the `RUFF_CACHE_DIR` environment
variable, if set.
**Default value**: `.ruff_cache`
@ -1626,9 +1627,9 @@ cache-dir = "~/.cache/ruff"
#### [`dummy-variable-rgx`](#dummy-variable-rgx)
A regular expression used to identify "dummy" variables, or those which should be
ignored when evaluating (e.g.) unused-variable checks. The default expression matches
`_`, `__`, and `_var`, but not `_var_`.
A regular expression used to identify "dummy" variables, or those which
should be ignored when evaluating (e.g.) unused-variable checks. The
default expression matches `_`, `__`, and `_var`, but not `_var_`.
**Default value**: `"^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"`
@ -1650,15 +1651,16 @@ A list of file patterns to exclude from linting.
Exclusions are based on globs, and can be either:
- 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`).
- 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`).
Note that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify
the excluded paths.
Note that you'll typically want to use
[`extend-exclude`](#extend-exclude) to modify the excluded paths.
**Default value**: `[".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv"]`
@ -1675,12 +1677,13 @@ exclude = [".venv"]
#### [`extend`](#extend)
A path to a local `pyproject.toml` file to merge into this configuration. User home
directory and environment variables will be expanded.
A path to a local `pyproject.toml` file to merge into this
configuration. User home directory and environment variables will be
expanded.
To resolve the current `pyproject.toml` file, Ruff will first resolve this base
configuration file, then merge in any properties defined in the current configuration
file.
To resolve the current `pyproject.toml` file, Ruff will first resolve
this base configuration file, then merge in any properties defined
in the current configuration file.
**Default value**: `None`
@ -1700,7 +1703,8 @@ line-length = 100
#### [`extend-exclude`](#extend-exclude)
A list of file patterns to omit from linting, in addition to those specified by `exclude`.
A list of file patterns to omit from linting, in addition to those
specified by `exclude`.
**Default value**: `[]`
@ -1718,7 +1722,8 @@ extend-exclude = ["tests", "src/bad.py"]
#### [`extend-ignore`](#extend-ignore)
A list of check code prefixes to ignore, in addition to those specified by `ignore`.
A list of check code prefixes to ignore, in addition to those specified
by `ignore`.
**Default value**: `[]`
@ -1736,7 +1741,8 @@ extend-ignore = ["F841"]
#### [`extend-select`](#extend-select)
A list of check code prefixes to enable, in addition to those specified by `select`.
A list of check code prefixes to enable, in addition to those specified
by `select`.
**Default value**: `[]`
@ -1754,9 +1760,10 @@ extend-select = ["B", "Q"]
#### [`external`](#external)
A list of check codes that are unsupported by Ruff, but should be preserved when (e.g.)
validating `# noqa` directives. Useful for retaining `# noqa` directives that cover plugins not
yet implemented in Ruff.
A list of check codes that are unsupported by Ruff, but should be
preserved when (e.g.) validating `# noqa` directives. Useful for
retaining `# noqa` directives that cover plugins not yet implemented
in Ruff.
**Default value**: `[]`
@ -1811,14 +1818,16 @@ fixable = ["E", "F"]
#### [`force-exclude`](#force-exclude)
Whether to enforce `exclude` and `extend-exclude` patterns, even for paths that are
passed to Ruff explicitly. Typically, Ruff will lint any paths passed in directly, even
if they would typically be excluded. Setting `force-exclude = true` will cause Ruff to
Whether to enforce `exclude` and `extend-exclude` patterns, even for
paths that are passed to Ruff explicitly. Typically, Ruff will lint
any paths passed in directly, even if they would typically be
excluded. Setting `force-exclude = true` will cause Ruff to
respect these exclusions unequivocally.
This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all
changed files to the [`ruff-pre-commit`](https://github.com/charliermarsh/ruff-pre-commit)
plugin, regardless of whether they're marked as excluded by Ruff's own settings.
plugin, regardless of whether they're marked as excluded by Ruff's own
settings.
**Default value**: `false`
@ -1835,9 +1844,10 @@ force-exclude = true
#### [`format`](#format)
The style in which violation messages should be formatted: `"text"` (default),
`"grouped"` (group messages by file), `"json"` (machine-readable), `"junit"`
(machine-readable XML), or `"github"` (GitHub Actions annotations).
The style in which violation messages should be formatted: `"text"`
(default), `"grouped"` (group messages by file), `"json"`
(machine-readable), `"junit"` (machine-readable XML), or `"github"`
(GitHub Actions annotations).
**Default value**: `"text"`
@ -1855,11 +1865,13 @@ format = "grouped"
#### [`ignore`](#ignore)
A list of check code prefixes to ignore. Prefixes can specify exact checks (like
`F841`), entire categories (like `F`), or anything in between.
A list of check code prefixes to ignore. Prefixes can specify exact
checks (like `F841`), entire categories (like `F`), or anything in
between.
When breaking ties between enabled and disabled checks (via `select` and `ignore`,
respectively), more specific prefixes override less specific prefixes.
When breaking ties between enabled and disabled checks (via `select` and
`ignore`, respectively), more specific prefixes override less
specific prefixes.
**Default value**: `[]`
@ -1877,10 +1889,11 @@ ignore = ["F841"]
#### [`ignore-init-module-imports`](#ignore-init-module-imports)
Avoid automatically removing unused imports in `__init__.py` files. Such imports will
still be +flagged, but with a dedicated message suggesting that the import is either
added to the module' +`__all__` symbol, or re-exported with a redundant alias (e.g.,
`import os as os`).
Avoid automatically removing unused imports in `__init__.py` files. Such
imports will still be +flagged, but with a dedicated message
suggesting that the import is either added to the module' +`__all__`
symbol, or re-exported with a redundant alias (e.g., `import os as
os`).
**Default value**: `false`
@ -1897,7 +1910,8 @@ ignore-init-module-imports = true
#### [`line-length`](#line-length)
The line length to use when enforcing long-lines violations (like E501).
The line length to use when enforcing long-lines violations (like
`E501`).
**Default value**: `88`
@ -1915,8 +1929,8 @@ line-length = 120
#### [`per-file-ignores`](#per-file-ignores)
A list of mappings from file pattern to check code prefixes to exclude, when considering
any matching files.
A list of mappings from file pattern to check code prefixes to exclude,
when considering any matching files.
**Default value**: `{}`
@ -1936,8 +1950,9 @@ any matching files.
#### [`respect-gitignore`](#respect-gitignore)
Whether to automatically exclude files that are ignored by `.ignore`, `.gitignore`,
`.git/info/exclude`, and global `gitignore` files. Enabled by default.
Whether to automatically exclude files that are ignored by `.ignore`,
`.gitignore`, `.git/info/exclude`, and global `gitignore` files.
Enabled by default.
**Default value**: `true`
@ -1954,11 +1969,13 @@ respect_gitignore = false
#### [`select`](#select)
A list of check code prefixes to enable. Prefixes can specify exact checks (like
`F841`), entire categories (like `F`), or anything in between.
A list of check code prefixes to enable. Prefixes can specify exact
checks (like `F841`), entire categories (like `F`), or anything in
between.
When breaking ties between enabled and disabled checks (via `select` and `ignore`,
respectively), more specific prefixes override less specific prefixes.
When breaking ties between enabled and disabled checks (via `select` and
`ignore`, respectively), more specific prefixes override less
specific prefixes.
**Default value**: `["E", "F"]`
@ -1976,8 +1993,8 @@ select = ["E", "F", "B", "Q"]
#### [`show-source`](#show-source)
Whether to show source code snippets when reporting lint error violations (overridden by
the `--show-source` command-line flag).
Whether to show source code snippets when reporting lint error
violations (overridden by the `--show-source` command-line flag).
**Default value**: `false`
@ -1995,7 +2012,8 @@ show-source = true
#### [`src`](#src)
The source code paths to consider, e.g., when resolving first- vs. third-party imports.
The source code paths to consider, e.g., when resolving first- vs.
third-party imports.
As an example: given a Python package structure like:
@ -2009,13 +2027,15 @@ my_package/
bar.py
```
The `src` directory should be included in `source` (e.g., `source = ["src"]`), such that
when resolving imports, `my_package.foo` is considered a first-party import.
The `src` directory should be included in `source` (e.g., `source =
["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 that directory. User home directory and environment variables
will also be expanded.
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 that directory. User home directory and environment
variables will also be expanded.
**Default value**: `["."]`
@ -2033,9 +2053,10 @@ src = ["src", "test"]
#### [`target-version`](#target-version)
The Python version to target, e.g., when considering automatic code upgrades, like
rewriting type annotations. Note that the target version will _not_ be inferred from the
_current_ Python version, and instead must be specified explicitly (as seen below).
The Python version to target, e.g., when considering automatic code
upgrades, like rewriting type annotations. Note that the target
version will _not_ be inferred from the _current_ Python version,
and instead must be specified explicitly (as seen below).
**Default value**: `"py310"`
@ -2073,7 +2094,8 @@ unfixable = ["F401"]
#### [`allow-star-arg-any`](#allow-star-arg-any)
Whether to suppress `ANN401` for dynamically typed `*args` and `**kwargs` arguments.
Whether to suppress `ANN401` for dynamically typed `*args` and
`**kwargs` arguments.
**Default value**: `false`
@ -2090,8 +2112,8 @@ allow-star-arg-any = true
#### [`mypy-init-return`](#mypy-init-return)
Whether to allow the omission of a return type hint for `__init__` if at least one
argument is annotated.
Whether to allow the omission of a return type hint for `__init__` if at
least one argument is annotated.
**Default value**: `false`
@ -2108,8 +2130,8 @@ mypy-init-return = true
#### [`suppress-dummy-args`](#suppress-dummy-args)
Whether to suppress `ANN000`-level errors for arguments matching the "dummy" variable
regex (like `_`).
Whether to suppress `ANN000`-level errors for arguments matching the
"dummy" variable regex (like `_`).
**Default value**: `false`
@ -2126,11 +2148,12 @@ suppress-dummy-args = true
#### [`suppress-none-returning`](#suppress-none-returning)
Whether to suppress `ANN200`-level errors for functions that meet either of the
following criteria:
Whether to suppress `ANN200`-level errors for functions that meet either
of the following criteria:
- Contain no `return` statement.
- Explicit `return` statement(s) all return `None` (explicitly or implicitly).
- Explicit `return` statement(s) all return `None` (explicitly or
implicitly).
**Default value**: `false`
@ -2149,8 +2172,8 @@ suppress-none-returning = true
#### [`extend-immutable-calls`](#extend-immutable-calls)
Additional callable functions to consider "immutable" when evaluating, e.g.,
`no-mutable-default-argument` checks (`B006`).
Additional callable functions to consider "immutable" when evaluating,
e.g., `no-mutable-default-argument` checks (`B006`).
**Default value**: `[]`
@ -2189,7 +2212,8 @@ max-string-length = 20
#### [`aliases`](#aliases)
The conventional aliases for imports. These aliases can be extended by the `extend_aliases` option.
The conventional aliases for imports. These aliases can be extended by
the `extend_aliases` option.
**Default value**: `{"altair": "alt", "matplotlib.pyplot": "plt", "numpy": "np", "pandas": "pd", "seaborn": "sns"}`
@ -2211,7 +2235,8 @@ seaborn = "sns"
#### [`extend-aliases`](#extend-aliases)
A mapping of modules to their conventional import aliases. These aliases will be added to the `aliases` mapping.
A mapping of modules to their conventional import aliases. These aliases
will be added to the `aliases` mapping.
**Default value**: `{}`
@ -2231,8 +2256,8 @@ A mapping of modules to their conventional import aliases. These aliases will be
#### [`avoid-escape`](#avoid-escape)
Whether to avoid using single quotes if a string contains single quotes, or vice-versa
with double quotes, as per [PEP8](https://peps.python.org/pep-0008/#string-quotes).
Whether to avoid using single quotes if a string contains single quotes,
or vice-versa with double quotes, as per [PEP8](https://peps.python.org/pep-0008/#string-quotes).
This minimizes the need to escape quotation marks within strings.
**Default value**: `true`
@ -2251,7 +2276,8 @@ avoid-escape = false
#### [`docstring-quotes`](#docstring-quotes)
Quote style to prefer for docstrings (either "single" (`'`) or "double" (`"`)).
Quote style to prefer for docstrings (either "single" (`'`) or "double"
(`"`)).
**Default value**: `"double"`
@ -2268,7 +2294,8 @@ docstring-quotes = "single"
#### [`inline-quotes`](#inline-quotes)
Quote style to prefer for inline strings (either "single" (`'`) or "double" (`"`)).
Quote style to prefer for inline strings (either "single" (`'`) or
"double" (`"`)).
**Default value**: `"double"`
@ -2285,7 +2312,8 @@ inline-quotes = "single"
#### [`multiline-quotes`](#multiline-quotes)
Quote style to prefer for multiline strings (either "single" (`'`) or "double" (`"`)).
Quote style to prefer for multiline strings (either "single" (`'`) or
"double" (`"`)).
**Default value**: `"double"`
@ -2304,8 +2332,8 @@ multiline-quotes = "single"
#### [`ban-relative-imports`](#ban-relative-imports)
Whether to ban all relative imports (`"all"`), or only those imports that extend into
the parent module and beyond (`"parents"`).
Whether to ban all relative imports (`"all"`), or only those imports
that extend into the parent module and beyond (`"parents"`).
**Default value**: `"parents"`
@ -2362,8 +2390,8 @@ combine-as-imports = true
#### [`extra-standard-library`](#extra-standard-library)
A list of modules to consider standard-library, in addition to those known to Ruff in
advance.
A list of modules to consider standard-library, in addition to those
known to Ruff in advance.
**Default value**: `[]`
@ -2380,9 +2408,10 @@ extra-standard-library = ["path"]
#### [`force-wrap-aliases`](#force-wrap-aliases)
Force `import from` statements with multiple members and at least one alias (e.g.,
`import A as B`) to wrap such that every line contains exactly one member. For example,
this formatting would be retained, rather than condensing to a single line:
Force `import from` statements with multiple members and at least one
alias (e.g., `import A as B`) to wrap such that every line contains
exactly one member. For example, this formatting would be retained,
rather than condensing to a single line:
```py
from .utils import (
@ -2391,9 +2420,10 @@ from .utils import (
)
```
Note that this setting is only effective when combined with `combine-as-imports = true`.
When `combine-as-imports` isn't enabled, every aliased `import from` will be given its
own line, in which case, wrapping is not necessary.
Note that this setting is only effective when combined with
`combine-as-imports = true`. When `combine-as-imports` isn't
enabled, every aliased `import from` will be given its own line, in
which case, wrapping is not necessary.
**Default value**: `false`
@ -2411,8 +2441,8 @@ combine-as-imports = true
#### [`known-first-party`](#known-first-party)
A list of modules to consider first-party, regardless of whether they can be identified
as such via introspection of the local filesystem.
A list of modules to consider first-party, regardless of whether they
can be identified as such via introspection of the local filesystem.
**Default value**: `[]`
@ -2429,8 +2459,8 @@ known-first-party = ["src"]
#### [`known-third-party`](#known-third-party)
A list of modules to consider third-party, regardless of whether they can be identified
as such via introspection of the local filesystem.
A list of modules to consider third-party, regardless of whether they
can be identified as such via introspection of the local filesystem.
**Default value**: `[]`
@ -2469,9 +2499,10 @@ max-complexity = 5
#### [`classmethod-decorators`](#classmethod-decorators)
A list of decorators that, when applied to a method, indicate that the method should be
treated as a class method. For example, Ruff will expect that any method decorated by a
decorator in this list takes a `cls` argument as its first argument.
A list of decorators that, when applied to a method, indicate that the
method should be treated as a class method. For example, Ruff will
expect that any method decorated by a decorator in this list takes a
`cls` argument as its first argument.
**Default value**: `["classmethod"]`
@ -2506,9 +2537,10 @@ ignore-names = ["callMethod"]
#### [`staticmethod-decorators`](#staticmethod-decorators)
A list of decorators that, when applied to a method, indicate that the method should be
treated as a static method. For example, Ruff will expect that any method decorated by a
decorator in this list has no `self` or `cls` argument.
A list of decorators that, when applied to a method, indicate that the
method should be treated as a static method. For example, Ruff will
expect that any method decorated by a decorator in this list has no
`self` or `cls` argument.
**Default value**: `["staticmethod"]`
@ -2528,7 +2560,11 @@ staticmethod-decorators = ["staticmethod", "stcmthd"]
#### [`keep-runtime-typing`](#keep-runtime-typing)
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 applicable when the target Python version is below 3.9 and 3.10 respectively.
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
applicable when the target Python version is below 3.9 and 3.10
respectively.
**Default value**: `false`

View file

@ -67,10 +67,7 @@ pub fn convert(
}
let from_codes = plugin::infer_plugins_from_codes(&referenced_codes);
if !from_codes.is_empty() {
eprintln!(
"Inferred plugins from referenced check codes: {:#?}",
from_codes
);
eprintln!("Inferred plugins from referenced check codes: {from_codes:#?}");
}
from_options.into_iter().chain(from_codes).collect()
}),

1194
ruff.schema.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -14,5 +14,7 @@ ruff = { path = ".." }
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "1b6cb170e925a43d605b3fed9f6b878e63e47744" }
schemars = { version = "0.8.11" }
serde_json = {version="1.0.91"}
strum = { version = "0.24.1", features = ["strum_macros"] }
strum_macros = { version = "0.24.3" }

View file

@ -65,7 +65,8 @@ pub fn main(cli: &Cli) -> Result<()> {
.derive("Ord")
.derive("Clone")
.derive("Serialize")
.derive("Deserialize");
.derive("Deserialize")
.derive("JsonSchema");
for prefix in prefix_to_codes.keys() {
gen = gen.push_variant(Variant::new(prefix.to_string()));
}
@ -138,8 +139,7 @@ pub fn main(cli: &Cli) -> Result<()> {
_ => panic!("Invalid prefix: {prefix}"),
};
gen = gen.line(format!(
"CheckCodePrefix::{prefix} => SuffixLength::{},",
specificity
"CheckCodePrefix::{prefix} => SuffixLength::{specificity},"
));
}
gen.line("}");
@ -152,6 +152,8 @@ pub fn main(cli: &Cli) -> Result<()> {
output.push('\n');
output.push_str("use colored::Colorize;");
output.push('\n');
output.push_str("use schemars::JsonSchema;");
output.push('\n');
output.push_str("use serde::{Deserialize, Serialize};");
output.push('\n');
output.push_str("use strum_macros::{AsRefStr, EnumString};");

View file

@ -0,0 +1,30 @@
use std::fs;
use std::path::PathBuf;
use anyhow::Result;
use clap::Args;
use ruff::settings::options::Options;
use schemars::schema_for;
#[derive(Args)]
pub struct Cli {
/// Write the generated table to stdout (rather than to `ruff.schema.json`).
#[arg(long)]
dry_run: bool,
}
pub fn main(cli: &Cli) -> Result<()> {
let schema = schema_for!(Options);
let schema_string = serde_json::to_string_pretty(&schema).unwrap();
if cli.dry_run {
println!("{schema_string}");
} else {
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("Failed to find root directory")
.join("ruff.schema.json");
fs::write(file, schema_string.as_bytes())?;
}
Ok(())
}

View file

@ -12,6 +12,7 @@
)]
pub mod generate_check_code_prefix;
pub mod generate_json_schema;
pub mod generate_options;
pub mod generate_rules_table;
pub mod generate_source_code;

View file

@ -14,8 +14,8 @@
use anyhow::Result;
use clap::{Parser, Subcommand};
use ruff_dev::{
generate_check_code_prefix, generate_options, generate_rules_table, generate_source_code,
print_ast, print_cst, print_tokens,
generate_check_code_prefix, generate_json_schema, generate_options, generate_rules_table,
generate_source_code, print_ast, print_cst, print_tokens,
};
#[derive(Parser)]
@ -30,6 +30,8 @@ struct Cli {
enum Commands {
/// Generate the `CheckCodePrefix` enum.
GenerateCheckCodePrefix(generate_check_code_prefix::Cli),
/// Generate JSON schema for the TOML configuration file.
GenerateJSONSchema(generate_json_schema::Cli),
/// Generate a Markdown-compatible table of supported lint rules.
GenerateRulesTable(generate_rules_table::Cli),
/// Generate a Markdown-compatible listing of configuration options.
@ -48,6 +50,7 @@ fn main() -> Result<()> {
let cli = Cli::parse();
match &cli.command {
Commands::GenerateCheckCodePrefix(args) => generate_check_code_prefix::main(args)?,
Commands::GenerateJSONSchema(args) => generate_json_schema::main(args)?,
Commands::GenerateRulesTable(args) => generate_rules_table::main(args)?,
Commands::GenerateSourceCode(args) => generate_source_code::main(args)?,
Commands::GenerateOptions(args) => generate_options::main(args)?,

View file

@ -13,13 +13,14 @@
use quote::{quote, quote_spanned};
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::token::Comma;
use syn::{
parse_macro_input, AngleBracketedGenericArguments, Attribute, Data, DataStruct, DeriveInput,
Field, Fields, Lit, LitStr, Path, PathArguments, PathSegment, Token, Type, TypePath,
};
#[proc_macro_derive(ConfigurationOptions, attributes(option, option_group))]
#[proc_macro_derive(ConfigurationOptions, attributes(option, doc, option_group))]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
@ -39,11 +40,28 @@ fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let mut output = vec![];
for field in fields.named.iter() {
if let Some(attr) = field.attrs.iter().find(|a| a.path.is_ident("option")) {
output.push(handle_option(field, attr)?);
let docs: Vec<&Attribute> = field
.attrs
.iter()
.filter(|attr| attr.path.is_ident("doc"))
.collect();
if docs.is_empty() {
return Err(syn::Error::new(
field.span(),
"Missing documentation for field",
));
}
if let Some(attr) = field.attrs.iter().find(|attr| attr.path.is_ident("option")) {
output.push(handle_option(field, attr, docs)?);
};
if field.attrs.iter().any(|a| a.path.is_ident("option_group")) {
if field
.attrs
.iter()
.any(|attr| attr.path.is_ident("option_group"))
{
output.push(handle_option_group(field)?);
};
}
@ -70,8 +88,10 @@ fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
/// deriving `ConfigurationOptions`, create code that calls retrieves options
/// from that group: `Foobar::get_available_options()`
fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
// unwrap is safe because we're only going over named fields
let ident = field.ident.as_ref().unwrap();
let ident = field
.ident
.as_ref()
.expect("Expected to handle named fields");
match &field.ty {
Type::Path(TypePath {
@ -103,17 +123,49 @@ fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
}
}
/// Parse a `doc` attribute into it a string literal.
fn parse_doc(doc: &Attribute) -> syn::Result<String> {
let doc = doc
.parse_meta()
.map_err(|e| syn::Error::new(doc.span(), e))?;
match doc {
syn::Meta::NameValue(syn::MetaNameValue {
lit: Lit::Str(lit_str),
..
}) => Ok(lit_str.value()),
_ => Err(syn::Error::new(doc.span(), "Expected doc attribute.")),
}
}
/// Parse an `#[option(doc="...", default="...", value_type="...",
/// example="...")]` attribute and return data in the form of an `OptionField`.
fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::TokenStream> {
// unwrap is safe because we're only going over named fields
let ident = field.ident.as_ref().unwrap();
fn handle_option(
field: &Field,
attr: &Attribute,
docs: Vec<&Attribute>,
) -> syn::Result<proc_macro2::TokenStream> {
// Convert the list of `doc` attributes into a single string.
let doc = textwrap::dedent(
&docs
.into_iter()
.map(parse_doc)
.collect::<syn::Result<Vec<_>>>()?
.join("\n"),
)
.trim_matches('\n')
.to_string();
let ident = field
.ident
.as_ref()
.expect("Expected to handle named fields");
let FieldAttributes {
doc,
default,
value_type,
example,
..
} = attr.parse_args::<FieldAttributes>()?;
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
@ -130,7 +182,6 @@ fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::To
#[derive(Debug)]
struct FieldAttributes {
doc: String,
default: String,
value_type: String,
example: String,
@ -138,8 +189,6 @@ struct FieldAttributes {
impl Parse for FieldAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let doc = _parse_key_value(input, "doc")?;
input.parse::<Comma>()?;
let default = _parse_key_value(input, "default")?;
input.parse::<Comma>()?;
let value_type = _parse_key_value(input, "value_type")?;
@ -150,7 +199,6 @@ impl Parse for FieldAttributes {
}
Ok(FieldAttributes {
doc: textwrap::dedent(&doc).trim_matches('\n').to_string(),
default,
value_type,
example: textwrap::dedent(&example).trim_matches('\n').to_string(),

View file

@ -1,6 +1,7 @@
//! File automatically generated by `examples/generate_check_code_prefix.rs`.
use colored::Colorize;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumString};
@ -8,7 +9,17 @@ use crate::checks::CheckCode;
use crate::one_time_warning;
#[derive(
EnumString, AsRefStr, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize,
EnumString,
AsRefStr,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Serialize,
Deserialize,
JsonSchema,
)]
pub enum CheckCodePrefix {
A,

View file

@ -1,51 +1,53 @@
//! Settings for the `flake-annotations` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8AnnotationsOptions"
)]
pub struct Options {
#[option(
doc = r#"
Whether to allow the omission of a return type hint for `__init__` if at least one
argument is annotated.
"#,
default = "false",
value_type = "bool",
example = "mypy-init-return = true"
)]
/// Whether to allow the omission of a return type hint for `__init__` if at
/// least one argument is annotated.
pub mypy_init_return: Option<bool>,
#[option(
doc = r#"
Whether to suppress `ANN000`-level errors for arguments matching the "dummy" variable
regex (like `_`).
"#,
default = "false",
value_type = "bool",
example = "suppress-dummy-args = true"
)]
/// Whether to suppress `ANN000`-level errors for arguments matching the
/// "dummy" variable regex (like `_`).
pub suppress_dummy_args: Option<bool>,
#[option(
doc = r#"
Whether to suppress `ANN200`-level errors for functions that meet either of the
following criteria:
- Contain no `return` statement.
- Explicit `return` statement(s) all return `None` (explicitly or implicitly).
"#,
default = "false",
value_type = "bool",
example = "suppress-none-returning = true"
)]
/// Whether to suppress `ANN200`-level errors for functions that meet either
/// of the following criteria:
///
/// - Contain no `return` statement.
/// - Explicit `return` statement(s) all return `None` (explicitly or
/// implicitly).
pub suppress_none_returning: Option<bool>,
#[option(
doc = "Whether to suppress `ANN401` for dynamically typed `*args` and `**kwargs` \
arguments.",
default = "false",
value_type = "bool",
example = "allow-star-arg-any = true"
)]
/// Whether to suppress `ANN401` for dynamically typed `*args` and
/// `**kwargs` arguments.
pub allow_star_arg_any: Option<bool>,
}

View file

@ -1,16 +1,19 @@
//! Settings for the `flake8-bugbear` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8BugbearOptions"
)]
pub struct Options {
#[option(
doc = r#"
Additional callable functions to consider "immutable" when evaluating, e.g.,
`no-mutable-default-argument` checks (`B006`).
"#,
default = r#"[]"#,
value_type = "Vec<String>",
example = r#"
@ -18,6 +21,8 @@ pub struct Options {
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]
"#
)]
/// Additional callable functions to consider "immutable" when evaluating,
/// e.g., `no-mutable-default-argument` checks (`B006`).
pub extend_immutable_calls: Option<Vec<String>>,
}

View file

@ -1,19 +1,24 @@
//! Settings for the `flake8-errmsg` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8ErrMsgOptions"
)]
pub struct Options {
#[option(
doc = r#"
Maximum string length for string literals in exception messages.
"#,
default = "0",
value_type = "usize",
example = "max-string-length = 20"
)]
/// Maximum string length for string literals in exception messages.
pub max_string_length: Option<usize>,
}

View file

@ -5,6 +5,7 @@ use std::hash::{Hash, Hasher};
use itertools::Itertools;
use ruff_macros::ConfigurationOptions;
use rustc_hash::FxHashMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
@ -15,12 +16,16 @@ const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
("seaborn", "sns"),
];
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8ImportConventionsOptions"
)]
pub struct Options {
#[option(
doc = "The conventional aliases for imports. These aliases can be extended by the \
`extend_aliases` option.",
default = r#"{"altair": "alt", "matplotlib.pyplot": "plt", "numpy": "np", "pandas": "pd", "seaborn": "sns"}"#,
value_type = "FxHashMap<String, String>",
example = r#"
@ -32,10 +37,10 @@ pub struct Options {
seaborn = "sns"
"#
)]
/// The conventional aliases for imports. These aliases can be extended by
/// the `extend_aliases` option.
pub aliases: Option<FxHashMap<String, String>>,
#[option(
doc = "A mapping of modules to their conventional import aliases. These aliases will be \
added to the `aliases` mapping.",
default = r#"{}"#,
value_type = "FxHashMap<String, String>",
example = r#"
@ -43,6 +48,8 @@ pub struct Options {
"dask.dataframe" = "dd"
"#
)]
/// A mapping of modules to their conventional import aliases. These aliases
/// will be added to the `aliases` mapping.
pub extend_aliases: Option<FxHashMap<String, String>>,
}

View file

@ -1,57 +1,56 @@
//! Settings for the `flake8-quotes` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub enum Quote {
Single,
Double,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8QuotesOptions"
)]
pub struct Options {
#[option(
doc = r#"
Quote style to prefer for inline strings (either "single" (`'`) or "double" (`"`)).
"#,
default = r#""double""#,
value_type = "Quote",
example = r#"
inline-quotes = "single"
"#
)]
/// Quote style to prefer for inline strings (either "single" (`'`) or
/// "double" (`"`)).
pub inline_quotes: Option<Quote>,
#[option(
doc = r#"
Quote style to prefer for multiline strings (either "single" (`'`) or "double" (`"`)).
"#,
default = r#""double""#,
value_type = "Quote",
example = r#"
multiline-quotes = "single"
"#
)]
/// Quote style to prefer for multiline strings (either "single" (`'`) or
/// "double" (`"`)).
pub multiline_quotes: Option<Quote>,
#[option(
doc = r#"
Quote style to prefer for docstrings (either "single" (`'`) or "double" (`"`)).
"#,
default = r#""double""#,
value_type = "Quote",
example = r#"
docstring-quotes = "single"
"#
)]
/// Quote style to prefer for docstrings (either "single" (`'`) or "double"
/// (`"`)).
pub docstring_quotes: Option<Quote>,
#[option(
doc = r#"
Whether to avoid using single quotes if a string contains single quotes, or vice-versa
with double quotes, as per [PEP8](https://peps.python.org/pep-0008/#string-quotes).
This minimizes the need to escape quotation marks within strings.
"#,
default = r#"true"#,
value_type = "bool",
example = r#"
@ -59,6 +58,9 @@ pub struct Options {
avoid-escape = false
"#
)]
/// Whether to avoid using single quotes if a string contains single quotes,
/// or vice-versa with double quotes, as per [PEP8](https://peps.python.org/pep-0008/#string-quotes).
/// This minimizes the need to escape quotation marks within strings.
pub avoid_escape: Option<bool>,
}

View file

@ -1,23 +1,26 @@
//! Settings for the `flake8-tidy-imports` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub enum Strictness {
Parents,
All,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8TidyImportsOptions"
)]
pub struct Options {
#[option(
doc = r#"
Whether to ban all relative imports (`"all"`), or only those imports that extend into
the parent module and beyond (`"parents"`).
"#,
default = r#""parents""#,
value_type = "Strictness",
example = r#"
@ -25,6 +28,8 @@ pub struct Options {
ban-relative-imports = "all"
"#
)]
/// Whether to ban all relative imports (`"all"`), or only those imports
/// that extend into the parent module and beyond (`"parents"`).
pub ban_relative_imports: Option<Strictness>,
}

View file

@ -1,19 +1,24 @@
//! Settings for the `flake8-unused-arguments` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Flake8UnusedArgumentsOptions"
)]
pub struct Options {
#[option(
doc = r#"
Whether to allow unused variadic arguments, like `*args` and `**kwargs`.
"#,
default = "false",
value_type = "bool",
example = "ignore-variadic-names = true"
)]
/// Whether to allow unused variadic arguments, like `*args` and `**kwargs`.
pub ignore_variadic_names: Option<bool>,
}

View file

@ -3,40 +3,19 @@
use std::collections::BTreeSet;
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "IsortOptions"
)]
pub struct Options {
#[option(
doc = r#"
Combines as imports on the same line. See isort's [`combine-as-imports`](https://pycqa.github.io/isort/docs/configuration/options.html#combine-as-imports)
option.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
combine-as-imports = true
"#
)]
pub combine_as_imports: Option<bool>,
#[option(
doc = r#"
Force `import from` statements with multiple members and at least one alias (e.g.,
`import A as B`) to wrap such that every line contains exactly one member. For example,
this formatting would be retained, rather than condensing to a single line:
```py
from .utils import (
test_directory as test_directory,
test_id as test_id
)
```
Note that this setting is only effective when combined with `combine-as-imports = true`.
When `combine-as-imports` isn't enabled, every aliased `import from` will be given its
own line, in which case, wrapping is not necessary.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
@ -44,42 +23,62 @@ pub struct Options {
combine-as-imports = true
"#
)]
/// Force `import from` statements with multiple members and at least one
/// alias (e.g., `import A as B`) to wrap such that every line contains
/// exactly one member. For example, this formatting would be retained,
/// rather than condensing to a single line:
///
/// ```py
/// from .utils import (
/// test_directory as test_directory,
/// test_id as test_id
/// )
/// ```
///
/// Note that this setting is only effective when combined with
/// `combine-as-imports = true`. When `combine-as-imports` isn't
/// enabled, every aliased `import from` will be given its own line, in
/// which case, wrapping is not necessary.
pub force_wrap_aliases: Option<bool>,
#[option(
doc = r#"
A list of modules to consider first-party, regardless of whether they can be identified
as such via introspection of the local filesystem.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
combine-as-imports = true
"#
)]
/// Combines as imports on the same line. See isort's [`combine-as-imports`](https://pycqa.github.io/isort/docs/configuration/options.html#combine-as-imports)
/// option.
pub combine_as_imports: Option<bool>,
#[option(
default = r#"[]"#,
value_type = "Vec<String>",
example = r#"
known-first-party = ["src"]
"#
)]
/// A list of modules to consider first-party, regardless of whether they
/// can be identified as such via introspection of the local filesystem.
pub known_first_party: Option<Vec<String>>,
#[option(
doc = r#"
A list of modules to consider third-party, regardless of whether they can be identified
as such via introspection of the local filesystem.
"#,
default = r#"[]"#,
value_type = "Vec<String>",
example = r#"
known-third-party = ["src"]
"#
)]
/// A list of modules to consider third-party, regardless of whether they
/// can be identified as such via introspection of the local filesystem.
pub known_third_party: Option<Vec<String>>,
#[option(
doc = r#"
A list of modules to consider standard-library, in addition to those known to Ruff in
advance.
"#,
default = r#"[]"#,
value_type = "Vec<String>",
example = r#"
extra-standard-library = ["path"]
"#
)]
/// A list of modules to consider standard-library, in addition to those
/// known to Ruff in advance.
pub extra_standard_library: Option<Vec<String>>,
}

View file

@ -1,13 +1,19 @@
//! Settings for the `mccabe` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "McCabeOptions"
)]
pub struct Options {
#[option(
doc = "The maximum McCabe complexity to allow before triggering `C901` errors.",
default = "10",
value_type = "usize",
example = r#"
@ -15,6 +21,7 @@ pub struct Options {
max-complexity = 5
"#
)]
/// The maximum McCabe complexity to allow before triggering `C901` errors.
pub max_complexity: Option<usize>,
}

View file

@ -1,6 +1,7 @@
//! Settings for the `pep8-naming` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
const IGNORE_NAMES: [&str; 12] = [
@ -22,26 +23,25 @@ const CLASSMETHOD_DECORATORS: [&str; 1] = ["classmethod"];
const STATICMETHOD_DECORATORS: [&str; 1] = ["staticmethod"];
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "Pep8NamingOptions"
)]
pub struct Options {
#[option(
doc = r#"
A list of names to ignore when considering `pep8-naming` violations.
"#,
default = r#"["setUp", "tearDown", "setUpClass", "tearDownClass", "setUpModule", "tearDownModule", "asyncSetUp", "asyncTearDown", "setUpTestData", "failureException", "longMessage", "maxDiff"]"#,
value_type = "Vec<String>",
example = r#"
ignore-names = ["callMethod"]
"#
)]
/// A list of names to ignore when considering `pep8-naming` violations.
pub ignore_names: Option<Vec<String>>,
#[option(
doc = r#"
A list of decorators that, when applied to a method, indicate that the method should be
treated as a class method. For example, Ruff will expect that any method decorated by a
decorator in this list takes a `cls` argument as its first argument.
"#,
default = r#"["classmethod"]"#,
value_type = "Vec<String>",
example = r#"
@ -49,13 +49,12 @@ pub struct Options {
classmethod-decorators = ["classmethod", "pydantic.validator"]
"#
)]
/// A list of decorators that, when applied to a method, indicate that the
/// method should be treated as a class method. For example, Ruff will
/// expect that any method decorated by a decorator in this list takes a
/// `cls` argument as its first argument.
pub classmethod_decorators: Option<Vec<String>>,
#[option(
doc = r#"
A list of decorators that, when applied to a method, indicate that the method should be
treated as a static method. For example, Ruff will expect that any method decorated by a
decorator in this list has no `self` or `cls` argument.
"#,
default = r#"["staticmethod"]"#,
value_type = "Vec<String>",
example = r#"
@ -63,6 +62,10 @@ pub struct Options {
staticmethod-decorators = ["staticmethod", "stcmthd"]
"#
)]
/// A list of decorators that, when applied to a method, indicate that the
/// method should be treated as a static method. For example, Ruff will
/// expect that any method decorated by a decorator in this list has no
/// `self` or `cls` argument.
pub staticmethod_decorators: Option<Vec<String>>,
}

View file

@ -1,15 +1,19 @@
//! Settings for the `pyupgrade` plugin.
use ruff_macros::ConfigurationOptions;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(
deny_unknown_fields,
rename_all = "kebab-case",
rename = "PyUpgradeOptions"
)]
pub struct Options {
#[option(
doc = r#"
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 applicable when the target Python version is below 3.9 and 3.10 respectively.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
@ -17,6 +21,11 @@ pub struct Options {
keep-runtime-typing = true
"#
)]
/// 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
/// applicable when the target Python version is below 3.9 and 3.10
/// respectively.
pub keep_runtime_typing: Option<bool>,
}

View file

@ -2,6 +2,7 @@
use ruff_macros::ConfigurationOptions;
use rustc_hash::FxHashMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::checks_gen::CheckCodePrefix;
@ -11,14 +12,12 @@ use crate::{
flake8_tidy_imports, flake8_unused_arguments, isort, mccabe, pep8_naming, pyupgrade,
};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema,
)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub struct Options {
#[option(
doc = r#"
A list of allowed "confusable" Unicode characters to ignore when enforcing `RUF001`,
`RUF002`, and `RUF003`.
"#,
default = r#"[]"#,
value_type = "Vec<char>",
example = r#"
@ -27,13 +26,10 @@ pub struct Options {
allowed-confusables = ["", "ρ", ""]
"#
)]
/// A list of allowed "confusable" Unicode characters to ignore when
/// enforcing `RUF001`, `RUF002`, and `RUF003`.
pub allowed_confusables: Option<Vec<char>>,
#[option(
doc = r#"
A regular expression used to identify "dummy" variables, or those which should be
ignored when evaluating (e.g.) unused-variable checks. The default expression matches
`_`, `__`, and `_var`, but not `_var_`.
"#,
default = r#""^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$""#,
value_type = "Regex",
example = r#"
@ -41,39 +37,33 @@ pub struct Options {
dummy-variable-rgx = "^_$"
"#
)]
/// A regular expression used to identify "dummy" variables, or those which
/// should be ignored when evaluating (e.g.) unused-variable checks. The
/// default expression matches `_`, `__`, and `_var`, but not `_var_`.
pub dummy_variable_rgx: Option<String>,
#[option(
doc = r#"
A list of file patterns to exclude from linting.
Exclusions are based on globs, and can be either:
- 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`).
Note that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify
the excluded paths.
"#,
default = r#"[".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv"]"#,
value_type = "Vec<FilePattern>",
example = r#"
exclude = [".venv"]
"#
)]
/// A list of file patterns to exclude from linting.
///
/// Exclusions are based on globs, and can be either:
///
/// - 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`).
///
/// Note that you'll typically want to use
/// [`extend-exclude`](#extend-exclude) to modify the excluded paths.
pub exclude: Option<Vec<String>>,
#[option(
doc = r#"
A path to a local `pyproject.toml` file to merge into this configuration. User home
directory and environment variables will be expanded.
To resolve the current `pyproject.toml` file, Ruff will first resolve this base
configuration file, then merge in any properties defined in the current configuration
file.
"#,
default = r#"None"#,
value_type = "Path",
example = r#"
@ -83,10 +73,15 @@ pub struct Options {
line-length = 100
"#
)]
/// A path to a local `pyproject.toml` file to merge into this
/// configuration. User home directory and environment variables will be
/// expanded.
///
/// To resolve the current `pyproject.toml` file, Ruff will first resolve
/// this base configuration file, then merge in any properties defined
/// in the current configuration file.
pub extend: Option<String>,
#[option(
doc = "A list of file patterns to omit from linting, in addition to those specified by \
`exclude`.",
default = "[]",
value_type = "Vec<FilePattern>",
example = r#"
@ -94,10 +89,10 @@ pub struct Options {
extend-exclude = ["tests", "src/bad.py"]
"#
)]
/// A list of file patterns to omit from linting, in addition to those
/// specified by `exclude`.
pub extend_exclude: Option<Vec<String>>,
#[option(
doc = "A list of check code prefixes to ignore, in addition to those specified by \
`ignore`.",
default = "[]",
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -105,10 +100,10 @@ pub struct Options {
extend-ignore = ["F841"]
"#
)]
/// A list of check code prefixes to ignore, in addition to those specified
/// by `ignore`.
pub extend_ignore: Option<Vec<CheckCodePrefix>>,
#[option(
doc = "A list of check code prefixes to enable, in addition to those specified by \
`select`.",
default = "[]",
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -116,13 +111,10 @@ pub struct Options {
extend-select = ["B", "Q"]
"#
)]
/// A list of check code prefixes to enable, in addition to those specified
/// by `select`.
pub extend_select: Option<Vec<CheckCodePrefix>>,
#[option(
doc = r#"
A list of check codes that are unsupported by Ruff, but should be preserved when (e.g.)
validating `# noqa` directives. Useful for retaining `# noqa` directives that cover plugins not
yet implemented in Ruff.
"#,
default = "[]",
value_type = "Vec<String>",
example = r#"
@ -131,19 +123,16 @@ pub struct Options {
external = ["V101"]
"#
)]
/// A list of check codes that are unsupported by Ruff, but should be
/// preserved when (e.g.) validating `# noqa` directives. Useful for
/// retaining `# noqa` directives that cover plugins not yet implemented
/// in Ruff.
pub external: Option<Vec<String>>,
#[option(
doc = r#"
Enable autofix behavior by-default when running `ruff` (overridden
by the `--fix` and `--no-fix` command-line flags).
"#,
default = "false",
value_type = "bool",
example = "fix = true"
)]
#[option(default = "false", value_type = "bool", example = "fix = true")]
/// Enable autofix behavior by-default when running `ruff` (overridden
/// by the `--fix` and `--no-fix` command-line flags).
pub fix: Option<bool>,
#[option(
doc = "A list of check code prefixes to consider autofix-able.",
default = r#"["A", "ANN", "ARG", "B", "BLE", "C", "D", "E", "ERA", "F", "FBT", "I", "ICN", "N", "PGH", "PLC", "PLE", "PLR", "PLW", "Q", "RET", "RUF", "S", "T", "TID", "UP", "W", "YTT"]"#,
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -151,13 +140,9 @@ pub struct Options {
fixable = ["E", "F"]
"#
)]
/// A list of check code prefixes to consider autofix-able.
pub fixable: Option<Vec<CheckCodePrefix>>,
#[option(
doc = r#"
The style in which violation messages should be formatted: `"text"` (default),
`"grouped"` (group messages by file), `"json"` (machine-readable), `"junit"`
(machine-readable XML), or `"github"` (GitHub Actions annotations).
"#,
default = r#""text""#,
value_type = "SerializationType",
example = r#"
@ -165,33 +150,30 @@ pub struct Options {
format = "grouped"
"#
)]
/// The style in which violation messages should be formatted: `"text"`
/// (default), `"grouped"` (group messages by file), `"json"`
/// (machine-readable), `"junit"` (machine-readable XML), or `"github"`
/// (GitHub Actions annotations).
pub format: Option<SerializationFormat>,
#[option(
doc = r#"
Whether to enforce `exclude` and `extend-exclude` patterns, even for paths that are
passed to Ruff explicitly. Typically, Ruff will lint any paths passed in directly, even
if they would typically be excluded. Setting `force-exclude = true` will cause Ruff to
respect these exclusions unequivocally.
This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all
changed files to the [`ruff-pre-commit`](https://github.com/charliermarsh/ruff-pre-commit)
plugin, regardless of whether they're marked as excluded by Ruff's own settings.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
force-exclude = true
"#
)]
/// Whether to enforce `exclude` and `extend-exclude` patterns, even for
/// paths that are passed to Ruff explicitly. Typically, Ruff will lint
/// any paths passed in directly, even if they would typically be
/// excluded. Setting `force-exclude = true` will cause Ruff to
/// respect these exclusions unequivocally.
///
/// This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all
/// changed files to the [`ruff-pre-commit`](https://github.com/charliermarsh/ruff-pre-commit)
/// plugin, regardless of whether they're marked as excluded by Ruff's own
/// settings.
pub force_exclude: Option<bool>,
#[option(
doc = r"
A list of check code prefixes to ignore. Prefixes can specify exact checks (like
`F841`), entire categories (like `F`), or anything in between.
When breaking ties between enabled and disabled checks (via `select` and `ignore`,
respectively), more specific prefixes override less specific prefixes.
",
default = "[]",
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -199,23 +181,28 @@ pub struct Options {
ignore = ["F841"]
"#
)]
/// A list of check code prefixes to ignore. Prefixes can specify exact
/// checks (like `F841`), entire categories (like `F`), or anything in
/// between.
///
/// When breaking ties between enabled and disabled checks (via `select` and
/// `ignore`, respectively), more specific prefixes override less
/// specific prefixes.
pub ignore: Option<Vec<CheckCodePrefix>>,
#[option(
doc = r#"
Avoid automatically removing unused imports in `__init__.py` files. Such imports will
still be +flagged, but with a dedicated message suggesting that the import is either
added to the module' +`__all__` symbol, or re-exported with a redundant alias (e.g.,
`import os as os`).
"#,
default = "false",
value_type = "bool",
example = r#"
ignore-init-module-imports = true
"#
)]
/// Avoid automatically removing unused imports in `__init__.py` files. Such
/// imports will still be +flagged, but with a dedicated message
/// suggesting that the import is either added to the module' +`__all__`
/// symbol, or re-exported with a redundant alias (e.g., `import os as
/// os`).
pub ignore_init_module_imports: Option<bool>,
#[option(
doc = "The line length to use when enforcing long-lines violations (like E501).",
default = "88",
value_type = "usize",
example = r#"
@ -223,27 +210,21 @@ pub struct Options {
line-length = 120
"#
)]
/// The line length to use when enforcing long-lines violations (like
/// `E501`).
pub line_length: Option<usize>,
#[option(
doc = r#"
Whether to automatically exclude files that are ignored by `.ignore`, `.gitignore`,
`.git/info/exclude`, and global `gitignore` files. Enabled by default.
"#,
default = "true",
value_type = "bool",
example = r#"
respect_gitignore = false
"#
)]
/// Whether to automatically exclude files that are ignored by `.ignore`,
/// `.gitignore`, `.git/info/exclude`, and global `gitignore` files.
/// Enabled by default.
pub respect_gitignore: Option<bool>,
#[option(
doc = r#"
A list of check code prefixes to enable. Prefixes can specify exact checks (like
`F841`), entire categories (like `F`), or anything in between.
When breaking ties between enabled and disabled checks (via `select` and `ignore`,
respectively), more specific prefixes override less specific prefixes.
"#,
default = r#"["E", "F"]"#,
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -251,12 +232,15 @@ pub struct Options {
select = ["E", "F", "B", "Q"]
"#
)]
/// A list of check code prefixes to enable. Prefixes can specify exact
/// checks (like `F841`), entire categories (like `F`), or anything in
/// between.
///
/// When breaking ties between enabled and disabled checks (via `select` and
/// `ignore`, respectively), more specific prefixes override less
/// specific prefixes.
pub select: Option<Vec<CheckCodePrefix>>,
#[option(
doc = r#"
Whether to show source code snippets when reporting lint error violations (overridden by
the `--show-source` command-line flag).
"#,
default = "false",
value_type = "bool",
example = r#"
@ -264,31 +248,10 @@ pub struct Options {
show-source = true
"#
)]
/// Whether to show source code snippets when reporting lint error
/// violations (overridden by the `--show-source` command-line flag).
pub show_source: Option<bool>,
#[option(
doc = r#"
The source code paths to consider, e.g., when resolving first- vs. third-party imports.
As an example: given a Python package structure like:
```text
my_package/
pyproject.toml
src/
my_package/
__init__.py
foo.py
bar.py
```
The `src` directory should be included in `source` (e.g., `source = ["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 that directory. User home directory and environment variables
will also be expanded.
"#,
default = r#"["."]"#,
value_type = "Vec<PathBuf>",
example = r#"
@ -296,13 +259,32 @@ pub struct Options {
src = ["src", "test"]
"#
)]
/// The source code paths to consider, e.g., when resolving first- vs.
/// third-party imports.
///
/// As an example: given a Python package structure like:
///
/// ```text
/// my_package/
/// pyproject.toml
/// src/
/// my_package/
/// __init__.py
/// foo.py
/// bar.py
/// ```
///
/// The `src` directory should be included in `source` (e.g., `source =
/// ["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 that directory. User home directory and environment
/// variables will also be expanded.
pub src: Option<Vec<String>>,
#[option(
doc = r#"
The Python version to target, e.g., when considering automatic code upgrades, like
rewriting type annotations. Note that the target version will _not_ be inferred from the
_current_ Python version, and instead must be specified explicitly (as seen below).
"#,
default = r#""py310""#,
value_type = "PythonVersion",
example = r#"
@ -310,9 +292,12 @@ pub struct Options {
target-version = "py37"
"#
)]
/// The Python version to target, e.g., when considering automatic code
/// upgrades, like rewriting type annotations. Note that the target
/// version will _not_ be inferred from the _current_ Python version,
/// and instead must be specified explicitly (as seen below).
pub target_version: Option<PythonVersion>,
#[option(
doc = "A list of check code prefixes to consider un-autofix-able.",
default = "[]",
value_type = "Vec<CheckCodePrefix>",
example = r#"
@ -320,53 +305,60 @@ pub struct Options {
unfixable = ["F401"]
"#
)]
/// A list of check code prefixes to consider un-autofix-able.
pub unfixable: Option<Vec<CheckCodePrefix>>,
#[option(
doc = r#"
A path to the cache directory.
By default, Ruff stores cache results in a `.ruff_cache` directory in the current
project root.
However, Ruff will also respect the `RUFF_CACHE_DIR` environment variable, which takes
precedence over that default.
This setting will override even the `RUFF_CACHE_DIR` environment variable, if set.
"#,
default = ".ruff_cache",
value_type = "PathBuf",
example = r#"cache-dir = "~/.cache/ruff""#
)]
/// A path to the cache directory.
///
/// By default, Ruff stores cache results in a `.ruff_cache` directory in
/// the current project root.
///
/// However, Ruff will also respect the `RUFF_CACHE_DIR` environment
/// variable, which takes precedence over that default.
///
/// This setting will override even the `RUFF_CACHE_DIR` environment
/// variable, if set.
pub cache_dir: Option<String>,
// Plugins
/// Plugins
#[option_group]
/// Options for the `flake8-annotations` plugin.
pub flake8_annotations: Option<flake8_annotations::settings::Options>,
#[option_group]
/// Options for the `flake8-bugbear` plugin.
pub flake8_bugbear: Option<flake8_bugbear::settings::Options>,
#[option_group]
/// Options for the `flake8-errmsg` plugin.
pub flake8_errmsg: Option<flake8_errmsg::settings::Options>,
#[option_group]
/// Options for the `flake8-quotes` plugin.
pub flake8_quotes: Option<flake8_quotes::settings::Options>,
#[option_group]
/// Options for the `flake8-tidy-imports` plugin.
pub flake8_tidy_imports: Option<flake8_tidy_imports::settings::Options>,
#[option_group]
/// Options for the `flake8-import-conventions` plugin.
pub flake8_import_conventions: Option<flake8_import_conventions::settings::Options>,
#[option_group]
/// Options for the `flake8-unused-arguments` plugin.
pub flake8_unused_arguments: Option<flake8_unused_arguments::settings::Options>,
#[option_group]
/// Options for the `isort` plugin.
pub isort: Option<isort::settings::Options>,
#[option_group]
/// Options for the `mccabe` plugin.
pub mccabe: Option<mccabe::settings::Options>,
#[option_group]
/// Options for the `pep8-naming` plugin.
pub pep8_naming: Option<pep8_naming::settings::Options>,
#[option_group]
/// Options for the `pyupgrade` plugin.
pub pyupgrade: Option<pyupgrade::settings::Options>,
// Tables are required to go last.
#[option(
doc = r#"
A list of mappings from file pattern to check code prefixes to exclude, when considering
any matching files.
"#,
default = "{}",
value_type = "HashMap<String, Vec<CheckCodePrefix>>",
example = r#"
@ -376,5 +368,7 @@ pub struct Options {
"path/to/file.py" = ["E402"]
"#
)]
/// A list of mappings from file pattern to check code prefixes to exclude,
/// when considering any matching files.
pub per_file_ignores: Option<FxHashMap<String, Vec<CheckCodePrefix>>>,
}

View file

@ -7,13 +7,16 @@ use anyhow::{anyhow, bail, Result};
use clap::ValueEnum;
use globset::{Glob, GlobSetBuilder};
use rustc_hash::FxHashSet;
use schemars::JsonSchema;
use serde::{de, Deserialize, Deserializer, Serialize};
use crate::checks::CheckCode;
use crate::checks_gen::CheckCodePrefix;
use crate::fs;
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[derive(
Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema,
)]
#[serde(rename_all = "lowercase")]
pub enum PythonVersion {
Py33,
@ -142,7 +145,7 @@ impl FromStr for PatternPrefixPair {
}
}
#[derive(Clone, Copy, ValueEnum, PartialEq, Eq, Serialize, Deserialize, Debug)]
#[derive(Clone, Copy, ValueEnum, PartialEq, Eq, Serialize, Deserialize, Debug, JsonSchema)]
#[serde(rename_all = "kebab-case")]
pub enum SerializationFormat {
Text,