target-version = "py311" # Pin Ruff to Python 3.11 line-length = 88 output-format = "full" extend-exclude = [ "build/*", "doc/_build/*", "tests/roots/test-directive-code/target.py", # Tests break if formatted "tests/roots/test-pycode/cp_1251_coded.py", # Not UTF-8 ] [format] preview = true quote-style = "single" [lint] preview = true ignore = [ # flake8-builtins "A001", # Variable `{name}` is shadowing a Python builtin "A002", # Function argument `{name}` is shadowing a Python builtin "A005", # Module `{name}` is shadowing a Python builtin module # flake8-annotations "ANN401", # Dynamically typed expressions (typing.Any) are disallowed in `{name}` # flake8-unused-arguments ('ARG') "ARG001", # Unused function argument: `{name}` "ARG002", # Unused method argument: `{name}` "ARG003", # Unused class method argument: `{name}` "ARG005", # Unused lambda argument: `{name}` # flake8-blind-except "BLE001", # Do not catch blind exception: `{name}` # flake8-commas "COM812", # Trailing comma missing # flake8-copyright "CPY001", # Missing copyright notice at top of file # pydocstyle ('D') "D100", # Missing docstring in public module "D101", # Missing docstring in public class "D102", # Missing docstring in public method "D103", # Missing docstring in public function "D104", # Missing docstring in public package "D105", # Missing docstring in magic method "D107", # Missing docstring in `__init__` "D200", # One-line docstring should fit on one line "D205", # 1 blank line required between summary line and description "D400", # First line should end with a period "D401", # First line of docstring should be in imperative mood: "{first_line}" # pydoclint "DOC201", # `return` is not documented in docstring "DOC402", # `yield` is not documented in docstring "DOC501", # Raised exception `{id}` missing from docstring # pycodestyle "E741", # Ambiguous variable name: `{name}` # eradicate "ERA001", # Found commented-out code # pyflakes "F841", # Local variable `{name}` is assigned to but never used # flake8-boolean-trap "FBT001", # Boolean-typed positional argument in function definition "FBT002", # Boolean default positional argument in function definition "FBT003", # Boolean positional value in function call # flake8-fixme "FIX001", # Line contains FIXME, consider resolving the issue "FIX002", # Line contains TODO, consider resolving the issue "FIX003", # Line contains XXX, consider resolving the issue "FIX004", # Line contains HACK, consider resolving the issue # refurb "FURB101", # `open` and `read` should be replaced by `Path(...).read_text(...)` "FURB103", # `open` and `write` should be replaced by `Path(...).write_text(...)` # flake8-implicit-str-concat # pep8-naming "N801", # Class name `{name}` should use CapWords convention "N802", # Function name `{name}` should be lowercase "N803", # Argument name `{name}` should be lowercase "N806", # Variable `{name}` in function should be lowercase "N818", # Exception name `{name}` should be named with an Error suffix # perflint "PERF203", # `try`-`except` within a loop incurs performance overhead # flake8-pie "PIE790", # Unnecessary `pass` statement # pylint "PLC0415", # `import` should be at the top-level of a file "PLC2701", # Private name import `{name}` from external module `{module}` "PLR0904", # Too many public methods ({methods} > {max_methods}) "PLR0911", # Too many return statements ({returns} > {max_returns}) "PLR0912", # Too many branches ({branches} > {max_branches}) "PLR0913", # Too many arguments in function definition ({c_args} > {max_args}) "PLR0914", # Too many local variables ({current_amount}/{max_amount}) "PLR0915", # Too many statements ({statements} > {max_statements}) "PLR0916", # Too many Boolean expressions ({expressions} > {max_expressions}) "PLR0917", # Too many positional arguments ({c_pos}/{max_pos}) "PLR1702", # Too many nested blocks ({nested_blocks} > {max_nested_blocks}) "PLR2004", # Magic value used in comparison, consider replacing `{value}` with a constant variable "PLR5501", # Use `elif` instead of `else` then `if`, to reduce indentation "PLR6104", # Use `{operator}` to perform an augmented assignment directly "PLR6301", # Method `{method_name}` could be a function, class method, or static method "PLW2901", # Outer {outer_kind} variable `{name}` overwritten by inner {inner_kind} target # flake8-use-pathlib "PTH100", # `os.path.abspath()` should be replaced by `Path.resolve()` "PTH110", # `os.path.exists()` should be replaced by `Path.exists()` "PTH113", # `os.path.isfile()` should be replaced by `Path.is_file()` "PTH118", # `os.{module}.join()` should be replaced by `Path` with `/` operator "PTH119", # `os.path.basename()` should be replaced by `Path.name` "PTH120", # `os.path.dirname()` should be replaced by `Path.parent` "PTH122", # `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent` "PTH123", # `open()` should be replaced by `Path.open()` # flake8-pyi ('PYI') "PYI025", # Use `from collections.abc import Set as AbstractSet` to avoid confusion with the `set` builtin # flake8-return "RET504", # Unnecessary assignment to `{name}` before `return` statement "RET505", # Unnecessary `{branch}` after `return` statement "RET506", # Unnecessary `{branch}` after `raise` statement # flake8-bandit ('S') "S101", # Use of `assert` detected "S110", # `try`-`except`-`pass` detected, consider logging the exception "S404", # `subprocess` module is possibly insecure "S405", # `xml.etree` methods are vulnerable to XML attacks "S603", # `subprocess` call: check for execution of untrusted input # flake8-simplify "SIM102", # Use a single `if` statement instead of nested `if` statements "SIM108", # Use ternary operator `{contents}` instead of `if`-`else`-block # flake8-self "SLF001", # Private member accessed: `{access}` # flake8-todos ('TD') "TD001", # Invalid TODO tag: `{tag}` "TD002", # Missing author in TODO; try: `# TODO(): ...` or `# TODO @: ...` "TD003", # Missing issue link on the line following this TODO "TD004", # Missing colon in TODO # tryceratops "TRY002", # Create your own exception "TRY300", # Consider moving this statement to an `else` block # pyupgrade "UP031", # Use format specifiers instead of percent format "UP032", # Use f-string instead of `format` call # Ruff-specific rules ('RUF') "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` "RUF021", # Parenthesize `a and b` expressions when chaining `and` and `or` together, to make the precedence clear "RUF022", # `__all__` is not sorted "RUF023", # `{}.__slots__` is not sorted "RUF027", # Possible f-string without an `f` prefix "RUF039", # First argument to {call} is not raw string "RUF052", # Local dummy variable `{}` is accessed ] external = [ # Whitelist for RUF100 unknown code warnings "SIM113", ] select = [ # flake8-builtins ('A') "A", # airflow ('AIR') # Airflow is not used in Sphinx # flake8-annotations ('ANN') "ANN", # flake8-unused-arguments ('ARG') "ARG", # flake8-async ('ASYNC') "ASYNC", # flake8-bugbear ('B') "B", # flake8-blind-except ('BLE') "BLE", # flake8-comprehensions ('C4') "C4", # mccabe ('C90') # "C901", # `{name}` is too complex ({complexity} > {max_complexity}) # flake8-commas ('COM') "COM", # Trailing comma prohibited # flake8-copyright ('CPY') "CPY", # pydocstyle ('D') "D", "D212", # Multi-line docstring summary should start at the first line # "D404", # First word of the docstring should not be "This" # "D415", # First line should end with a period, question mark, or exclamation point "D417", # Missing argument description in the docstring for `{definition}`: `{name}` # pydoclint ('DOC') "DOC", # flake8-django ('DJ') # Django is not used in Sphinx # flake8-datetimez ('DTZ') "DTZ", # pycodestyle ('E') "E", # flake8-errmsg ('EM') "EM", # eradicate ('ERA') "ERA", # flake8-executable ('EXE') "EXE", # pyflakes ('F') "F", # flake8-future-annotations ('FA') "FA", # flake8-fastapi ('FAST') # FastAPI is not used in Sphinx # flake8-boolean-trap ('FBT') "FBT", # flake8-fixme ('FIX') "FIX", # flynt ('FLY') "FLY", # refurb ('FURB') "FURB", # flake8-logging-format ('G') "G", # isort ('I') "I", # flake8-import-conventions ('ICN') "ICN", # flake8-no-pep420 ('INP') "INP", # flake8-gettext ('INT') "INT", # flake8-implicit-str-concat ('ISC') "ISC", # flake8-logging ('LOG') "LOG", # pep8-naming ('N') "N", # numpy-specific rules ('NPY') # Numpy is not used in Sphinx # pandas-vet ('PD') # Pandas is not used in Sphinx # perflint ('PERF') "PERF", # pygrep-hooks ('PGH') "PGH", # flake8-pie ('PIE') "PIE", # pylint ('PL', 'PLC', 'PLE', 'PLR', 'PLW') "PL", # flake8-pytest-style ('PT') "PT", # flake8-use-pathlib ('PTH') "PTH", # flake8-pyi ('PYI') "PYI", # flake8-quotes ('Q') "Q", # flake8-return ('RET') "RET", # flake8-raise ('RSE') "RSE", # Ruff-specific rules ('RUF') "RUF", # flake8-bandit ('S') "S", # flake8-simplify ('SIM') "SIM", # flake8-simplify # flake8-self ('SLF') "SLF", # flake8-slots ('SLOT') "SLOT", # flake8-debugger ('T10') "T10", # flake8-print ('T20') "T20", # flake8-type-checking ('TC') "TC", # flake8-todos ('TD') "TD", # flake8-tidy-imports ('TID') "TID", # flake8-trio ('TRIO') # Trio is not used in Sphinx # tryceratops ('TRY') "TRY", # pyupgrade ('UP') "UP", # pycodestyle ('W') "W", # flake8-2020 ('YTT') "YTT", ] logger-objects = [ "sphinx.ext.apidoc._shared.LOGGER", "sphinx.ext.intersphinx._shared.LOGGER", ] [lint.per-file-ignores] "doc/*" = [ "ANN", # documentation doesn't need annotations "TC001", # documentation doesn't need type-checking blocks ] "doc/conf.py" = [ "INP001", # doc/ is not a namespace package ] "doc/development/tutorials/examples/*" = [ "I002", # we don't need the annotations future "INP001", # examples/ is not a namespace package ] "doc/development/tutorials/examples/recipe.py" = [ "FURB118", # keep the tutorial simple: no itemgetter "T201" # allow print() in the tutorial ] "doc/usage/extensions/example_{google,numpy}.py" = [ "D416", # Section name should end with a colon ("{name}") "DOC502", # Raised exception is not explicitly raised: `{id}` "I002", # Missing required import: {name} "INP001", # File {filename} is part of an implicit namespace package. Add an __init__.py. "PLW3201", # Dunder method {name} has no special meaning in Python 3 ] # whitelist ``print`` for stdout messages "sphinx/_cli/__init__.py" = ["T201"] # allow use of ``pickle`` "sphinx/{application,builders/__init__,environment/__init__,ext/coverage,search/__init__,versioning}.py" = [ "S301", "S403", ] # whitelist ``print`` for stdout messages "sphinx/cmd/build.py" = ["T201"] "sphinx/cmd/make_mode.py" = ["T201"] "sphinx/cmd/quickstart.py" = [ "PTH", "T201", ] "sphinx/environment/collectors/toctree.py" = ["B026"] "sphinx/environment/adapters/toctree.py" = ["B026"] # whitelist ``print`` for stdout messages "sphinx/ext/intersphinx/_cli.py" = ["T201"] # whitelist ``token`` in docstring parsing "sphinx/ext/napoleon/docstring.py" = ["S105"] "sphinx/search/*" = ["RUF001"] # whitelist ``print`` for stdout messages "sphinx/testing/fixtures.py" = ["T201"] # whitelist ``os.path`` for deprecated ``sphinx.testing.path`` "sphinx/testing/path.py" = ["PTH"] # whitelist ``token`` in date format parsing "sphinx/util/i18n.py" = ["S105"] # whitelist ``os.path`` for ``sphinx.util.osutil`` "sphinx/util/osutil.py" = ["PTH"] # whitelist ``token`` in literal parsing "sphinx/writers/html5.py" = ["S105"] "tests/*" = [ "E501", "ANN", # tests don't need annotations "D402", "PLC1901", # whitelist comparisons to the empty string ('') "RUF001", # ambiguous unicode character "S301", # allow use of ``pickle`` "S403", # allow use of ``pickle`` "T201", # whitelist ``print`` for tests ] # test roots are not packages "tests/js/roots/*" = ["I002", "INP001"] "tests/roots/*" = [ "D403", # permit uncapitalised docstrings "F401", # names may be unused in test roots "I002", # we don't need the annotations future "INP001", # test roots are not packages ] # these tests need old ``typing`` generic aliases "tests/roots/test-ext-autodoc/target/genericalias.py" = ["UP006", "UP007", "UP035", "UP045"] "tests/test_util/test_util_typing.py" = ["RUF036", "UP006", "UP007", "UP035", "UP045"] "tests/test_util/typing_test_data.py" = ["FA100", "I002", "PYI030", "UP006", "UP007", "UP035", "UP045"] "utils/*" = [ "T201", # whitelist ``print`` for stdout messages "ANN", # utilities don't need annotations ] [lint.pycodestyle] max-line-length = 95 [lint.flake8-quotes] inline-quotes = "single" [lint.flake8-type-checking] exempt-modules = [] strict = true [lint.isort] forced-separate = [ "tests", ] required-imports = [ "from __future__ import annotations", ] [lint.pydocstyle] convention = "pep257" ignore-decorators = ["typing.overload"] ignore-var-parameters = true