Skip to content

Commit 478231d

Browse files
implement requested changes, add required tests
1 parent 178db4a commit 478231d

14 files changed

Lines changed: 743 additions & 142 deletions

File tree

docs/checking_class_attributes.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,11 @@ class MyPet:
190190

191191
## 4. Inline docstrings
192192

193-
PEP-257 indicates that string literals located directly after an assign
194-
statement may be treated as attribute documentation. As such, we also
195-
optionally support inline docstrings for class attributes with the
196-
`allow-inline-classvar-docs` option set to True (it is False by default).
193+
[PEP-257](https://peps.python.org/pep-0257/) indicates that string literals
194+
located directly after an assign statement may be treated as attribute
195+
documentation. As such, we also optionally support inline docstrings for class
196+
attributes with the `allow-inline-class-var-docs` option set to True (it is
197+
False by default).
197198

198199
Attribute type documentation may be specified as the first thing in the
199200
docstring followed by a colon. For example:

docs/config_options.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ attributes, and all other attributes are treated as instance attributes.
232232

233233
## 19. `--allow-inline-classvar-docs` (shortform: `-aicvd`, default: `False`)
234234

235-
If True, allow class attributes to have inline documentation. For example:
235+
If True, require class attributes to have inline documentation. For example:
236236

237237
```python
238238
class MyClass:
@@ -244,9 +244,10 @@ class MyClass:
244244

245245
If False, pydoclint will not parse inline class attribute docstrings.
246246

247-
Inline documentation will not supersede class-level documentation, meaning that
248-
if you declare an attribute at the class level **and** an inline docstring,
249-
pydoclint will take the class-level documentation and not the inline docstring.
247+
Inline documentation will not be allowed if this setting is set to False.
248+
Similarly, class-level documentation of class attributes will not be allowed if
249+
this option is set to True.
250+
250251
Inline docstrings may specify the attribute type as the first token in the
251252
docstring followed by a `:`.
252253

docs/notes_for_users.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,9 @@ As mentioned in Section 2 above, _pydoclint_ uses static syntax analysis. As a
114114
result, it cannot really "know" that these type annotations are in fact
115115
equivalent:
116116

117-
| Type annotation | Equivalent version |
118-
| ----------------- | ------------------ |
119-
| `Optional[str]` | `str \| None` |
120-
| `Union[str, int]` | `int \| str` |
121-
| `Tuple[str, int]` | `tuple[str, int]` |
117+
| Type annotation | Equivalent version | | ----------------- |
118+
------------------ | | `Optional[str]` | `str \| None` | | `Union[str, int]` |
119+
`int \| str` | | `Tuple[str, int]` | `tuple[str, int]` |
122120

123121
Additionally, _pydoclint_ does not recognize some docstring conventions allowed
124122
in the docstring style guide, such as using "`int, optional`" for

docs/style_mismatch.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,12 @@ even when we fall back to the configured style the cost is still negligible.
9292
For reference, benchmarking large code bases (as of 2025/01/12) shows the
9393
overhead of style detection is only a few percent:
9494

95-
| | numpy | scikit-learn | Bokeh | Airflow |
96-
| ---------------------------- | ----- | ------------ | ----- | ------- |
97-
| Number of .py files | 581 | 929 | 1196 | 5004 |
98-
| Run time with 1 style [sec] | 1.84 | 2.68 | 0.77 | 5.50 |
99-
| Run time with 3 styles [sec] | 1.91 | 2.79 | 0.78 | 5.77 |
100-
| Additional run time [sec] | 0.07 | 0.11 | 0.01 | 0.07 |
101-
| Relative additional run time | 4% | 4% | 1% | 5% |
95+
| | numpy | scikit-learn | Bokeh | Airflow | | ---------------------------- |
96+
----- | ------------ | ----- | ------- | | Number of .py files | 581 | 929 |
97+
1196 | 5004 | | Run time with 1 style [sec] | 1.84 | 2.68 | 0.77 | 5.50 | | Run
98+
time with 3 styles [sec] | 1.91 | 2.79 | 0.78 | 5.77 | | Additional run time
99+
[sec] | 0.07 | 0.11 | 0.01 | 0.07 | | Relative additional run time | 4% | 4% |
100+
1% | 5% |
102101

103102
## 5. What violation code is associated with style mismatch?
104103

docs/violation_codes.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,15 @@ on the top) do not need to have a return section.
9898

9999
## 7. `DOC6xx`: Violations about class attributes
100100

101-
| Code | Explanation |
102-
| -------- | --------------------------------------------------------------------------------- |
103-
| `DOC601` | Class docstring contains fewer class attributes than actual class attributes. |
104-
| `DOC602` | Class docstring contains more class attributes than in actual class attributes. |
105-
| `DOC603` | Class docstring attributes are different from actual class attributes. |
106-
| `DOC604` | Attributes are the same in docstring and class def, but are in a different order. |
107-
| `DOC605` | Attribute names match, but type hints in these attributes do not match |
101+
| Code | Explanation |
102+
| -------- | -------------------------------------------------------------------------------------------------- |
103+
| `DOC601` | Class docstring contains fewer class attributes than actual class attributes. |
104+
| `DOC602` | Class docstring contains more class attributes than in actual class attributes. |
105+
| `DOC603` | Class docstring attributes are different from actual class attributes. |
106+
| `DOC604` | Attributes are the same in docstring and class def, but are in a different order. |
107+
| `DOC605` | Attribute names match, but type hints in these attributes do not match |
108+
| `DOC606` | Attribute should not have an inline docstring; please combine it with the docstring of the class |
109+
| `DOC607` | The class docstring should not have an "Attributes" section; please document all attributes inline |
108110

109111
More about checking class attributes:
110112
https://jsh9.github.io/pydoclint/checking_class_attributes.html

pydoclint/utils/arg.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,5 +438,8 @@ def insertAt(
438438
arg: Arg,
439439
) -> None:
440440
"""Insert an Arg at a specific index."""
441+
if arg.name in self.lookup:
442+
raise ValueError(f'Arg with name "{arg.name}" already exists.')
443+
441444
self.infoList.insert(index, arg)
442445
self.lookup[arg.name] = arg.typeHint

pydoclint/utils/violation.py

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,33 @@
2121
' ).'
2222
),
2323
104: (
24-
'Arguments are the same in the docstring and the function signature,'
25-
' but are in a different order.'
24+
'Arguments are the same in the docstring and the function'
25+
' signature, but are in a different order.'
2626
),
27-
105: 'Argument names match, but type hints in these args do not match:',
27+
105: ('Argument names match, but type hints in these args do not match:'),
2828
106: (
29-
'The option `--arg-type-hints-in-signature` is `True` but there are'
30-
' no argument type hints in the signature'
29+
'The option `--arg-type-hints-in-signature` is `True` but'
30+
' there are no argument type hints in the signature'
3131
),
3232
107: (
3333
'The option `--arg-type-hints-in-signature` is `True` but not all'
3434
' args in the signature have type hints'
3535
),
3636
108: (
37-
'The option `--arg-type-hints-in-signature` is `False` but there are'
38-
' argument type hints in the signature'
37+
'The option `--arg-type-hints-in-signature` is `False` but'
38+
' there are argument type hints in the signature'
3939
),
4040
109: (
41-
'The option `--arg-type-hints-in-docstring` is `True` but there are'
42-
' no type hints in the docstring arg list'
41+
'The option `--arg-type-hints-in-docstring` is `True` but'
42+
' there are no type hints in the docstring arg list'
4343
),
4444
110: (
4545
'The option `--arg-type-hints-in-docstring` is `True` but not all'
4646
' args in the docstring arg list have type hints'
4747
),
4848
111: (
49-
'The option `--arg-type-hints-in-docstring` is `False` but there are'
50-
' type hints in the docstring arg list'
49+
'The option `--arg-type-hints-in-docstring` is `False` but'
50+
' there are type hints in the docstring arg list'
5151
),
5252
201: 'does not have a return section in docstring',
5353
202: (
@@ -59,20 +59,20 @@
5959
' annotation.'
6060
),
6161
301: (
62-
'__init__() should not have a docstring; please combine it with the'
63-
' docstring of the class'
62+
'__init__() should not have a docstring; please combine it'
63+
' with the docstring of the class'
6464
),
6565
302: (
6666
'The class docstring does not need a "Returns" section, because'
6767
' __init__() cannot return anything'
6868
),
6969
303: (
70-
'The __init__() docstring does not need a "Returns" section, because'
71-
' it cannot return anything'
70+
'The __init__() docstring does not need a "Returns" section,'
71+
' because it cannot return anything'
7272
),
7373
304: (
74-
'Class docstring has an argument/parameter section; please put it in'
75-
' the __init__() docstring'
74+
'Class docstring has an argument/parameter section; please'
75+
' put it in the __init__() docstring'
7676
),
7777
305: (
7878
'Class docstring has a "Raises" section; please put it in the'
@@ -83,13 +83,13 @@
8383
' __init__() cannot yield anything'
8484
),
8585
307: (
86-
'The __init__() docstring does not need a "Yields" section, because'
87-
' __init__() cannot yield anything'
86+
'The __init__() docstring does not need a "Yields" section,'
87+
' because __init__() cannot yield anything'
8888
),
8989
401: '', # Deprecated
9090
402: (
91-
'has "yield" statements, but the docstring does not have a "Yields"'
92-
' section'
91+
'has "yield" statements, but the docstring does not have a'
92+
' "Yields" section'
9393
),
9494
403: (
9595
'has a "Yields" section in the docstring, but there are no "yield"'
@@ -102,49 +102,58 @@
102102
),
103103
405: (
104104
'has both "return" and "yield" statements. Please use'
105-
' Generator[YieldType, SendType, ReturnType] as the return type'
106-
' annotation, and put your yield type in YieldType and return type'
107-
' in ReturnType. More details in'
105+
' Generator[YieldType, SendType, ReturnType] as the'
106+
' return type annotation, and put your yield type in'
107+
' YieldType and return type in ReturnType. More details in'
108108
' https://jsh9.github.io/pydoclint/notes_generator_vs_iterator.html'
109109
),
110110
501: (
111-
'has raise statements, but the docstring does not have a "Raises"'
112-
' section'
111+
'has raise statements, but the docstring does not have a'
112+
' "Raises" section'
113113
),
114114
502: (
115-
'has a "Raises" section in the docstring, but there are not "raise"'
116-
' statements in the body'
115+
'has a "Raises" section in the docstring, but there are not'
116+
' "raise" statements in the body'
117117
),
118118
503: (
119119
'exceptions in the "Raises" section in the docstring do not match'
120120
' those in the function body.'
121121
),
122122
504: (
123-
'has assert statements, but the docstring does not have a "Raises"'
124-
' section. (Assert statements could raise "AssertError".)'
123+
'has assert statements, but the docstring does not have a'
124+
' "Raises" section. (Assert statements could raise'
125+
' "AssertError".)'
125126
),
126127
601: (
127-
'Class docstring contains fewer class attributes than actual class'
128-
' attributes.'
128+
'Class docstring contains fewer class attributes than actual'
129+
' class attributes.'
129130
),
130131
602: (
131-
'Class docstring contains more class attributes than in actual class'
132-
' attributes.'
132+
'Class docstring contains more class attributes than in actual'
133+
' class attributes.'
133134
),
134135
603: (
135136
'Class docstring attributes are different from actual class'
136137
' attributes.'
137138
' (Or could be other formatting issues: '
138-
'https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103'
139-
' ).'
139+
'https://jsh9.github.io/pydoclint/violation_codes.html'
140+
'#notes-on-doc103 ).'
140141
),
141142
604: (
142143
'Attributes are the same in docstring and class def, but are in a'
143144
' different order.'
144145
),
145146
605: (
146-
'Attribute names match, but type hints in these attributes do not'
147-
' match:'
147+
'Attribute names match, but type hints in these'
148+
' attributes do not match:'
149+
),
150+
606: (
151+
'Attribute has an inline docstring, but should be documented in'
152+
' the class docstring instead.'
153+
),
154+
607: (
155+
'The class docstring does not need an "Attributes" section,'
156+
' because the class attributes are documented inline.'
148157
),
149158
})
150159

0 commit comments

Comments
 (0)