diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a69c6621f..0d434f5c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,16 +20,16 @@ jobs: fail-fast: false matrix: include: - - nox-sessions: "black check_yaml check_json check_toml check_eof check_trailing_space check_lf" + - nox-sessions: "ruff_format ruff_lint check_yaml check_json check_toml check_eof check_trailing_space check_lf" python-version: "3.x" node-version: "16.x" - - nox-sessions: "mypy pylint" + - nox-sessions: "mypy" python-version: "3.9" - - nox-sessions: "mypy pylint" + - nox-sessions: "mypy" python-version: "3.10" - - nox-sessions: "mypy pylint" + - nox-sessions: "mypy" python-version: "3.11" - - nox-sessions: "mypy pylint" + - nox-sessions: "mypy" python-version: "3.12" steps: - uses: actions/checkout@v4 @@ -54,9 +54,9 @@ jobs: if: matrix.node-version with: path: | - .nox/black + .nox/ruff_* .nox/check_* - key: nox-${{ steps.python-setup.outputs.python-version }}-${{ hashFiles('requirements/dev-black.txt', 'requirements/dev-pre_commit_hooks.txt') }} + key: nox-${{ steps.python-setup.outputs.python-version }}-${{ hashFiles('requirements/dev-ruff.txt', 'requirements/dev-pre_commit_hooks.txt') }} - run: npm install if: matrix.node-version - run: npm run check diff --git a/dev-requirements.txt b/dev-requirements.txt index 1bb0d9a20..ee44991b8 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,4 +4,4 @@ nox -r requirements/cpp.txt -r requirements/dev-mypy.txt -r requirements/dev-black.txt --r requirements/dev-pylint.txt +-r requirements/dev-ruff.txt diff --git a/docs/conf.py b/docs/conf.py index 6f441ffac..b643f7f46 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -353,6 +353,7 @@ def get_colors(color_t: str): unique_colors.append(m.group(1)) return unique_colors + # jinja contexts example_python_apigen_modules = { "my_module": "my_api/", @@ -373,8 +374,12 @@ def get_colors(color_t: str): ( full_name, overload_id, - python_apigen._get_docname(example_python_apigen_modules, full_name, overload_id, False), - python_apigen._get_docname(example_python_apigen_modules, full_name, overload_id, True), + python_apigen._get_docname( + example_python_apigen_modules, full_name, overload_id, False + ), + python_apigen._get_docname( + example_python_apigen_modules, full_name, overload_id, True + ), ) for full_name, overload_id in example_python_apigen_objects ], diff --git a/docs/tensorstore_demo/__init__.py b/docs/tensorstore_demo/__init__.py index 5ba76a517..07875c0fb 100644 --- a/docs/tensorstore_demo/__init__.py +++ b/docs/tensorstore_demo/__init__.py @@ -6,9 +6,10 @@ from __future__ import annotations import typing -import _abc -from ._tensorstore import * +from ._tensorstore import * # noqa: F403 + +# fmt: off class Dim(): diff --git a/docs/test_py_module/test.py b/docs/test_py_module/test.py index 1782eef09..ec766676f 100644 --- a/docs/test_py_module/test.py +++ b/docs/test_py_module/test.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """Test Module for sphinx_rtd_theme.""" + import functools from typing import Union class Foo: - """Docstring for class Foo. This text tests for the formatting of docstrings generated from output diff --git a/merge_from_mkdocs_material.py b/merge_from_mkdocs_material.py index 02189fc68..8f91f72c1 100755 --- a/merge_from_mkdocs_material.py +++ b/merge_from_mkdocs_material.py @@ -27,7 +27,6 @@ import json import os import pathlib -import shutil import subprocess import tempfile from typing import Optional @@ -243,7 +242,7 @@ def main(): message=f"Original upstream {merge_base} (adjusted)", ) - print(f"\nCreating adjusted commit for sphinx-immaterial") + print("\nCreating adjusted commit for sphinx-immaterial") subprocess.run( ["git", "remote", "rm", "local-sphinx-immaterial"], cwd=temp_workdir, @@ -289,7 +288,7 @@ def main(): parent=old_tree_commit, ) - print(f"\nRebasing") + print("\nRebasing") subprocess.run(["git", "rebase", new_tree_commit, "HEAD"], cwd=temp_workdir) with open(patch_path, "wb") as patch_f: diff --git a/noxfile.py b/noxfile.py index c4106bbe2..ae41c3d1a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -6,8 +6,8 @@ nox.options.reuse_existing_virtualenvs = True nox.options.sessions = [ - "black", - "pylint", + "ruff_format", + "ruff_lint", "mypy", "check_yaml", "check_json", @@ -21,17 +21,17 @@ @nox.session -def black(session: nox.Session): - """Checks formatting linting and typing""" - session.install("-r", "requirements/dev-black.txt") - session.run("black", ".") +def ruff_format(session: nox.Session): + """Checks formatting with ruff""" + session.install("-r", "requirements/dev-ruff.txt") + session.run("ruff", "format") -@nox.session(python=False) -def pylint(session: nox.Session): - """Run pylint using in default env""" - session.run("pip", "install", "-r", "requirements/dev-pylint.txt") - session.run("pylint", "sphinx_immaterial") +@nox.session +def ruff_lint(session: nox.Session): + """Run ruff as linter""" + session.install("-r", "requirements/dev-ruff.txt") + session.run("ruff", "check") @nox.session(python=False) @@ -45,7 +45,7 @@ def mypy(session: nox.Session): "|".join( [ "\\.git/", - "^\\.(?:mypy|pylint|pytest|eslint)_?cache", + "^\\.(?:mypy|ruff|pytest|eslint)_?cache", "^(?:\\.nox|\\.?env|\\.?venv)", "^\\.coverage.*", "^htmlcov/", diff --git a/pyproject.toml b/pyproject.toml index 343a8fed9..aa7cb2f79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,13 +13,6 @@ exclude = "setup.py" plugins = ["pydantic.mypy"] check_untyped_defs = true -[tool.black] -include = '\.py$' -# 'extend-exclude' excludes files or directories in addition to the defaults -extend-exclude = '^/docs/tensorstore_demo/__init__\.py$' -# Note: Don't add options like `--diff` here since then `black` cannot -# easily be used from the command line to reformat files. - [tool.pytest.ini_options] minversion = "6.0" testpaths = ["tests"] @@ -61,562 +54,3 @@ exclude_lines = [ [tool.coverage.html] show_contexts = true - -[tool.pylint.main] -# Analyse import fallback blocks. This can be used to support both Python 2 and 3 -# compatible code, which means that the block might have code that exists only in -# one or another interpreter, leading to false positives when analysed. -# analyse-fallback-blocks = - -# Always return a 0 (non-error) status code, even if lint errors are found. This -# is primarily useful in continuous integration scripts. -# exit-zero = - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-allow-list = ["pydantic.dataclasses"] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. (This is an alternative name to extension-pkg-allow-list -# for backward compatibility.) -# extension-pkg-whitelist = - -# Return non-zero exit code if any of these messages/categories are detected, -# even if score is above --fail-under value. Syntax same as enable. Messages -# specified are enabled, while categories only check already-enabled messages. -# fail-on = - -# Specify a score threshold to be exceeded before program exits with error. -fail-under = 10.0 - -# Interpret the stdin as a python script, whose filename needs to be passed as -# the module_or_package argument. -# from-stdin = - -# Files or directories to be skipped. They should be base names, not paths. -ignore = ["CVS"] - -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against paths and can be in Posix or Windows format. -# ignore-paths = - -# Files or directories matching the regex patterns are skipped. The regex matches -# against base names, not paths. The default value ignores Emacs file locks -# ignore-patterns = - -# List of module names for which member attributes should not be checked (useful -# for modules/projects where namespaces are manipulated during runtime and thus -# existing member attributes cannot be deduced by static analysis). It supports -# qualified module names, as well as Unix pattern matching. -# ignored-modules = - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -# init-hook = - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs = 1 - -# Control the amount of potential inferred values when inferring a single object. -# This can help the performance when dealing with large functions or complex, -# nested conditions. -limit-inference-results = 100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -# load-plugins = - -# Pickle collected data for later comparisons. -persistent = true - -# Minimum Python version to use for version dependent checks. Will default to the -# version used to run pylint. -py-version = "3.10" - -# Discover python modules and packages in the file system subtree. -# recursive = - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode = true - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -# unsafe-load-any-extension = - -[tool.pylint.basic] -# Naming style matching correct argument names. -argument-naming-style = "snake_case" - -# Regular expression matching correct argument names. Overrides argument-naming- -# style. If left empty, argument names will be checked with the set naming style. -# argument-rgx = - -# Naming style matching correct attribute names. -attr-naming-style = "snake_case" - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. If left empty, attribute names will be checked with the set naming -# style. -# attr-rgx = - -# Bad variable names which should always be refused, separated by a comma. -bad-names = ["foo", "bar", "baz", "toto", "tutu", "tata"] - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -# bad-names-rgxs = - -# Naming style matching correct class attribute names. -class-attribute-naming-style = "any" - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. If left empty, class attribute names will be checked -# with the set naming style. -# class-attribute-rgx = - -# Naming style matching correct class constant names. -class-const-naming-style = "UPPER_CASE" - -# Regular expression matching correct class constant names. Overrides class- -# const-naming-style. If left empty, class constant names will be checked with -# the set naming style. -# class-const-rgx = - -# Naming style matching correct class names. -class-naming-style = "PascalCase" - -# Regular expression matching correct class names. Overrides class-naming-style. -# If left empty, class names will be checked with the set naming style. -# class-rgx = - -# Naming style matching correct constant names. -const-naming-style = "UPPER_CASE" - -# Regular expression matching correct constant names. Overrides const-naming- -# style. If left empty, constant names will be checked with the set naming style. -# const-rgx = - -# Minimum line length for functions/classes that require docstrings, shorter ones -# are exempt. -docstring-min-length = -1 - -# Naming style matching correct function names. -function-naming-style = "snake_case" - -# Regular expression matching correct function names. Overrides function-naming- -# style. If left empty, function names will be checked with the set naming style. -# function-rgx = - -# Good variable names which should always be accepted, separated by a comma. -good-names = ["i", "j", "k", "ex", "Run", "_"] - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -# good-names-rgxs = - -# Include a hint for the correct naming format with invalid-name. -# include-naming-hint = - -# Naming style matching correct inline iteration names. -inlinevar-naming-style = "any" - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. If left empty, inline iteration names will be checked -# with the set naming style. -# inlinevar-rgx = - -# Naming style matching correct method names. -method-naming-style = "snake_case" - -# Regular expression matching correct method names. Overrides method-naming- -# style. If left empty, method names will be checked with the set naming style. -# method-rgx = - -# Naming style matching correct module names. -module-naming-style = "snake_case" - -# Regular expression matching correct module names. Overrides module-naming- -# style. If left empty, module names will be checked with the set naming style. -# module-rgx = - -# Colon-delimited sets of names that determine each other's naming style when the -# name regexes allow several styles. -# name-group = - -# Regular expression which should only match function or class names that do not -# require a docstring. -no-docstring-rgx = "^_" - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. These -# decorators are taken in consideration only for invalid-name. -property-classes = ["abc.abstractproperty"] - -# Regular expression matching correct type variable names. If left empty, type -# variable names will be checked with the set naming style. -# typevar-rgx = - -# Naming style matching correct variable names. -variable-naming-style = "snake_case" - -# Regular expression matching correct variable names. Overrides variable-naming- -# style. If left empty, variable names will be checked with the set naming style. -# variable-rgx = - -[tool.pylint.classes] -# Warn about protected attribute access inside special methods -# check-protected-access-in-special-methods = - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods = ["__init__", "__new__", "setUp", "__post_init__"] - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected = ["_asdict", "_fields", "_replace", "_source", "_make"] - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg = ["cls"] - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg = ["cls"] - -[tool.pylint.design] -# List of regular expressions of class ancestor names to ignore when counting -# public methods (see R0903) -# exclude-too-few-public-methods = - -# List of qualified class names to ignore when counting class parents (see R0901) -# ignored-parents = - -# Maximum number of arguments for function / method. -max-args = 9 - -# Maximum number of attributes for a class (see R0902). -max-attributes = 7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr = 5 - -# Maximum number of branch for function / method body. -max-branches = 12 - -# Maximum number of locals for function / method body. -max-locals = 20 - -# Maximum number of parents for a class (see R0901). -max-parents = 7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods = 20 - -# Maximum number of return / yield for function / method body. -max-returns = 6 - -# Maximum number of statements in function / method body. -max-statements = 50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods = 2 - -[tool.pylint.exceptions] -# Exceptions that will emit a warning when caught. -overgeneral-exceptions = ["builtins.BaseException", "builtins.Exception"] - -[tool.pylint.format] -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -# expected-line-ending-format = - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines = "^\\s*(# )??$" - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren = 4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string = " " - -# Maximum number of characters on a single line. -max-line-length = 90 - -# Maximum number of lines in a module. -max-module-lines = 1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -# single-line-class-stmt = - -# Allow the body of an if to be on the same line as the test if there is no else. -# single-line-if-stmt = - -[tool.pylint.imports] -# List of modules that can be imported at any level, not just the top level one. -# allow-any-import-level = - -# Allow wildcard imports from modules that define __all__. -# allow-wildcard-with-all = - -# Deprecated modules which should not be used, separated by a comma. -# deprecated-modules = - -# Output a graph (.gv or any supported image format) of external dependencies to -# the given file (report RP0402 must not be disabled). -# ext-import-graph = - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be disabled). -# import-graph = - -# Output a graph (.gv or any supported image format) of internal dependencies to -# the given file (report RP0402 must not be disabled). -# int-import-graph = - -# Force import order to recognize a module as part of the standard compatibility -# libraries. -# known-standard-library = - -# Force import order to recognize a module as part of a third party library. -known-third-party = ["enchant"] - -# Couples of modules and preferred modules, separated by a comma. -# preferred-modules = - -[tool.pylint.logging] -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style = "old" - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules = ["logging"] - -[tool.pylint."messages control"] -# Only show warnings with the listed confidence levels. Leave empty to show all. -# Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence = ["HIGH", "CONTROL_FLOW", "INFERENCE", "INFERENCE_FAILURE", "UNDEFINED"] - -# Disable the message, report, category or checker with the given id(s). You can -# either give multiple identifiers separated by comma (,) or put this option -# multiple times (only on the command line, not in the configuration file where -# it should appear only once). You can also use "--disable=all" to disable -# everything first and then re-enable specific checks. For example, if you want -# to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable = [ - "raw-checker-failed", - "bad-inline-option", - "locally-disabled", - "file-ignored", - "suppressed-message", - "useless-suppression", - "deprecated-pragma", - "use-symbolic-message-instead", - "missing-function-docstring", - "missing-class-docstring", - "missing-module-docstring", - "unused-argument", - "invalid-name", - "consider-using-f-string", - "too-few-public-methods", - "attribute-defined-outside-init", - "access-member-before-definition", - "protected-access", - "dangerous-default-value", - "unused-variable", - "no-member", - "duplicate-code", - "too-many-statements", - "too-many-locals", - "too-many-branches", - "too-many-ancestors", - "too-many-nested-blocks", - "global-statement", - "too-many-lines", - "too-many-instance-attributes", - "useless-option-value", - "unknown-option-value", - "too-many-return-statements", - "line-too-long", - "fixme", - "cyclic-import", - "too-many-arguments" -] - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where it -# should appear only once). See also the "--disable" option for examples. -enable = ["c-extension-no-member", "unused-import", "init-import"] - -[tool.pylint.miscellaneous] -# List of note tags to take in consideration, separated by a comma. -notes = ["FIXME", "XXX", "TODO"] - -# Regular expression of note tags to take in consideration. -# notes-rgx = - -[tool.pylint.refactoring] -# Maximum number of nested blocks for function / method body -max-nested-blocks = 5 - -# Complete name of functions that never returns. When checking for inconsistent- -# return-statements if a never returning function is called then it will be -# considered as an explicit return statement and no message will be printed. -never-returning-functions = ["sys.exit", "argparse.parse_error"] - -[tool.pylint.reports] -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'fatal', 'error', 'warning', 'refactor', -# 'convention', and 'info' which contain the number of messages in each category, -# as well as 'statement' which is the total number of statements analyzed. This -# score is used by the global evaluation report (RP0004). -evaluation = "10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)" - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -# msg-template = - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -# output-format = - -# Tells whether to display a full report or only the messages. -# reports = - -# Activate the evaluation score. -score = true - -[tool.pylint.similarities] -# Comments are removed from the similarity computation -ignore-comments = true - -# Docstrings are removed from the similarity computation -ignore-docstrings = true - -# Imports are removed from the similarity computation -# ignore-imports = - -# Signatures are removed from the similarity computation -# ignore-signatures = - -# Minimum lines number of a similarity. -min-similarity-lines = 4 - -[tool.pylint.spelling] -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions = 4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the 'python-enchant' package. -# spelling-dict = - -# List of comma separated words that should be considered directives if they -# appear at the beginning of a comment and should not be checked. -spelling-ignore-comment-directives = "fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:" - -# List of comma separated words that should not be checked. -# spelling-ignore-words = - -# A path to a file that contains the private dictionary; one word per line. -# spelling-private-dict-file = - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -# spelling-store-unknown-words = - -[tool.pylint.string] -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -# check-quote-consistency = - -# This flag controls whether the implicit-str-concat should generate a warning on -# implicit string concatenation in sequences defined over several lines. -# check-str-concat-over-line-jumps = - -[tool.pylint.typecheck] -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators = ["contextlib.contextmanager"] - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -# generated-members = - -# Tells whether missing members accessed in mixin class should be ignored. A -# class is considered mixin if its name matches the mixin-class-rgx option. -# Tells whether to warn about missing members when the owner of the attribute is -# inferred to be None. -ignore-none = true - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference can -# return multiple potential results while evaluating a Python object, but some -# branches might not be evaluated, which results in partial inference. In that -# case, it might be useful to still emit no-member and other checks for the rest -# of the inferred objects. -ignore-on-opaque-inference = true - -# List of symbolic message names to ignore for Mixin members. -ignored-checks-for-mixins = ["no-member", "not-async-context-manager", "not-context-manager", "attribute-defined-outside-init"] - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes = ["optparse.Values", "thread._local", "_thread._local"] - -# Show a hint with possible names when a member name was not found. The aspect of -# finding the hint is based on edit distance. -missing-member-hint = true - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance = 1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices = 1 - -# Regex pattern to define which classes are considered mixins. -mixin-class-rgx = ".*[Mm]ixin" - -# List of decorators that change the signature of a decorated function. -# signature-mutators = - -[tool.pylint.variables] -# List of additional names supposed to be defined in builtins. Remember that you -# should avoid defining new builtins when possible. -# additional-builtins = - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables = true - -# List of names allowed to shadow builtins -# allowed-redefined-builtins = - -# List of strings which can identify a callback function by name. A callback name -# must start or end with one of those strings. -callbacks = ["cb_", "_cb"] - -# A regular expression matching the name of dummy variables (i.e. expected to not -# be used). -dummy-variables-rgx = "_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_" - -# Argument names that match this expression will be ignored. Default to name with -# leading underscore. -ignored-argument-names = "_.*|^ignored_|^unused_" - -# Tells whether we should check for unused import in __init__ files. -# init-import = - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules = ["six.moves", "past.builtins", "future.builtins", "builtins", "io"] diff --git a/requirements/dev-black.txt b/requirements/dev-black.txt deleted file mode 100644 index 25b0593b7..000000000 --- a/requirements/dev-black.txt +++ /dev/null @@ -1 +0,0 @@ -black==23.7.0 diff --git a/requirements/dev-mypy.txt b/requirements/dev-mypy.txt index 8d1588dd2..4fc6daeb2 100644 --- a/requirements/dev-mypy.txt +++ b/requirements/dev-mypy.txt @@ -1,4 +1,4 @@ -mypy==1.9.0 +mypy==1.10.1 types-PyYAML docutils-stubs types-beautifulsoup4 diff --git a/requirements/dev-pylint.txt b/requirements/dev-pylint.txt deleted file mode 100644 index 4ee578b7c..000000000 --- a/requirements/dev-pylint.txt +++ /dev/null @@ -1,5 +0,0 @@ -pylint==3.0.3 - --r ./cpp.txt --r ./json.txt --r ../requirements.txt diff --git a/requirements/dev-ruff.txt b/requirements/dev-ruff.txt new file mode 100644 index 000000000..6d4c5a81a --- /dev/null +++ b/requirements/dev-ruff.txt @@ -0,0 +1 @@ +ruff==0.5.2 diff --git a/setup.py b/setup.py index 6eecd502c..16662087f 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import setuptools # pylint: disable=wrong-import-order +import setuptools import atexit import distutils.command.build @@ -163,7 +163,7 @@ def run(self): else: subprocess.call("npm i", shell=True, cwd=root_dir) res = subprocess.call(f"npm run {tgt}", shell=True, cwd=root_dir) - except: + except: # noqa: E722 raise RuntimeError("Could not run 'npm run %s'." % tgt) if res: diff --git a/sphinx_immaterial/__init__.py b/sphinx_immaterial/__init__.py index 2edfe1721..61c625715 100644 --- a/sphinx_immaterial/__init__.py +++ b/sphinx_immaterial/__init__.py @@ -19,9 +19,9 @@ from . import html_translator_mixin from .apidoc import apidoc_formatting -from .apidoc import fix_sphinx_issue_11147 # pylint: disable=unused-import +from .apidoc import fix_sphinx_issue_11147 # noqa: F401 from . import nav_adapt -from . import sections # pylint: disable=unused-import +from . import sections # noqa: F401 logger = sphinx.util.logging.getLogger(__name__) diff --git a/sphinx_immaterial/apidoc/apigen_utils.py b/sphinx_immaterial/apidoc/apigen_utils.py index 62e46d95e..427599ab4 100644 --- a/sphinx_immaterial/apidoc/apigen_utils.py +++ b/sphinx_immaterial/apidoc/apigen_utils.py @@ -37,7 +37,7 @@ def _is_generated_file(rst_path: str, initial_comment: str) -> bool: return False content = pathlib.Path(rst_path).read_text(encoding="utf-8") return content.startswith(initial_comment) - except: # pylint: disable=bare-except + except Exception: return False diff --git a/sphinx_immaterial/apidoc/cpp/api_parser.py b/sphinx_immaterial/apidoc/cpp/api_parser.py index 4ecde4a0f..279413985 100644 --- a/sphinx_immaterial/apidoc/cpp/api_parser.py +++ b/sphinx_immaterial/apidoc/cpp/api_parser.py @@ -73,7 +73,7 @@ import sphinx.util.logging from typing_extensions import NotRequired -from . import ast_fixes # pylint: disable=unused-import +from . import ast_fixes # noqa: F401 logger = sphinx.util.logging.getLogger(__name__) @@ -489,17 +489,17 @@ def _substitute_internal_type_names(config: Config, decl: str) -> str: def get_previous_line_location(tu, location: SourceLocation): - f = location.file + file = location.file line = location.line - return SourceLocation.from_position(tu, location.file, line - 1, 1) + return SourceLocation.from_position(tu, file, line - 1, 1) def get_presumed_location(location: SourceLocation) -> typing.Tuple[str, int, int]: - f, l, c = clang.cindex._CXString(), ctypes.c_uint(), ctypes.c_uint() + file, line, col = clang.cindex._CXString(), ctypes.c_uint(), ctypes.c_uint() clang.cindex.conf.lib.clang_getPresumedLocation( - location, ctypes.byref(f), ctypes.byref(l), ctypes.byref(c) + location, ctypes.byref(file), ctypes.byref(line), ctypes.byref(col) ) - return (clang.cindex._CXString.from_result(f), int(l.value), int(c.value)) + return (clang.cindex._CXString.from_result(file), int(line.value), int(col.value)) def _get_template_cursor_kind(cursor: Cursor) -> CursorKind: @@ -723,7 +723,6 @@ def get_extent_spelling(translation_unit: TranslationUnit, extent: SourceRange) def get_spellings(): prev_token = None COMMENT = TokenKind.COMMENT - spellings = [] for token in translation_unit.get_tokens(extent=extent): if prev_token is not None: yield prev_token.spelling @@ -1059,7 +1058,6 @@ def _transform_enum_decl(config: Config, decl: Cursor) -> EnumEntity: if token1_spelling in ("class", "struct"): keyword = cast(ClassKeyword, token1_spelling) - name = decl.spelling enumerators: List[EnumeratorEntity] = [] for child in decl.get_children(): if child.kind != CursorKind.ENUM_CONSTANT_DECL: @@ -1174,7 +1172,7 @@ def _maybe_wrap_requires_expr_in_parentheses(expr: str) -> str: parser.skip_ws() parser.assert_end() return expr - except: # pylint: disable=bare-except + except Exception: return f"({expr})" @@ -1583,7 +1581,7 @@ def _transform_cursor_to_json(self, decl: Cursor, parent: Optional[Cursor]): doc = None self._document_with_parent[entity_id] = document_with json_repr["document_with"] = document_with - extent = decl.extent + # extent = decl.extent json_repr["location"] = location nonitpick = get_nonitpick_directives(decl) if nonitpick: @@ -2175,7 +2173,7 @@ def _parse_entity_doc(entity: CppApiEntity): return False doc_text = doc["text"] for m in SPECIAL_GROUP_COMMAND_PATTERN.finditer(doc_text): - entity[cast(Literal["special_id"], "special_" + m.group(1))] = m.group( + entity[cast(Literal["special_id"], "special_" + m.group(1))] = m.group( # noqa: F821 2 ).strip() return True @@ -2382,7 +2380,7 @@ def generate_output(config: Config) -> JsonApiData: def _load_config(config_path: str) -> Config: config_content = pathlib.Path(config_path).read_text(encoding="utf-8") context: dict = {} - exec(config_content, context) # pylint: disable=exec-used + exec(config_content, context) config = context["config"] assert isinstance(config, Config) diff --git a/sphinx_immaterial/apidoc/cpp/ast_fixes.py b/sphinx_immaterial/apidoc/cpp/ast_fixes.py index a0c1f3867..dc29901b8 100644 --- a/sphinx_immaterial/apidoc/cpp/ast_fixes.py +++ b/sphinx_immaterial/apidoc/cpp/ast_fixes.py @@ -2,13 +2,13 @@ import sphinx -from . import ( # pylint: disable=unused-import +from . import ( # noqa: F401 fix_cpp_domain_symbol_resolution_through_type_aliases, ) if sphinx.version_info < (5, 2): - from . import fix_cpp_domain_requires_clause # pylint: disable=unused-import - from . import fix_cpp_is_pack # pylint: disable=unused-import - from . import ( # pylint: disable=unused-import + from . import fix_cpp_domain_requires_clause # noqa: F401 + from . import fix_cpp_is_pack # noqa: F401 + from . import ( # noqa: F401 fix_cpp_symbol_to_normalize_template_args, ) diff --git a/sphinx_immaterial/apidoc/cpp/cpp_resolve_c_xrefs.py b/sphinx_immaterial/apidoc/cpp/cpp_resolve_c_xrefs.py index 3799d0285..652b1e94b 100644 --- a/sphinx_immaterial/apidoc/cpp/cpp_resolve_c_xrefs.py +++ b/sphinx_immaterial/apidoc/cpp/cpp_resolve_c_xrefs.py @@ -11,7 +11,6 @@ `missing-reference` handlers from receiving them. """ - import re from typing import Optional, Tuple, List, cast @@ -25,8 +24,8 @@ # We monkey patch `resolve_xref` multiple times. We must call # `_monkey_patch_cpp_resolve_c_xrefs` last, to ensure that the other logic only # runs once. -from . import last_resolved_symbol # pylint: disable=unused-import -from . import synopses # pylint: disable=unused-import +from . import last_resolved_symbol # noqa: F401 +from . import synopses # noqa: F401 POSSIBLE_MACRO_TARGET_PATTERN = re.compile("^[A-Z]+[A-Z_0-9]*(?:::[a-zA-Z0-9_]+)?$") """Pattern for targets that may possibly refer to a macro or macro parameter. diff --git a/sphinx_immaterial/apidoc/cpp/default.py b/sphinx_immaterial/apidoc/cpp/default.py index 01e4f8249..dc3fb77db 100644 --- a/sphinx_immaterial/apidoc/cpp/default.py +++ b/sphinx_immaterial/apidoc/cpp/default.py @@ -1,15 +1,15 @@ import sphinx.application -from . import ast_fixes # pylint: disable=unused-import -from . import cpp_resolve_c_xrefs # pylint: disable=unused-import -from . import include_directives_in_signatures # pylint: disable=unused-import -from . import last_resolved_symbol # pylint: disable=unused-import -from . import macro_parameters # pylint: disable=unused-import -from . import parameter_objects # pylint: disable=unused-import -from . import signodes # pylint: disable=unused-import -from . import strip_namespaces_from_signatures # pylint: disable=unused-import -from . import symbol_ids # pylint: disable=unused-import -from . import synopses # pylint: disable=unused-import +from . import ast_fixes # noqa: F401 +from . import cpp_resolve_c_xrefs # noqa: F401 +from . import include_directives_in_signatures # noqa: F401 +from . import last_resolved_symbol # noqa: F401 +from . import macro_parameters # noqa: F401 +from . import parameter_objects # noqa: F401 +from . import signodes # noqa: F401 +from . import strip_namespaces_from_signatures # noqa: F401 +from . import symbol_ids # noqa: F401 +from . import synopses # noqa: F401 def setup(app: sphinx.application.Sphinx): diff --git a/sphinx_immaterial/apidoc/cpp/last_resolved_symbol.py b/sphinx_immaterial/apidoc/cpp/last_resolved_symbol.py index 12084272c..ec07c3e74 100644 --- a/sphinx_immaterial/apidoc/cpp/last_resolved_symbol.py +++ b/sphinx_immaterial/apidoc/cpp/last_resolved_symbol.py @@ -71,7 +71,14 @@ def find_declaration(self: Union[CSymbol, CPPSymbol], *args, **kwargs): try: return orig_resolve_xref_inner( - self, env, fromdocname, builder, typ, target, node, contnode # type: ignore + self, # type: ignore[arg-type] + env, + fromdocname, + builder, + typ, + target, + node, + contnode, # type: ignore ) finally: if orig_find_name: diff --git a/sphinx_immaterial/apidoc/cpp/parameter_objects.py b/sphinx_immaterial/apidoc/cpp/parameter_objects.py index 3b6d14eed..dc541d268 100644 --- a/sphinx_immaterial/apidoc/cpp/parameter_objects.py +++ b/sphinx_immaterial/apidoc/cpp/parameter_objects.py @@ -125,25 +125,25 @@ def get_precise_template_parameter_object_type( def _monkey_patch_cpp_add_precise_template_parameter_object_types(): """Adds more precise template{Type,NonType,Template}Param object types.""" - sphinx.domains.cpp.CPPDomain.object_types[ - "templateTypeParam" - ] = sphinx.domains.ObjType( - "type template parameter", - "identifier", - "class", - "struct", - "union", - "type", + sphinx.domains.cpp.CPPDomain.object_types["templateTypeParam"] = ( + sphinx.domains.ObjType( + "type template parameter", + "identifier", + "class", + "struct", + "union", + "type", + ) ) - sphinx.domains.cpp.CPPDomain.object_types[ - "templateNonTypeParam" - ] = sphinx.domains.ObjType( - "non-type template parameter", "identifier", "member", "var" + sphinx.domains.cpp.CPPDomain.object_types["templateNonTypeParam"] = ( + sphinx.domains.ObjType( + "non-type template parameter", "identifier", "member", "var" + ) ) - sphinx.domains.cpp.CPPDomain.object_types[ - "templateTemplateParam" - ] = sphinx.domains.ObjType( - "template template parameter", "identifier", "member", "var" + sphinx.domains.cpp.CPPDomain.object_types["templateTemplateParam"] = ( + sphinx.domains.ObjType( + "template template parameter", "identifier", "member", "var" + ) ) def get_objects( diff --git a/sphinx_immaterial/apidoc/cpp/signodes.py b/sphinx_immaterial/apidoc/cpp/signodes.py index 5f7b228a0..03f5c34f2 100644 --- a/sphinx_immaterial/apidoc/cpp/signodes.py +++ b/sphinx_immaterial/apidoc/cpp/signodes.py @@ -3,7 +3,6 @@ This allows other extensions to identify those elements more easily. """ - from typing import Type import docutils.nodes diff --git a/sphinx_immaterial/apidoc/cpp/symbol_ids.py b/sphinx_immaterial/apidoc/cpp/symbol_ids.py index c6e248e8a..89f03d3f1 100644 --- a/sphinx_immaterial/apidoc/cpp/symbol_ids.py +++ b/sphinx_immaterial/apidoc/cpp/symbol_ids.py @@ -122,7 +122,7 @@ def add_declaration(declaration, docname: str, line: int): other_symbol.remove() break else: - raise AssertionError( # pylint: disable=raise-missing-from + raise AssertionError( "Duplicate symbol not found: %r" % (symbol.dump(2),) ) return symbol diff --git a/sphinx_immaterial/apidoc/cpp/synopses.py b/sphinx_immaterial/apidoc/cpp/synopses.py index f3932109b..ccbbe850f 100644 --- a/sphinx_immaterial/apidoc/cpp/synopses.py +++ b/sphinx_immaterial/apidoc/cpp/synopses.py @@ -24,7 +24,7 @@ def set_synopsis( def _monkey_patch_add_object_type_and_synopsis( domain_class: Union[ Type[sphinx.domains.cpp.CPPDomain], Type[sphinx.domains.c.CDomain] - ] + ], ): """Patch C/C++ resolve_xref to add object type-dependent CSS classes.""" orig_resolve_xref_inner = domain_class._resolve_xref_inner @@ -40,7 +40,14 @@ def _resolve_xref_inner( contnode: docutils.nodes.Element, ) -> Tuple[Optional[docutils.nodes.Element], Optional[str]]: refnode, objtype = orig_resolve_xref_inner( - self, env, fromdocname, builder, typ, target, node, contnode # type: ignore + self, # type: ignore[arg-type] + env, + fromdocname, + builder, + typ, + target, + node, + contnode, # type: ignore ) if refnode is None: return refnode, objtype @@ -65,15 +72,15 @@ def _resolve_xref_inner( refnode["classes"].append("desctype") if last_symbol is not None: - refnode[ - "reftitle" - ] = object_description_options.format_object_description_tooltip( - env, - object_description_options.get_object_description_options( - env, self.name, objtype - ), - base_title=refnode["reftitle"], - synopsis=getattr(last_symbol.declaration, SYNOPSIS_ATTR, None), + refnode["reftitle"] = ( + object_description_options.format_object_description_tooltip( + env, + object_description_options.get_object_description_options( + env, self.name, objtype + ), + base_title=refnode["reftitle"], + synopsis=getattr(last_symbol.declaration, SYNOPSIS_ATTR, None), + ) ) return refnode, objtype @@ -82,7 +89,7 @@ def _resolve_xref_inner( def _monkey_patch_domain_get_object_synopses( - domain_class: Union[Type[CDomain], Type[CPPDomain]] + domain_class: Union[Type[CDomain], Type[CPPDomain]], ): def get_object_synopses( self: Union[CDomain, CPPDomain], diff --git a/sphinx_immaterial/apidoc/fix_sphinx_issue_11147.py b/sphinx_immaterial/apidoc/fix_sphinx_issue_11147.py index 6d7dd292f..d30e08cb6 100644 --- a/sphinx_immaterial/apidoc/fix_sphinx_issue_11147.py +++ b/sphinx_immaterial/apidoc/fix_sphinx_issue_11147.py @@ -28,7 +28,7 @@ def nested_parse_with_titles(state, content, node): return orig_nested_parse_with_titles(state, content, node) sphinx.util.nodes.nested_parse_with_titles = nested_parse_with_titles # type: ignore[assignment] - sphinx.directives.nested_parse_with_titles = nested_parse_with_titles # type: ignore[assignment] + sphinx.directives.nested_parse_with_titles = nested_parse_with_titles # type: ignore[assignment,attr-defined] _monkey_patch_nested_parse_with_titles() diff --git a/sphinx_immaterial/apidoc/format_signatures.py b/sphinx_immaterial/apidoc/format_signatures.py index b0fbda06d..88f485985 100644 --- a/sphinx_immaterial/apidoc/format_signatures.py +++ b/sphinx_immaterial/apidoc/format_signatures.py @@ -228,7 +228,7 @@ def process(node: docutils.nodes.Node): _extend_children_copy_source_info(node, child, process(child)) if name_text_node_replacement is not None: - ( # pylint: disable=unpacking-non-sequence + ( existing_node, new_node, ) = name_text_node_replacement diff --git a/sphinx_immaterial/apidoc/json/domain.py b/sphinx_immaterial/apidoc/json/domain.py index d9758a37c..f5112fe54 100644 --- a/sphinx_immaterial/apidoc/json/domain.py +++ b/sphinx_immaterial/apidoc/json/domain.py @@ -41,7 +41,7 @@ import sphinx.util.logging import sphinx.util.matching from sphinx.locale import _ -import yaml # pylint: disable=import-error +import yaml from .. import object_description_options from . import json_pprint @@ -217,7 +217,7 @@ def get_location_from_schema_string( return "%s:" % (filename,) -def yaml_load( # pylint: disable=invalid-name +def yaml_load( stream, source_path: str, ) -> Tuple[Any, YamlSourceInfoMap]: @@ -1148,7 +1148,7 @@ def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]: else OBJECT_PRIORITY_UNIMPORTANT, ) - def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: # pylint: disable=g-bare-generic + def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: self.schemas.update(otherdata["schemas"]) def _find_schema( diff --git a/sphinx_immaterial/apidoc/object_description_options.py b/sphinx_immaterial/apidoc/object_description_options.py index 240232e95..d4acc7919 100644 --- a/sphinx_immaterial/apidoc/object_description_options.py +++ b/sphinx_immaterial/apidoc/object_description_options.py @@ -188,7 +188,7 @@ def _builder_inited(app: sphinx.application.Sphinx) -> None: options[name] = pydantic.TypeAdapter( registered_option.type_constraint ).validate_python(value) - except Exception as e: # pylint: disable=broad-except + except Exception as e: logger.error( "Invalid value %r for object description option" " %r specified for pattern %r: %s", diff --git a/sphinx_immaterial/apidoc/object_toc.py b/sphinx_immaterial/apidoc/object_toc.py index 90c29bdea..5c6b431b7 100644 --- a/sphinx_immaterial/apidoc/object_toc.py +++ b/sphinx_immaterial/apidoc/object_toc.py @@ -73,7 +73,7 @@ def _make_section_from_field( source: docutils.nodes.field, ) -> Optional[docutils.nodes.section]: fieldname = cast(docutils.nodes.field_name, source[0]) - fieldbody = cast(docutils.nodes.field_body, source[1]) + # fieldbody = cast(docutils.nodes.field_body, source[1]) ids = fieldname["ids"] if not ids: # Not indexed diff --git a/sphinx_immaterial/apidoc/python/apigen.py b/sphinx_immaterial/apidoc/python/apigen.py index 0d1c01af1..23e0f3978 100644 --- a/sphinx_immaterial/apidoc/python/apigen.py +++ b/sphinx_immaterial/apidoc/python/apigen.py @@ -61,7 +61,7 @@ stringify_annotation = sphinx.util.typing.stringify # type: ignore[attr-defined] if sphinx.version_info >= (7, 3): - from sphinx.domains.python._annotations import _parse_annotation # type: ignore[import-not-found] # pylint: disable=import-error,no-name-in-module + from sphinx.domains.python._annotations import _parse_annotation # type: ignore[import-not-found] else: from sphinx.domains.python import _parse_annotation @@ -883,7 +883,7 @@ def run(self) -> List[docutils.nodes.Node]: top_level_groups = data.top_level_groups group_id = docutils.nodes.make_id(self.arguments[0]) - members = data.top_level_groups.get(group_id) + members = top_level_groups.get(group_id) if members is None: logger.warning( @@ -1374,7 +1374,7 @@ def _get_unseen_members( ), is_inherited=True, ) - except Exception as e: # pylint: disable=broad-except + except Exception as e: logger.warning( "Cannot obtain documenter for base class %r of %r: %r", cls, @@ -1487,8 +1487,10 @@ def collect_entity_recursively( if isinstance(entry.documenter, sphinx.ext.autodoc.ClassDocumenter): canonical_full_name = entry.documenter.get_canonical_fullname() elif isinstance(entry.documenter, sphinx.ext.autodoc.FunctionDocumenter): - canonical_full_name = sphinx.ext.autodoc.ClassDocumenter.get_canonical_fullname( - entry.documenter # type: ignore[arg-type] + canonical_full_name = ( + sphinx.ext.autodoc.ClassDocumenter.get_canonical_fullname( + entry.documenter # type: ignore[arg-type] + ) ) if canonical_full_name is None: canonical_full_name = f"{entry.parent_canonical_full_name}.{entry.name}" @@ -1854,15 +1856,13 @@ def _monkey_patch_napoleon_to_add_group_field(): """ orig_load_custom_sections = ( sphinx.ext.napoleon.docstring.GoogleDocstring._load_custom_sections - ) # pylint: disable=protected-access + ) def parse_section( self: sphinx.ext.napoleon.docstring.GoogleDocstring, section: str ) -> List[str]: - lines = self._strip_empty( - self._consume_to_next_section() - ) # pylint: disable=protected-access - lines = self._dedent(lines) # pylint: disable=protected-access + lines = self._strip_empty(self._consume_to_next_section()) + lines = self._dedent(lines) name = section.lower() if len(lines) != 1: raise ValueError(f"Expected exactly one {name} in {section} section") @@ -1872,15 +1872,11 @@ def load_custom_sections( self: sphinx.ext.napoleon.docstring.GoogleDocstring, ) -> None: orig_load_custom_sections(self) - self._sections["group"] = lambda section: parse_section( - self, section - ) # pylint: disable=protected-access - self._sections["order"] = lambda section: parse_section( - self, section - ) # pylint: disable=protected-access + self._sections["group"] = lambda section: parse_section(self, section) + self._sections["order"] = lambda section: parse_section(self, section) sphinx.ext.napoleon.docstring.GoogleDocstring._load_custom_sections = ( # type: ignore[assignment] - load_custom_sections # pylint: disable=protected-access + load_custom_sections ) diff --git a/sphinx_immaterial/apidoc/python/attribute_style.py b/sphinx_immaterial/apidoc/python/attribute_style.py index 8540d10eb..030cffd1e 100644 --- a/sphinx_immaterial/apidoc/python/attribute_style.py +++ b/sphinx_immaterial/apidoc/python/attribute_style.py @@ -6,7 +6,7 @@ import sphinx.domains.python if sphinx.version_info >= (7, 3): - from sphinx.domains.python._annotations import _parse_annotation # type: ignore[import-not-found] # pylint: disable=import-error,no-name-in-module + from sphinx.domains.python._annotations import _parse_annotation # type: ignore[import-not-found] else: from sphinx.domains.python import _parse_annotation diff --git a/sphinx_immaterial/apidoc/python/autodoc_property_type.py b/sphinx_immaterial/apidoc/python/autodoc_property_type.py index 9cf385665..af078e79f 100644 --- a/sphinx_immaterial/apidoc/python/autodoc_property_type.py +++ b/sphinx_immaterial/apidoc/python/autodoc_property_type.py @@ -1,5 +1,6 @@ """Adds support for obtaining property types from docstring signatures, and improves formatting by PyProperty of type annotations.""" + import re from typing import Tuple, Optional, Any @@ -70,7 +71,7 @@ def import_object(self: PropertyDocumenter, raiseerror: bool = False) -> bool: ): self.retann = stringify_annotation(signature.return_annotation) return True - except: # pylint: disable=bare-except + except Exception: pass if not self.retann: diff --git a/sphinx_immaterial/apidoc/python/default.py b/sphinx_immaterial/apidoc/python/default.py index 4b501aa02..4cfe79403 100644 --- a/sphinx_immaterial/apidoc/python/default.py +++ b/sphinx_immaterial/apidoc/python/default.py @@ -1,21 +1,21 @@ import sphinx import sphinx.application -from . import annotation_style # pylint: disable=unused-import -from . import object_ids # pylint: disable=unused-import -from . import synopses # pylint: disable=unused-import +from . import annotation_style # noqa: F401 +from . import object_ids # noqa: F401 +from . import synopses # noqa: F401 from . import parameter_objects -from . import style_default_values_as_code # pylint: disable=unused-import -from . import subscript_methods # pylint: disable=unused-import -from . import attribute_style # pylint: disable=unused-import -from . import napoleon_admonition_classes # pylint: disable=unused-import +from . import style_default_values_as_code # noqa: F401 +from . import subscript_methods # noqa: F401 +from . import attribute_style # noqa: F401 +from . import napoleon_admonition_classes # noqa: F401 from . import strip_property_prefix -from . import autodoc_property_type # pylint: disable=unused-import +from . import autodoc_property_type # noqa: F401 from . import type_annotation_transforms from . import strip_self_and_return_type_annotations if sphinx.version_info < (5, 3): - from . import section_titles # pylint: disable=unused-import + from . import section_titles # noqa: F401 def setup(app: sphinx.application.Sphinx): diff --git a/sphinx_immaterial/apidoc/python/domain_fixes.py b/sphinx_immaterial/apidoc/python/domain_fixes.py index 838cea590..ed38ad8f8 100644 --- a/sphinx_immaterial/apidoc/python/domain_fixes.py +++ b/sphinx_immaterial/apidoc/python/domain_fixes.py @@ -12,7 +12,7 @@ import sphinx.util.logging import sphinx.util.nodes -from . import autodoc_property_type # pylint: disable=unused-import +from . import autodoc_property_type # noqa: F401 PythonDomain = sphinx.domains.python.PythonDomain PyTypedField = sphinx.domains.python.PyTypedField diff --git a/sphinx_immaterial/apidoc/python/object_ids.py b/sphinx_immaterial/apidoc/python/object_ids.py index 698650eb6..e6435374a 100644 --- a/sphinx_immaterial/apidoc/python/object_ids.py +++ b/sphinx_immaterial/apidoc/python/object_ids.py @@ -96,7 +96,6 @@ def strip_object_entry_node_id(existing_node_id: str, object_id: str): nonodeid = "nonodeid" in self.options canonical_name = self.options.get("canonical") noindexentry = "noindexentry" in self.options - noindex = "noindex" in self.options for signode in cast(List[docutils.nodes.Element], signodes): modname = signode["module"] @@ -117,9 +116,9 @@ def strip_object_entry_node_id(existing_node_id: str, object_id: str): if new_entry[2] == orig_node_id: new_entry[2] = "" new_entries.append(tuple(new_entry)) - cast(docutils.nodes.Element, self.indexnode)[ - "entries" - ] = new_entries + cast(docutils.nodes.Element, self.indexnode)["entries"] = ( + new_entries + ) PyObject.after_content = after_content # type: ignore[assignment] diff --git a/sphinx_immaterial/apidoc/python/parameter_objects.py b/sphinx_immaterial/apidoc/python/parameter_objects.py index 4fde71bbf..8543e786d 100644 --- a/sphinx_immaterial/apidoc/python/parameter_objects.py +++ b/sphinx_immaterial/apidoc/python/parameter_objects.py @@ -471,8 +471,6 @@ def after_content(self: PyObject) -> None: ).parent signodes = obj_desc.children[:-1] - py = cast(PythonDomain, self.env.get_domain("py")) - noindex = "noindex" in self.options symbols = [] diff --git a/sphinx_immaterial/apidoc/python/synopses.py b/sphinx_immaterial/apidoc/python/synopses.py index 19461596b..b7f262afe 100644 --- a/sphinx_immaterial/apidoc/python/synopses.py +++ b/sphinx_immaterial/apidoc/python/synopses.py @@ -21,15 +21,15 @@ def _add_synopsis( obj = self.objects.get(name) if obj is None: return - refnode[ - "reftitle" - ] = object_description_options.format_object_description_tooltip( - env, - object_description_options.get_object_description_options( - env, self.name, obj.objtype - ), - base_title=name, - synopsis=self.data["synopses"].get(name), + refnode["reftitle"] = ( + object_description_options.format_object_description_tooltip( + env, + object_description_options.get_object_description_options( + env, self.name, obj.objtype + ), + base_title=name, + synopsis=self.data["synopses"].get(name), + ) ) orig_resolve_xref = PythonDomain.resolve_xref diff --git a/sphinx_immaterial/code_annotations.py b/sphinx_immaterial/code_annotations.py index 8037f6e43..f6cfdde9d 100644 --- a/sphinx_immaterial/code_annotations.py +++ b/sphinx_immaterial/code_annotations.py @@ -1,6 +1,7 @@ """Adds a new directive for using upstream's code annotations feature. See comments in visit_literal_block() override below for detailed explanation about why this directive is needed.""" + from typing import List, cast from docutils import nodes from sphinx.application import Sphinx diff --git a/sphinx_immaterial/content_tabs.py b/sphinx_immaterial/content_tabs.py index 7f3f4ccd0..6c5cb27b4 100644 --- a/sphinx_immaterial/content_tabs.py +++ b/sphinx_immaterial/content_tabs.py @@ -1,6 +1,7 @@ """ A special theme-specific extension to support "content tabs" from mkdocs-material. """ + from typing import List from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_immaterial/custom_admonitions.py b/sphinx_immaterial/custom_admonitions.py index 89ec1c424..ac451cfb7 100644 --- a/sphinx_immaterial/custom_admonitions.py +++ b/sphinx_immaterial/custom_admonitions.py @@ -1,5 +1,6 @@ """This module inherits from the generic ``admonition`` directive and makes the title optional.""" + from abc import ABC from pathlib import PurePath import re @@ -19,7 +20,6 @@ from sphinx.locale import admonitionlabels, _ from sphinx.util.logging import getLogger from sphinx.writers.html5 import HTML5Translator -from typing_extensions import Annotated from .css_and_javascript_bundles import add_global_css from .inline_icons import load_svg_into_builder_env, get_custom_icons from . import html_translator_mixin @@ -43,8 +43,6 @@ _CUSTOM_ADMONITIONS_KEY = "sphinx_immaterial_custom_admonitions" -CSSClassType = Annotated[str, pydantic.AfterValidator(nodes.make_id)] - # defaults used for version directives re-styling VERSION_DIR_STYLE = { "versionadded": { @@ -79,7 +77,7 @@ class CustomAdmonitionConfig(pydantic.BaseModel): """The required name of the directive. This will be also used as a CSS class name. This value shall have characters that match the regular expression pattern ``[a-zA-Z0-9_-]``.""" - title: Annotated[Optional[str], pydantic.Field(validate_default=True)] = None + title: Optional[str] = pydantic.Field(default=None, validate_default=True) """The default title to use when rendering the custom admonition. If this is not specified, then the `name` value is converted and used.""" icon: Optional[str] = None @@ -106,7 +104,7 @@ class CustomAdmonitionConfig(pydantic.BaseModel): .. note:: Any specified transparency (alpha value) is ignored. """ - classes: List[CSSClassType] = [] + classes: List[str] = [] """If specified, this list of qualified names will be added to every rendered admonition (specific to the generated directive) element's ``class`` attribute. @@ -147,8 +145,17 @@ def validate_title(cls, val, info: pydantic.ValidationInfo): val = " ".join( re.split(r"[\-_]+", cast(str, info.data.get("name"))) ).title() + return val + @pydantic.field_validator("classes") + @classmethod + def validate_classes(cls, val): + validated = [] + for c in val: + validated.append(nodes.make_id(c)) + return validated + def visit_collapsible(self: HTML5Translator, node: nodes.Element, flag: str): tag_extra_args: Dict[str, Any] = {"CLASS": "admonition"} diff --git a/sphinx_immaterial/default_literal_role.py b/sphinx_immaterial/default_literal_role.py index fe08da823..325077a70 100644 --- a/sphinx_immaterial/default_literal_role.py +++ b/sphinx_immaterial/default_literal_role.py @@ -20,7 +20,10 @@ def nodeclass(rawsource: str, text: str): nodeclass.__name__ = "literal" before, inlines, remaining, sysmessages, endstring = self.inline_obj( - match, lineno, self.patterns.literal, nodeclass # type: ignore[arg-type] + match, + lineno, + self.patterns.literal, + nodeclass, # type: ignore[arg-type] ) if len(inlines) == 1 and isinstance(inlines[0], tuple): diff --git a/sphinx_immaterial/external_resource_cache.py b/sphinx_immaterial/external_resource_cache.py index 2c51e89ed..ac9ff14af 100644 --- a/sphinx_immaterial/external_resource_cache.py +++ b/sphinx_immaterial/external_resource_cache.py @@ -30,9 +30,7 @@ def get_url( pass logger.info("Fetching: %s with %r", url, headers) - r = requests.get( # pylint: disable=missing-timeout - url, headers=headers, stream=True - ) + r = requests.get(url, headers=headers, stream=True) r.raise_for_status() response_content = r.content diff --git a/sphinx_immaterial/html_translator_mixin.py b/sphinx_immaterial/html_translator_mixin.py index 4ba5744f1..e74c89832 100644 --- a/sphinx_immaterial/html_translator_mixin.py +++ b/sphinx_immaterial/html_translator_mixin.py @@ -15,7 +15,7 @@ HTMLTranslatorMixinBase = object -class HTMLTranslatorMixin(HTMLTranslatorMixinBase): # pylint: disable=abstract-method +class HTMLTranslatorMixin(HTMLTranslatorMixinBase): pass @@ -72,8 +72,9 @@ def get_html_translator( base_translator: Type[sphinx.writers.html5.HTML5Translator], ) -> Type[sphinx.writers.html5.HTML5Translator]: class CustomHTMLTranslator( - HTMLTranslatorMixin, base_translator # type: ignore - ): # pylint: disable=abstract-method + HTMLTranslatorMixin, + base_translator, # type: ignore + ): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/sphinx_immaterial/inline_icons.py b/sphinx_immaterial/inline_icons.py index 50e905a43..ca2974289 100644 --- a/sphinx_immaterial/inline_icons.py +++ b/sphinx_immaterial/inline_icons.py @@ -1,6 +1,7 @@ """This module adds the md-icon role. This is specific to this this theme because, primarily, the icons bundled with this theme are supported (plus any svg files in the user project's static directories).""" + from pathlib import Path from typing import Tuple, List, Dict diff --git a/sphinx_immaterial/local_mathjax.py b/sphinx_immaterial/local_mathjax.py index 22d496f8c..7c97482ca 100644 --- a/sphinx_immaterial/local_mathjax.py +++ b/sphinx_immaterial/local_mathjax.py @@ -10,8 +10,7 @@ def copy_mathjax_dist(app: Sphinx, env: BuildEnvironment) -> None: if ( - app.builder.format != "html" - or app.builder.math_renderer_name != "mathjax" # type: ignore[attr-defined] + app.builder.format != "html" or app.builder.math_renderer_name != "mathjax" # type: ignore[attr-defined] ): return if not app.config.mathjax_path: diff --git a/sphinx_immaterial/mermaid_diagrams.py b/sphinx_immaterial/mermaid_diagrams.py index 315f28001..83694f7e4 100644 --- a/sphinx_immaterial/mermaid_diagrams.py +++ b/sphinx_immaterial/mermaid_diagrams.py @@ -1,4 +1,5 @@ """A custom directive that allows using mermaid diagrams""" + from pathlib import Path import shutil from typing import List diff --git a/sphinx_immaterial/nav_adapt.py b/sphinx_immaterial/nav_adapt.py index 414c7a87c..ec6340f82 100644 --- a/sphinx_immaterial/nav_adapt.py +++ b/sphinx_immaterial/nav_adapt.py @@ -162,7 +162,7 @@ if sphinx.version_info >= (6,): meta_node_types = (docutils.nodes.meta,) # type: ignore[attr-defined] else: - from sphinx.addnodes import ( # type: ignore[attr-defined] # pylint: disable=no-name-in-module + from sphinx.addnodes import ( # type: ignore[attr-defined] docutils_meta, meta as sphinx_meta, ) diff --git a/sphinx_immaterial/postprocess_html.py b/sphinx_immaterial/postprocess_html.py index 4f57ba899..c8f4b655d 100644 --- a/sphinx_immaterial/postprocess_html.py +++ b/sphinx_immaterial/postprocess_html.py @@ -40,8 +40,9 @@ def create_sitemap(app: sphinx.application.Sphinx, exception): filename = str(app.outdir) + "/sitemap.xml" print( - "Generating sitemap for {0} pages in " - "{1}".format(len(sitemap_links), sphinx.util.console.colorize("blue", filename)) + "Generating sitemap for {0} pages in {1}".format( + len(sitemap_links), sphinx.util.console.colorize("blue", filename) + ) ) root = ElementTree.Element("urlset") diff --git a/sphinx_immaterial/search_adapt.py b/sphinx_immaterial/search_adapt.py index 55966da01..8f745ec25 100644 --- a/sphinx_immaterial/search_adapt.py +++ b/sphinx_immaterial/search_adapt.py @@ -86,7 +86,6 @@ def get_objects( # type: ignore[override] objtype_entry = onames[typeindex] domain_name = objtype_entry[0] objtype = objtype_entry[1] - domain = self.env.domains[domain_name] docname = docindex_to_docname.get(docindex) @@ -163,7 +162,9 @@ def freeze(self): return result def load( - self, stream: IO, format: Any # pylint: disable=redefined-builtin + self, + stream: IO, + format: Any, ) -> None: if isinstance(format, str): format = self.formats[format] diff --git a/sphinx_immaterial/sphinx_utils.py b/sphinx_immaterial/sphinx_utils.py index 9b6122bed..7960616f8 100644 --- a/sphinx_immaterial/sphinx_utils.py +++ b/sphinx_immaterial/sphinx_utils.py @@ -59,9 +59,9 @@ def format_directive( out.write(prefix + signature + "\n") if options: for key, value in options.items(): - if value is False or value is None: # pylint: disable=g-bool-id-comparison + if value is False or value is None: continue - if value is True: # pylint: disable=g-bool-id-comparison + if value is True: value = "" out.write(f" :{key}: {value}\n") if content: @@ -110,9 +110,9 @@ def append_directive_to_stringlist( content_indent_str = base_indent_str + " " if options: for key, value in options.items(): - if value is False or value is None: # pylint: disable=g-bool-id-comparison + if value is False or value is None: continue - if value is True: # pylint: disable=g-bool-id-comparison + if value is True: value = "" out.append(f"{content_indent_str}:{key}: {value}", source_path, source_line) if content is not None: diff --git a/sphinx_immaterial/task_lists.py b/sphinx_immaterial/task_lists.py index d9092dad3..dce2b93e2 100644 --- a/sphinx_immaterial/task_lists.py +++ b/sphinx_immaterial/task_lists.py @@ -1,4 +1,5 @@ """A custom directive that allows using checkboxes for lists""" + from typing import List from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_immaterial/theme_result.py b/sphinx_immaterial/theme_result.py index bc5c9b404..2c47c9328 100644 --- a/sphinx_immaterial/theme_result.py +++ b/sphinx_immaterial/theme_result.py @@ -1,4 +1,5 @@ """A directive designed to reduce example snippets duplication.""" + from pathlib import PurePath from docutils.parsers.rst import directives from docutils import nodes diff --git a/tests/code_annotations_test.py b/tests/code_annotations_test.py index d703b0626..19dc938f4 100644 --- a/tests/code_annotations_test.py +++ b/tests/code_annotations_test.py @@ -31,6 +31,7 @@ def test_code_annotation(immaterial_make_app): app.build() assert not app._warning.getvalue() # type: ignore[attr-defined] + def test_code_annotation_error(immaterial_make_app): app: SphinxTestApp = immaterial_make_app( files={ @@ -41,7 +42,8 @@ def test_code_annotation_error(immaterial_make_app): .. code-annotations:: This is not an enumerated list! -"""}, +""" + }, ) app.build() diff --git a/tests/content_tabs_test.py b/tests/content_tabs_test.py index e64be1633..986a96fe4 100644 --- a/tests/content_tabs_test.py +++ b/tests/content_tabs_test.py @@ -30,9 +30,11 @@ def test_content_tabs(immaterial_make_app): app.build() assert not app._warning.getvalue() # type: ignore[attr-defined] + def test_tab_ext_error(): assert not is_md_tab_type(Node(), "") + def test_tab_set_child_error(immaterial_make_app): app: SphinxTestApp = immaterial_make_app( files={ @@ -43,7 +45,8 @@ def test_tab_set_child_error(immaterial_make_app): .. md-tab-set:: This is not a ``md-tab-item``! -"""}, +""" + }, ) with pytest.raises(ValueError): @@ -52,6 +55,7 @@ def test_tab_set_child_error(immaterial_make_app): assert warnings assert "All children of a 'md-tab-set' should be 'md-tab-item'" in warnings + def test_tab_item_parent_error(immaterial_make_app): app: SphinxTestApp = immaterial_make_app( files={ @@ -62,7 +66,8 @@ def test_tab_item_parent_error(immaterial_make_app): .. md-tab-item:: Orphan This is ``md-tab-item`` has no parent ``md-tab-set``! -"""}, +""" + }, ) app.build() warnings = app._warning.getvalue() # type: ignore[attr-defined] diff --git a/tests/graphviz_test.py b/tests/graphviz_test.py index 0827b5c5f..b8a94bdff 100644 --- a/tests/graphviz_test.py +++ b/tests/graphviz_test.py @@ -1,4 +1,5 @@ """Tests related to theme's patched graphviz ext.""" + import pytest from sphinx.testing.util import SphinxTestApp @@ -50,9 +51,7 @@ def test_square_brackets(immaterial_make_app, graph: str): A graph ------- -{}""".format( - graph - ) +{}""".format(graph) }, ) diff --git a/tests/issue_134/issue_134_test.py b/tests/issue_134/issue_134_test.py index c89efc607..230adad5c 100644 --- a/tests/issue_134/issue_134_test.py +++ b/tests/issue_134/issue_134_test.py @@ -1,5 +1,5 @@ -"""Test specific to https://github.com/jbms/sphinx-immaterial/issues/134 -""" +"""Test specific to https://github.com/jbms/sphinx-immaterial/issues/134""" + from typing import List import pytest from sphinx.testing.util import SphinxTestApp diff --git a/tests/python_apigen_test_modules/issue147.py b/tests/python_apigen_test_modules/issue147.py index a10c05710..4420ef5b6 100644 --- a/tests/python_apigen_test_modules/issue147.py +++ b/tests/python_apigen_test_modules/issue147.py @@ -1,2 +1,2 @@ -from ._alpha import Alpha -from ._bravo import Bravo +from ._alpha import Alpha # noqa: F401 +from ._bravo import Bravo # noqa: F401 diff --git a/tests/search_index_test.py b/tests/search_index_test.py index 9c390ee0b..b3ca91d1b 100644 --- a/tests/search_index_test.py +++ b/tests/search_index_test.py @@ -1,4 +1,3 @@ -import json import os import pathlib diff --git a/tests/system_fonts_test.py b/tests/system_fonts_test.py index 00d2b97b4..11a04dae6 100644 --- a/tests/system_fonts_test.py +++ b/tests/system_fonts_test.py @@ -1,4 +1,5 @@ """Tests related to theme's patched graphviz ext.""" + from sphinx.testing.util import SphinxTestApp diff --git a/typings_py/pymdownx/keymap_db.pyi b/typings_py/pymdownx/keymap_db.pyi index 64e1a0281..34e838736 100644 --- a/typings_py/pymdownx/keymap_db.pyi +++ b/typings_py/pymdownx/keymap_db.pyi @@ -1,6 +1,7 @@ """ This type stub file was generated by pyright. """ + from typing import Dict keymap: Dict[str, str] = ...