Skip to content

Commit 252ed89

Browse files
authored
Extend linter/formatter rules (#427)
1 parent 124fde4 commit 252ed89

File tree

9 files changed

+64
-61
lines changed

9 files changed

+64
-61
lines changed

pyproject.toml

+22-12
Original file line numberDiff line numberDiff line change
@@ -71,27 +71,37 @@ line-length = 120
7171
line-length = 120
7272
target-version = "py37"
7373
lint.select = ["ALL"]
74-
lint.isort = {known-first-party = ["sphinx_autodoc_typehints", "tests"], required-imports = ["from __future__ import annotations"]}
74+
lint.isort = { known-first-party = [
75+
"sphinx_autodoc_typehints",
76+
"tests",
77+
], required-imports = [
78+
"from __future__ import annotations",
79+
] }
7580
lint.ignore = [
76-
"ANN101", # no type annotation for self
77-
"ANN401", # allow Any as type annotation
78-
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
79-
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
80-
"S104", # Possible binding to all interface
81+
"ANN101", # no type annotation for self
82+
"ANN401", # allow Any as type annotation
83+
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
84+
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
85+
"S104", # Possible binding to all interface
8186
"COM812", # Conflict with formatter
8287
"ISC001", # Conflict with formatter
8388
"CPY", # No copyright statements
8489
]
90+
lint.preview = true
91+
format.preview = true
92+
format.docstring-code-format = true
93+
format.docstring-code-line-length = 100
8594
[tool.ruff.lint.per-file-ignores]
8695
"tests/**/*.py" = [
87-
"S101", # asserts allowed in tests...
88-
"FBT", # don"t care about booleans as positional arguments in tests
89-
"INP001", # no implicit namespace
90-
"D", # don't care about documentation in tests
91-
"S603", # `subprocess` call: check for execution of untrusted input
92-
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
96+
"S101", # asserts allowed in tests...
97+
"FBT", # don"t care about booleans as positional arguments in tests
98+
"INP001", # no implicit namespace
99+
"D", # don't care about documentation in tests
100+
"S603", # `subprocess` call: check for execution of untrusted input
101+
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
93102
"PLR0913", # any number of arguments in tests
94103
"PLR0917", # any number of arguments in tests
104+
"PLC2701", # private imports
95105
]
96106

97107
[tool.codespell]

src/sphinx_autodoc_typehints/__init__.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def get_annotation_module(annotation: Any) -> str:
6767
if (
6868
is_new_type
6969
or isinstance(annotation, TypeVar)
70-
or type(annotation).__name__ in ("ParamSpec", "ParamSpecArgs", "ParamSpecKwargs")
70+
or type(annotation).__name__ in {"ParamSpec", "ParamSpecArgs", "ParamSpecKwargs"}
7171
):
7272
return "typing"
7373
if hasattr(annotation, "__module__"):
@@ -107,7 +107,7 @@ def get_annotation_class_name(annotation: Any, module: str) -> str: # noqa: C90
107107
return annotation.__qualname__ # type: ignore[no-any-return]
108108
if getattr(annotation, "_name", None): # Required for generic aliases on Python 3.7+
109109
return annotation._name # type: ignore[no-any-return] # noqa: SLF001
110-
if module in ("typing", "typing_extensions") and isinstance(getattr(annotation, "name", None), str):
110+
if module in {"typing", "typing_extensions"} and isinstance(getattr(annotation, "name", None), str):
111111
# Required for at least Pattern and Match
112112
return annotation.name # type: ignore[no-any-return]
113113

@@ -140,7 +140,7 @@ def get_annotation_args(annotation: Any, module: str, class_name: str) -> tuple[
140140
return () # This is the original, not parametrized type
141141

142142
# Special cases
143-
if class_name in ("Pattern", "Match") and hasattr(annotation, "type_var"): # Python < 3.7
143+
if class_name in {"Pattern", "Match"} and hasattr(annotation, "type_var"): # Python < 3.7
144144
return (annotation.type_var,)
145145
if class_name == "ClassVar" and hasattr(annotation, "__type__"): # ClassVar on Python < 3.7
146146
return (annotation.__type__,)
@@ -169,7 +169,7 @@ def format_internal_tuple(t: tuple[Any, ...], config: Config) -> str:
169169
return f"({', '.join(fmt)})"
170170

171171

172-
def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PLR0911, PLR0912, PLR0915
172+
def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PLR0911, PLR0912, PLR0915, PLR0914
173173
"""
174174
Format the annotation.
175175
@@ -238,7 +238,7 @@ def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PL
238238
formatted_args = None if args else args_format
239239
elif full_name == "typing.Optional":
240240
args = tuple(x for x in args if x is not type(None))
241-
elif full_name in ("typing.Union", "types.UnionType") and type(None) in args:
241+
elif full_name in {"typing.Union", "types.UnionType"} and type(None) in args:
242242
if len(args) == 2: # noqa: PLR2004
243243
full_name = "typing.Optional"
244244
role = "data"
@@ -250,7 +250,7 @@ def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901, PL
250250
role = "data"
251251
args_format = f"\\[:py:data:`{prefix}typing.Union`\\[{{}}]]"
252252
args = tuple(x for x in args if x is not type(None))
253-
elif full_name in ("typing.Callable", "collections.abc.Callable") and args and args[0] is not ...:
253+
elif full_name in {"typing.Callable", "collections.abc.Callable"} and args and args[0] is not ...:
254254
fmt = [format_annotation(arg, config) for arg in args]
255255
formatted_args = f"\\[\\[{', '.join(fmt[:-1])}], {fmt[-1]}]"
256256
elif full_name == "typing.Literal":
@@ -316,7 +316,7 @@ def remove_prefix(text: str, prefix: str) -> str:
316316
return "\n".join(aligned_prefix + aligned_suffix)
317317

318318

319-
def process_signature( # noqa: C901, PLR0913
319+
def process_signature( # noqa: C901, PLR0913, PLR0917
320320
app: Sphinx,
321321
what: str,
322322
name: str,
@@ -541,7 +541,7 @@ def _one_child(module: Module) -> stmt | None:
541541
comment_args = split_type_comment_args(comment_args_str)
542542
is_inline = len(comment_args) == 1 and comment_args[0] == "..."
543543
if not is_inline:
544-
if args and args[0].arg in ("self", "cls") and len(comment_args) != len(args):
544+
if args and args[0].arg in {"self", "cls"} and len(comment_args) != len(args):
545545
comment_args.insert(0, None) # self/cls may be omitted in type comments, insert blank
546546

547547
if len(args) != len(comment_args):
@@ -590,9 +590,9 @@ def add(val: str) -> None:
590590

591591
brackets, start_arg_at, at = 0, 0, 0
592592
for at, char in enumerate(comment):
593-
if char in ("[", "("):
593+
if char in {"[", "("}:
594594
brackets += 1
595-
elif char in ("]", ")"):
595+
elif char in {"]", ")"}:
596596
brackets -= 1
597597
elif char == "," and brackets == 0:
598598
add(comment[start_arg_at:at])
@@ -616,7 +616,7 @@ def format_default(app: Sphinx, default: Any, is_annotated: bool) -> str | None:
616616
return f"default: ``{formatted}``"
617617

618618

619-
def process_docstring( # noqa: PLR0913
619+
def process_docstring( # noqa: PLR0913, PLR0917, PLR0917
620620
app: Sphinx,
621621
what: str,
622622
name: str,
@@ -695,7 +695,7 @@ def _line_is_param_line_for_arg(line: str, arg_name: str) -> bool:
695695
return any(doc_name == prefix + arg_name for prefix in ("", "\\*", "\\**", "\\*\\*"))
696696

697697

698-
def _inject_types_to_docstring( # noqa: PLR0913
698+
def _inject_types_to_docstring( # noqa: PLR0913, PLR0917
699699
type_hints: dict[str, Any],
700700
signature: inspect.Signature | None,
701701
original_obj: Any,
@@ -826,7 +826,7 @@ def get_insert_index(app: Sphinx, lines: list[str]) -> InsertIndexInfo | None:
826826

827827
# 4. Insert before examples
828828
for child in doc.children:
829-
if tag_name(child) in ["literal_block", "paragraph", "field_list"]:
829+
if tag_name(child) in {"literal_block", "paragraph", "field_list"}:
830830
continue
831831
line_no = node_line_no(child)
832832
at = line_no - 2 if line_no else len(lines)
@@ -836,7 +836,7 @@ def get_insert_index(app: Sphinx, lines: list[str]) -> InsertIndexInfo | None:
836836
return InsertIndexInfo(insert_index=len(lines))
837837

838838

839-
def _inject_rtype( # noqa: PLR0913
839+
def _inject_rtype( # noqa: PLR0913, PLR0917
840840
type_hints: dict[str, Any],
841841
original_obj: Any,
842842
app: Sphinx,
@@ -950,12 +950,12 @@ def setup(app: Sphinx) -> dict[str, bool]:
950950

951951
__all__ = [
952952
"__version__",
953+
"backfill_type_hints",
953954
"format_annotation",
954955
"get_annotation_args",
955956
"get_annotation_class_name",
956957
"get_annotation_module",
957958
"normalize_source_lines",
958959
"process_docstring",
959960
"process_signature",
960-
"backfill_type_hints",
961961
]

src/sphinx_autodoc_typehints/attributes_patch.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
def _stringify_annotation(app: Sphinx, annotation: Any, mode: str = "") -> str: # noqa: ARG001
4646
# Format the annotation with sphinx-autodoc-typehints and inject our magic prefix to tell our patched
4747
# PyAttribute.handle_signature to treat it as rst.
48-
from . import format_annotation
48+
from . import format_annotation # noqa: PLC0415
4949

5050
return TYPE_IS_RST_LABEL + format_annotation(annotation, app.config)
5151

src/sphinx_autodoc_typehints/patches.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ def fix_autodoc_typehints_for_overloaded_methods() -> None:
2828
2929
See https://github.com/tox-dev/sphinx-autodoc-typehints/issues/296
3030
"""
31-
from sphinx.ext.autodoc import FunctionDocumenter, MethodDocumenter
31+
from sphinx.ext.autodoc import FunctionDocumenter, MethodDocumenter # noqa: PLC0415
3232

3333
del FunctionDocumenter.format_signature
3434
del MethodDocumenter.format_signature
3535

3636

37-
def napoleon_numpy_docstring_return_type_processor( # noqa: PLR0913
37+
def napoleon_numpy_docstring_return_type_processor( # noqa: PLR0913, PLR0917
3838
app: Sphinx,
3939
what: str,
4040
name: str, # noqa: ARG001
@@ -43,7 +43,7 @@ def napoleon_numpy_docstring_return_type_processor( # noqa: PLR0913
4343
lines: list[str],
4444
) -> None:
4545
"""Insert a : under Returns: to tell napoleon not to look for a return type."""
46-
if what not in ["function", "method"]:
46+
if what not in {"function", "method"}:
4747
return
4848
if not getattr(app.config, "napoleon_numpy_docstring", False):
4949
return
@@ -52,7 +52,7 @@ def napoleon_numpy_docstring_return_type_processor( # noqa: PLR0913
5252
# Returns:
5353
# --------
5454
for pos, line in enumerate(lines[:-2]):
55-
if line.lower().strip(":") not in ["return", "returns"]:
55+
if line.lower().strip(":") not in {"return", "returns"}:
5656
continue
5757
# Underline detection.
5858
chars = set(lines[pos + 1].strip())

tests/roots/test-resolve-typing-guard-tmp/demo_typing_guard.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class SomeClass:
1515
"""Date to handle"""
1616

1717
@classmethod
18-
def from_str(cls, input_value: str) -> SomeClass: # noqa: ANN102
18+
def from_str(cls, input_value: str) -> SomeClass:
1919
"""
2020
Initialize from string
2121
@@ -25,7 +25,7 @@ def from_str(cls, input_value: str) -> SomeClass: # noqa: ANN102
2525
return cls(input_value)
2626

2727
@classmethod
28-
def from_date(cls, input_value: datetime.date) -> SomeClass: # noqa: ANN102
28+
def from_date(cls, input_value: datetime.date) -> SomeClass:
2929
"""
3030
Initialize from date
3131
@@ -35,7 +35,7 @@ def from_date(cls, input_value: datetime.date) -> SomeClass: # noqa: ANN102
3535
return cls(input_value)
3636

3737
@classmethod
38-
def from_time(cls, input_value: datetime.time) -> SomeClass: # noqa: ANN102
38+
def from_time(cls, input_value: datetime.time) -> SomeClass:
3939
"""
4040
Initialize from time
4141
@@ -44,7 +44,7 @@ def from_time(cls, input_value: datetime.time) -> SomeClass: # noqa: ANN102
4444
"""
4545
return cls(input_value)
4646

47-
def calculate_thing(self, number: float) -> datetime.timedelta:
47+
def calculate_thing(self, number: float) -> datetime.timedelta: # noqa: PLR6301
4848
"""
4949
Calculate a thing
5050

tests/roots/test-resolve-typing-guard/demo_typing_guard.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,13 @@ def guarded(self, item: Decimal) -> None:
5555
"""
5656

5757

58-
def func(_x: Literal) -> None:
59-
...
58+
def func(_x: Literal) -> None: ...
6059

6160

6261
__all__ = [
63-
"a",
62+
"AnotherClass",
63+
"SomeClass",
6464
"ValueError",
65+
"a",
6566
"cmp_to_key",
66-
"SomeClass",
67-
"AnotherClass",
6867
]

tests/test_integration.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,15 @@ def __dunder_method(self, x: str) -> str:
175175
:param x: foo
176176
"""
177177

178-
def __magic_custom_method__(self, x: str) -> str:
178+
def __magic_custom_method__(self, x: str) -> str: # noqa: PLW3201
179179
"""
180180
Magic dunder method docstring.
181181
182182
:param x: foo
183183
"""
184184

185185
@classmethod
186-
def a_classmethod(cls, x: bool, y: int, z: Optional[str] = None) -> str: # noqa: ANN102, UP007
186+
def a_classmethod(cls, x: bool, y: int, z: Optional[str] = None) -> str: # noqa: UP007
187187
"""
188188
Classmethod docstring.
189189
@@ -415,7 +415,7 @@ def __init__(
415415
# type: (...) -> None
416416
pass
417417

418-
def foo( # noqa: ANN201
418+
def foo( # noqa: ANN201, PLR6301
419419
self,
420420
x, # type: str # noqa: ANN001, ARG002
421421
):
@@ -427,7 +427,7 @@ def foo( # noqa: ANN201
427427
"""
428428
return 42
429429

430-
def method_without_typehint(self, x): # noqa: ANN001, ANN201, ARG002
430+
def method_without_typehint(self, x): # noqa: ANN001, ANN201, ARG002, PLR6301
431431
"""
432432
Method docstring.
433433
"""
@@ -510,7 +510,7 @@ class ClassWithTypehintsNotInline:
510510
def __init__(self, x=None) -> None: # type: (Optional[Callable[[int, bytes], int]]) -> None # noqa: ANN001
511511
pass
512512

513-
def foo(self, x=1): # type: (Callable[[int, bytes], int]) -> int # noqa: ANN001, ANN201
513+
def foo(self, x=1): # type: (Callable[[int, bytes], int]) -> int # noqa: ANN001, ANN201, PLR6301
514514
"""
515515
Method docstring.
516516
@@ -520,7 +520,7 @@ def foo(self, x=1): # type: (Callable[[int, bytes], int]) -> int # noqa: ANN00
520520

521521
@classmethod
522522
def mk( # noqa: ANN206
523-
cls, # noqa: ANN102
523+
cls,
524524
x=None, # noqa: ANN001
525525
): # type: (Optional[Callable[[int, bytes], int]]) -> ClassWithTypehintsNotInline
526526
"""
@@ -625,13 +625,11 @@ def func_with_examples() -> int:
625625

626626

627627
@overload
628-
def func_with_overload(a: int, b: int) -> None:
629-
...
628+
def func_with_overload(a: int, b: int) -> None: ...
630629

631630

632631
@overload
633-
def func_with_overload(a: str, b: str) -> None:
634-
...
632+
def func_with_overload(a: str, b: str) -> None: ...
635633

636634

637635
@expected(

tests/test_sphinx_autodoc_typehints.py

+5-9
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,17 @@ class A:
8181
def get_type(self) -> type:
8282
return type(self)
8383

84-
class Inner:
85-
...
84+
class Inner: ...
8685

8786

8887
class B(Generic[T]):
8988
name = "Foo" # This is set to make sure the correct class name ("B") is picked up
9089

9190

92-
class C(B[str]):
93-
...
91+
class C(B[str]): ...
9492

9593

96-
class D(typing_extensions.Protocol):
97-
...
94+
class D(typing_extensions.Protocol): ...
9895

9996

10097
class E(typing_extensions.Protocol[T]): # type: ignore[misc]
@@ -105,8 +102,7 @@ class Slotted:
105102
__slots__ = ()
106103

107104

108-
class Metaclass(type):
109-
...
105+
class Metaclass(type): ...
110106

111107

112108
class HintedMethods:
@@ -843,7 +839,7 @@ def test_resolve_typing_guard_attrs_imports(app: SphinxTestApp, status: StringIO
843839

844840

845841
def test_no_source_code_type_guard() -> None:
846-
from csv import Error
842+
from csv import Error # noqa: PLC0415
847843

848844
_resolve_type_guarded_imports([], Error)
849845

0 commit comments

Comments
 (0)