docstring-format-checker 0.9.0__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docstring-format-checker
3
- Version: 0.9.0
3
+ Version: 0.11.0
4
4
  Summary: A CLI tool to check and validate Python docstring formatting and completeness
5
5
  Author: Chris Mahoney
6
6
  Author-email: Chris Mahoney <docstring-format-checker@data-science-extensions.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "docstring-format-checker"
3
- version = "v0.9.0"
3
+ version = "v0.11.0"
4
4
  description = "A CLI tool to check and validate Python docstring formatting and completeness"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -154,63 +154,19 @@ files = [
154
154
  ]
155
155
 
156
156
  [tool.dfc]
157
- # Default configuration for docstring format checker
158
-
159
- [[tool.dfc.sections]]
160
- order = 1
161
- name = "summary"
162
- type = "free_text"
163
- admonition = "note"
164
- prefix = "!!!"
165
- required = true
166
-
167
- [[tool.dfc.sections]]
168
- order = 2
169
- name = "details"
170
- type = "free_text"
171
- admonition = "info"
172
- prefix = "???+"
173
- required = false
174
-
175
- [[tool.dfc.sections]]
176
- order = 3
177
- name = "params"
178
- type = "list_name_and_type"
179
- required = true
180
-
181
- [[tool.dfc.sections]]
182
- order = 4
183
- name = "returns"
184
- type = "list_name_and_type"
185
- required = false
186
-
187
- [[tool.dfc.sections]]
188
- order = 5
189
- name = "yields"
190
- type = "list_type"
191
- required = false
192
-
193
- [[tool.dfc.sections]]
194
- order = 6
195
- name = "raises"
196
- type = "list_type"
197
- required = false
198
-
199
- [[tool.dfc.sections]]
200
- order = 7
201
- name = "examples"
202
- type = "free_text"
203
- admonition = "example"
204
- prefix = "???+"
205
- required = false
206
-
207
- [[tool.dfc.sections]]
208
- order = 8
209
- name = "notes"
210
- type = "free_text"
211
- admonition = "note"
212
- prefix = "???"
213
- required = false
157
+ allow_undefined_sections = false
158
+ require_docstrings = true
159
+ check_private = true
160
+ sections = [
161
+ { order = 1, name = "summary", type = "free_text", required = true, admonition = "note", prefix = "!!!" },
162
+ { order = 2, name = "details", type = "free_text", required = false, admonition = "abstract", prefix = "???+" },
163
+ { order = 3, name = "params", type = "list_name_and_type", required = false },
164
+ { order = 4, name = "raises", type = "list_type", required = false },
165
+ { order = 5, name = "returns", type = "list_name_and_type", required = false },
166
+ { order = 6, name = "yields", type = "list_type", required = false },
167
+ { order = 7, name = "examples", type = "free_text", required = false, admonition = "example", prefix = "???+" },
168
+ { order = 8, name = "notes", type = "free_text", required = false, admonition = "note", prefix = "???" },
169
+ ]
214
170
 
215
171
  [build-system]
216
172
  requires = ["uv_build>=0.7.19,<0.8.0"]
@@ -4,7 +4,7 @@ Docstring Format Checker.
4
4
  A CLI tool to check and validate Python docstring formatting and completeness.
5
5
  """
6
6
 
7
- __version__ = "v0.9.0"
7
+ __version__ = "v0.11.0"
8
8
  __author__ = "Chris Mahoney"
9
9
  __email__ = "docstring-format-checker@data-science-extensions.com"
10
10
 
@@ -72,6 +72,7 @@ from docstring_format_checker.core import DocstringChecker, DocstringError
72
72
  __all__: list[str] = [
73
73
  "main",
74
74
  "entry_point",
75
+ "check_docstrings",
75
76
  ]
76
77
 
77
78
 
@@ -90,6 +91,20 @@ NEW_LINE = "\n"
90
91
 
91
92
  ### Colours ----
92
93
  def _colour(text: str, colour: str) -> str:
94
+ """
95
+ !!! note "Summary"
96
+ Apply Rich colour markup to text.
97
+
98
+ Params:
99
+ text (str):
100
+ The text to colour.
101
+ colour (str):
102
+ The colour to apply, e.g., 'red', 'green', 'blue'.
103
+
104
+ Returns:
105
+ (str):
106
+ The text wrapped in Rich colour markup.
107
+ """
93
108
  return f"[{colour}]{text}[/{colour}]"
94
109
 
95
110
 
@@ -107,7 +107,8 @@ VALID_TYPES: tuple[str, ...] = (
107
107
  @dataclass
108
108
  class GlobalConfig:
109
109
  """
110
- Global configuration for docstring checking behavior.
110
+ !!! note "Summary"
111
+ Global configuration for docstring checking behavior.
111
112
  """
112
113
 
113
114
  allow_undefined_sections: bool = False
@@ -123,7 +124,8 @@ class GlobalConfig:
123
124
  @dataclass
124
125
  class SectionConfig:
125
126
  """
126
- Configuration for a docstring section.
127
+ !!! note "Summary"
128
+ Configuration for a docstring section.
127
129
  """
128
130
 
129
131
  order: int
@@ -135,17 +137,26 @@ class SectionConfig:
135
137
  message: str = "" # Optional message for validation errors
136
138
 
137
139
  def __post_init__(self) -> None:
138
- """Validate configuration after initialization."""
140
+ """
141
+ !!! note "Summary"
142
+ Validate configuration after initialization.
143
+ """
139
144
  self._validate_types()
140
145
  self._validate_admonition_prefix_combination()
141
146
 
142
147
  def _validate_types(self) -> None:
143
- """Validate the 'type' field."""
148
+ """
149
+ !!! note "Summary"
150
+ Validate the 'type' field.
151
+ """
144
152
  if self.type not in VALID_TYPES:
145
153
  raise InvalidTypeValuesError(f"Invalid section type: {self.type}. Valid types: {VALID_TYPES}")
146
154
 
147
155
  def _validate_admonition_prefix_combination(self) -> None:
148
- """Validate admonition and prefix combination rules."""
156
+ """
157
+ !!! note "Summary"
158
+ Validate admonition and prefix combination rules.
159
+ """
149
160
 
150
161
  if isinstance(self.admonition, bool):
151
162
  # Rule: admonition cannot be True (only False or string)
@@ -173,6 +184,22 @@ class SectionConfig:
173
184
 
174
185
 
175
186
  def _validate_config_order(config_sections: list[SectionConfig]) -> None:
187
+ """
188
+ !!! note "Summary"
189
+ Validate that section order values are unique.
190
+
191
+ Params:
192
+ config_sections (list[SectionConfig]):
193
+ List of section configurations to validate.
194
+
195
+ Raises:
196
+ (InvalidConfigError_DuplicateOrderValues):
197
+ If duplicate order values are found.
198
+
199
+ Returns:
200
+ (None):
201
+ Nothing is returned.
202
+ """
176
203
 
177
204
  # Validate no duplicate order values
178
205
  order_values: list[int] = [section.order for section in config_sections]
@@ -202,7 +229,8 @@ def _validate_config_order(config_sections: list[SectionConfig]) -> None:
202
229
  @dataclass
203
230
  class Config:
204
231
  """
205
- Complete configuration containing global settings and section definitions.
232
+ !!! note "Summary"
233
+ Complete configuration containing global settings and section definitions.
206
234
  """
207
235
 
208
236
  global_config: GlobalConfig
@@ -293,15 +321,15 @@ def load_config(config_path: Optional[Union[str, Path]] = None) -> Config:
293
321
  If `None`, looks for `pyproject.toml` in current directory.
294
322
  Default: `None`.
295
323
 
296
- Returns:
297
- (Config):
298
- Configuration object containing global settings and section definitions.
299
-
300
324
  Raises:
301
325
  (FileNotFoundError):
302
326
  If the specified config file doesn't exist.
303
327
  (InvalidConfigError):
304
328
  If the configuration is invalid.
329
+
330
+ Returns:
331
+ (Config):
332
+ Configuration object containing global settings and section definitions.
305
333
  """
306
334
 
307
335
  if config_path is None:
@@ -80,7 +80,8 @@ __all__: list[str] = [
80
80
 
81
81
  class FunctionAndClassDetails(NamedTuple):
82
82
  """
83
- Details about a function or class found in the AST.
83
+ !!! note "Summary"
84
+ Details about a function or class found in the AST.
84
85
  """
85
86
 
86
87
  item_type: Literal["function", "class", "method"]
@@ -92,7 +93,8 @@ class FunctionAndClassDetails(NamedTuple):
92
93
 
93
94
  class DocstringChecker:
94
95
  """
95
- Main class for checking docstring format and completeness.
96
+ !!! note "Summary"
97
+ Main class for checking docstring format and completeness.
96
98
  """
97
99
 
98
100
  def __init__(self, config: Config) -> None:
@@ -118,10 +120,6 @@ class DocstringChecker:
118
120
  file_path (Union[str, Path]):
119
121
  Path to the Python file to check.
120
122
 
121
- Returns:
122
- (list[DocstringError]):
123
- List of DocstringError objects for any validation failures.
124
-
125
123
  Raises:
126
124
  (FileNotFoundError):
127
125
  If the file doesn't exist.
@@ -131,6 +129,10 @@ class DocstringChecker:
131
129
  If the file can't be decoded.
132
130
  (SyntaxError):
133
131
  If the file contains invalid Python syntax.
132
+
133
+ Returns:
134
+ (list[DocstringError]):
135
+ List of DocstringError objects for any validation failures.
134
136
  """
135
137
 
136
138
  file_path = Path(file_path)
@@ -274,12 +276,24 @@ class DocstringChecker:
274
276
  items: list[FunctionAndClassDetails] = []
275
277
 
276
278
  class ItemVisitor(ast.NodeVisitor):
279
+ """
280
+ !!! note "Summary"
281
+ AST visitor to extract function and class definitions
282
+ """
277
283
 
278
284
  def __init__(self, checker: DocstringChecker) -> None:
285
+ """
286
+ !!! note "Summary"
287
+ Initialize the AST visitor.
288
+ """
279
289
  self.class_stack: list[str] = []
280
290
  self.checker: DocstringChecker = checker
281
291
 
282
292
  def visit_ClassDef(self, node: ast.ClassDef) -> None:
293
+ """
294
+ !!! note "Summary"
295
+ Visit class definition node.
296
+ """
283
297
  # Skip private classes unless check_private is enabled
284
298
  should_check: bool = self.checker.config.global_config.check_private or not node.name.startswith("_")
285
299
  if should_check:
@@ -299,13 +313,24 @@ class DocstringChecker:
299
313
  self.class_stack.pop()
300
314
 
301
315
  def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
316
+ """
317
+ !!! note "Summary"
318
+ Visit function definition node.
319
+ """
302
320
  self._visit_function(node)
303
321
 
304
322
  def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
323
+ """
324
+ !!! note "Summary"
325
+ Visit async function definition node.
326
+ """
305
327
  self._visit_function(node)
306
328
 
307
329
  def _visit_function(self, node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> None:
308
- """Visit function definition node (sync or async)."""
330
+ """
331
+ !!! note "Summary"
332
+ Visit function definition node (sync or async).
333
+ """
309
334
 
310
335
  # Skip private functions unless check_private is enabled
311
336
  should_check: bool = self.checker.config.global_config.check_private or not node.name.startswith("_")
@@ -835,7 +860,8 @@ class DocstringChecker:
835
860
 
836
861
  def _check_colon_usage(self, docstring: str) -> list[str]:
837
862
  """
838
- Check that colons are used correctly for admonition vs non-admonition sections.
863
+ !!! note "Summary"
864
+ Check that colons are used correctly for admonition vs non-admonition sections.
839
865
  """
840
866
 
841
867
  errors: list[str] = []
@@ -882,7 +908,8 @@ class DocstringChecker:
882
908
 
883
909
  def _check_title_case_sections(self, docstring: str) -> list[str]:
884
910
  """
885
- Check that non-admonition sections are single word, title case, and match config name.
911
+ !!! note "Summary"
912
+ Check that non-admonition sections are single word, title case, and match config name.
886
913
  """
887
914
 
888
915
  errors: list[str] = []
@@ -914,7 +941,8 @@ class DocstringChecker:
914
941
 
915
942
  def _check_parentheses_validation(self, docstring: str) -> list[str]:
916
943
  """
917
- Check that list_type and list_name_and_type sections have proper parentheses.
944
+ !!! note "Summary"
945
+ Check that list_type and list_name_and_type sections have proper parentheses.
918
946
  """
919
947
 
920
948
  errors: list[str] = []
@@ -1,6 +1,7 @@
1
1
  class DocstringError(Exception):
2
2
  """
3
- Exception raised when a docstring validation error occurs.
3
+ !!! note "Summary"
4
+ Exception raised when a docstring validation error occurs.
4
5
  """
5
6
 
6
7
  def __init__(
@@ -11,6 +12,10 @@ class DocstringError(Exception):
11
12
  item_name: str,
12
13
  item_type: str,
13
14
  ) -> None:
15
+ """
16
+ !!! note "Summary"
17
+ Initialize a DocstringError.
18
+ """
14
19
  self.message = message
15
20
  self.file_path = file_path
16
21
  self.line_number = line_number
@@ -20,20 +25,45 @@ class DocstringError(Exception):
20
25
 
21
26
 
22
27
  class InvalidConfigError(Exception):
28
+ """
29
+ !!! note "Summary"
30
+ Exception raised for invalid configuration errors.
31
+ """
32
+
23
33
  pass
24
34
 
25
35
 
26
36
  class InvalidConfigError_DuplicateOrderValues(Exception):
37
+ """
38
+ !!! note "Summary"
39
+ Exception raised for duplicate order values in configuration.
40
+ """
41
+
27
42
  pass
28
43
 
29
44
 
30
45
  class InvalidTypeValuesError(Exception):
46
+ """
47
+ !!! note "Summary"
48
+ Exception raised for invalid type values in configuration.
49
+ """
50
+
31
51
  pass
32
52
 
33
53
 
34
54
  class InvalidFileError(OSError):
55
+ """
56
+ !!! note "Summary"
57
+ Exception raised for invalid file errors.
58
+ """
59
+
35
60
  pass
36
61
 
37
62
 
38
63
  class DirectoryNotFoundError(OSError):
64
+ """
65
+ !!! note "Summary"
66
+ Exception raised for directory not found errors.
67
+ """
68
+
39
69
  pass