CLASPLint 0.5.0__tar.gz → 0.5.2__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.
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/__init__.py +5 -5
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/__main__.py +6 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/checker_base.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/comment_checker.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/configuration.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/configuration.yaml +39 -5
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/dict_key_checker.py +7 -7
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/docstring_checker.py +60 -6
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/function_checker.py +10 -10
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/log_checker.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/naming_utils.py +18 -6
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/reporter.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/runner.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/try_except_checker.py +2 -2
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint/variable_checker.py +51 -21
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/PKG-INFO +4 -4
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/PKG-INFO +4 -4
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/README.md +3 -3
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/pyproject.toml +1 -1
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/setup.py +5 -5
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/SOURCES.txt +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/dependency_links.txt +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/entry_points.txt +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/not-zip-safe +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/CLASPLint.egg-info/top_level.txt +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/LICENSE +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/MANIFEST.in +0 -0
- {CLASPLint-0.5.0 → CLASPLint-0.5.2}/setup.cfg +0 -0
|
@@ -22,16 +22,16 @@ MAINTAINER :
|
|
|
22
22
|
|
|
23
23
|
PROJECT CREATE DATE : 2026-06-17
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION DATE : 2026-07-
|
|
25
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
26
26
|
|
|
27
|
-
PROJECT VERSION : 0.5.
|
|
27
|
+
PROJECT VERSION : 0.5.2
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
FILE CREATE DATE : 2026-06-17
|
|
31
31
|
|
|
32
|
-
FILE VERSION DATE : 2026-07-
|
|
32
|
+
FILE VERSION DATE : 2026-07-11
|
|
33
33
|
|
|
34
|
-
FILE VERSION : 0.
|
|
34
|
+
FILE VERSION : 1.0.1
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
STATUS : Stable
|
|
@@ -71,6 +71,6 @@ Sort License:
|
|
|
71
71
|
"""
|
|
72
72
|
|
|
73
73
|
# Define the package version string.
|
|
74
|
-
__version__ = "0.5.
|
|
74
|
+
__version__ = "0.5.2"
|
|
75
75
|
# Expose the runner and reporter modules as the public API.
|
|
76
76
|
__all__ = ["runner", "reporter"]
|
|
@@ -20,9 +20,9 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
@@ -159,6 +159,10 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
159
159
|
:return: Exit code 0 when no violations are found, 1 otherwise.
|
|
160
160
|
:rtype: int
|
|
161
161
|
"""
|
|
162
|
+
# Ensure stdout and stderr use UTF-8 encoding for cross-platform Chinese output.
|
|
163
|
+
sys.stdout.reconfigure(encoding='utf-8')
|
|
164
|
+
# Reconfigure the standard error stream to use UTF-8 encoding.
|
|
165
|
+
sys.stderr.reconfigure(encoding='utf-8')
|
|
162
166
|
# Build and parse command-line arguments.
|
|
163
167
|
command_parser = _init_build_parser_function_()
|
|
164
168
|
# Parse the provided arguments or default to sys.argv.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
2
|
"""
|
|
3
3
|
THIS FILE IS CORE PART OF CLASPLINT BY MATT BELFAST BROWN.
|
|
4
4
|
|
|
@@ -24,16 +24,16 @@ MAINTAINER :
|
|
|
24
24
|
|
|
25
25
|
PROJECT CREATE DATE : 2026-06-17
|
|
26
26
|
|
|
27
|
-
PROJECT VERSION DATE : 2026-07-
|
|
27
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
28
28
|
|
|
29
|
-
PROJECT VERSION : 0.5.
|
|
29
|
+
PROJECT VERSION : 0.5.2
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
FILE CREATE DATE : 2026-07-06
|
|
33
33
|
|
|
34
|
-
FILE VERSION DATE : 2026-07-
|
|
34
|
+
FILE VERSION DATE : 2026-07-11
|
|
35
35
|
|
|
36
|
-
FILE VERSION : 1.0.
|
|
36
|
+
FILE VERSION : 1.0.1
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
STATUS : Stable
|
|
@@ -341,6 +341,40 @@ bool_words:
|
|
|
341
341
|
- is
|
|
342
342
|
# Require the has prefix to mark boolean possession-checking variables.
|
|
343
343
|
- has
|
|
344
|
+
# Require the bool prefix to mark boolean type-prefixed variables.
|
|
345
|
+
- bool
|
|
346
|
+
# Require the should prefix to mark boolean recommendation variables.
|
|
347
|
+
- should
|
|
348
|
+
# Require the can prefix to mark boolean capability-checking variables.
|
|
349
|
+
- can
|
|
350
|
+
# Require the does prefix to mark boolean action-status variables.
|
|
351
|
+
- does
|
|
352
|
+
# Require the did prefix to mark boolean past-action variables.
|
|
353
|
+
- did
|
|
354
|
+
# Require the do prefix to mark boolean imperative variables.
|
|
355
|
+
- do
|
|
356
|
+
# Require the will prefix to mark boolean future-intent variables.
|
|
357
|
+
- will
|
|
358
|
+
# Require the was prefix to mark boolean past-state variables.
|
|
359
|
+
- was
|
|
360
|
+
# Require the were prefix to mark boolean past-plural variables.
|
|
361
|
+
- were
|
|
362
|
+
# Require the could prefix to mark boolean possibility variables.
|
|
363
|
+
- could
|
|
364
|
+
# Require the would prefix to mark boolean hypothetical variables.
|
|
365
|
+
- would
|
|
366
|
+
# Require the might prefix to mark boolean uncertainty variables.
|
|
367
|
+
- might
|
|
368
|
+
# Require the must prefix to mark boolean requirement variables.
|
|
369
|
+
- must
|
|
370
|
+
# Require the needs prefix to mark boolean need-indication variables.
|
|
371
|
+
- needs
|
|
372
|
+
# Require the contains prefix to mark boolean membership variables.
|
|
373
|
+
- contains
|
|
374
|
+
# Require the allows prefix to mark boolean permission variables.
|
|
375
|
+
- allows
|
|
376
|
+
# Require the supports prefix to mark boolean feature-check variables.
|
|
377
|
+
- supports
|
|
344
378
|
|
|
345
379
|
# Vague verbs that trigger function name warnings when used at the start.
|
|
346
380
|
verbs_vague:
|
|
@@ -20,16 +20,16 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
29
29
|
|
|
30
|
-
FILE VERSION DATE : 2026-07-
|
|
30
|
+
FILE VERSION DATE : 2026-07-11
|
|
31
31
|
|
|
32
|
-
FILE VERSION : 1.0.
|
|
32
|
+
FILE VERSION : 1.0.1
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
STATUS : Stable
|
|
@@ -94,7 +94,7 @@ class DictKeyChecker(ast.NodeVisitor):
|
|
|
94
94
|
Visit subscript nodes for potential dict key access in assignments.
|
|
95
95
|
|
|
96
96
|
PRIVATE METHODS :
|
|
97
|
-
|
|
97
|
+
_init_validate_key_function_(node_key: ast.AST) -> None:
|
|
98
98
|
Validate a string-constant dictionary key.
|
|
99
99
|
_init_keyword_as_key_function_(node_keyword: ast.keyword) -> list:
|
|
100
100
|
Validate a keyword argument name used as a dictionary key.
|
|
@@ -129,7 +129,7 @@ class DictKeyChecker(ast.NodeVisitor):
|
|
|
129
129
|
# Collect violations found during AST traversal.
|
|
130
130
|
self.list_violations: List[Violation] = []
|
|
131
131
|
|
|
132
|
-
def
|
|
132
|
+
def _init_validate_key_function_(self, node_key: ast.AST) -> None:
|
|
133
133
|
"""
|
|
134
134
|
Validate a single dictionary key literal.
|
|
135
135
|
|
|
@@ -197,7 +197,7 @@ class DictKeyChecker(ast.NodeVisitor):
|
|
|
197
197
|
# Process non-None keys through the key validator.
|
|
198
198
|
if node_key is not None:
|
|
199
199
|
# Delegate to the key validation method for this dictionary key.
|
|
200
|
-
self.
|
|
200
|
+
self._init_validate_key_function_(node_key)
|
|
201
201
|
# Continue visiting child nodes for nested dictionaries.
|
|
202
202
|
self.generic_visit(ast_node)
|
|
203
203
|
|
|
@@ -20,16 +20,16 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
29
29
|
|
|
30
|
-
FILE VERSION DATE : 2026-07-
|
|
30
|
+
FILE VERSION DATE : 2026-07-11
|
|
31
31
|
|
|
32
|
-
FILE VERSION : 1.0.
|
|
32
|
+
FILE VERSION : 1.0.1
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
STATUS : Stable
|
|
@@ -156,6 +156,8 @@ class DocstringChecker(ast.NodeVisitor):
|
|
|
156
156
|
self.list_violations: List[Violation] = []
|
|
157
157
|
# Track the current class name for contextual messages.
|
|
158
158
|
self.string_currentclass: str = ""
|
|
159
|
+
# Track whether the current class inherits from ast.NodeVisitor for visit_* exemption.
|
|
160
|
+
self.is_astvisitor: bool = False
|
|
159
161
|
|
|
160
162
|
def _init_add_violation_function_(self, ast_node: ast.AST, string_message: str) -> None:
|
|
161
163
|
"""
|
|
@@ -273,10 +275,16 @@ class DocstringChecker(ast.NodeVisitor):
|
|
|
273
275
|
string_previous = self.string_currentclass
|
|
274
276
|
# Set the current class name for method context messages.
|
|
275
277
|
self.string_currentclass = ast_node.name
|
|
278
|
+
# Save the previous visitor flag before entering the new class.
|
|
279
|
+
was_visitor = self.is_astvisitor
|
|
280
|
+
# Determine whether this class inherits from ast.NodeVisitor for visit_* exemption.
|
|
281
|
+
self.is_astvisitor = self._init_detect_visitor_function_(ast_node)
|
|
276
282
|
# Visit child nodes within the class body to check methods.
|
|
277
283
|
self.generic_visit(ast_node)
|
|
278
284
|
# Restore the previous class context after leaving the class.
|
|
279
285
|
self.string_currentclass = string_previous
|
|
286
|
+
# Restore the previous visitor flag after leaving the class.
|
|
287
|
+
self.is_astvisitor = was_visitor
|
|
280
288
|
|
|
281
289
|
def visit_FunctionDef(self, ast_node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> None:
|
|
282
290
|
"""
|
|
@@ -319,8 +327,14 @@ class DocstringChecker(ast.NodeVisitor):
|
|
|
319
327
|
return
|
|
320
328
|
# Perform Sphinx format validation only for class methods.
|
|
321
329
|
if bool_ismethod:
|
|
322
|
-
#
|
|
323
|
-
self.
|
|
330
|
+
# Skip Sphinx format checks for visit_* methods in ast.NodeVisitor subclasses.
|
|
331
|
+
if self.is_astvisitor and ast_node.name.startswith("visit_"):
|
|
332
|
+
# Exempt NodeVisitor callback methods per CLASP Stage 3.3 Section 6.4.4.
|
|
333
|
+
pass
|
|
334
|
+
# Sphinx format checks apply to non-visit methods only.
|
|
335
|
+
else:
|
|
336
|
+
# Validate the method docstring against the Sphinx directive format.
|
|
337
|
+
self._init_check_format_function_(ast_node, docstring_text, display_name)
|
|
324
338
|
# Validate docstring text quality for all functions and methods.
|
|
325
339
|
self._init_chk_doc_qual_function_(ast_node, docstring_text, display_name)
|
|
326
340
|
# Continue visiting the function body for nested definitions.
|
|
@@ -341,6 +355,46 @@ class DocstringChecker(ast.NodeVisitor):
|
|
|
341
355
|
# Delegate to the standard function definition visitor.
|
|
342
356
|
self.visit_FunctionDef(ast_node)
|
|
343
357
|
|
|
358
|
+
@staticmethod
|
|
359
|
+
def _init_detect_visitor_function_(class_node: ast.ClassDef) -> bool:
|
|
360
|
+
"""
|
|
361
|
+
Determine whether the class definition inherits from ast.NodeVisitor.
|
|
362
|
+
|
|
363
|
+
Inspects each base class of the given ClassDef node and checks whether any
|
|
364
|
+
base matches the ast.NodeVisitor attribute chain. Returns True immediately
|
|
365
|
+
upon finding a match, or False after exhausting all bases.
|
|
366
|
+
|
|
367
|
+
The parameters are as follows:
|
|
368
|
+
|
|
369
|
+
:param class_node: The ClassDef AST node whose base classes are inspected.
|
|
370
|
+
:type class_node: ast.ClassDef
|
|
371
|
+
:return: True if any base class is ast.NodeVisitor, False otherwise.
|
|
372
|
+
:rtype: bool
|
|
373
|
+
"""
|
|
374
|
+
# Iterate over each base class in the class definition.
|
|
375
|
+
for node_base in class_node.bases:
|
|
376
|
+
# Check for direct ast.NodeVisitor base class reference.
|
|
377
|
+
if isinstance(node_base, ast.Attribute):
|
|
378
|
+
# Verify the attribute chain matches ast.NodeVisitor.
|
|
379
|
+
if (
|
|
380
|
+
# Check that the value is an ast Name node.
|
|
381
|
+
isinstance(node_base.value, ast.Name)
|
|
382
|
+
# Match the module name ast.
|
|
383
|
+
and node_base.value.id == "ast"
|
|
384
|
+
# Match the class name NodeVisitor.
|
|
385
|
+
and node_base.attr == "NodeVisitor"
|
|
386
|
+
):
|
|
387
|
+
# Confirm that the class inherits from ast.NodeVisitor.
|
|
388
|
+
return True
|
|
389
|
+
# Check for known NodeVisitor subclass as base class.
|
|
390
|
+
if isinstance(node_base, ast.Name):
|
|
391
|
+
# Detect known NodeVisitor subclasses used in this project.
|
|
392
|
+
if node_base.id == "CheckerBase":
|
|
393
|
+
# Confirm transitively inheriting from ast.NodeVisitor.
|
|
394
|
+
return True
|
|
395
|
+
# No ast.NodeVisitor base class was found in the inheritance chain.
|
|
396
|
+
return False
|
|
397
|
+
|
|
344
398
|
def _init_check_format_function_(
|
|
345
399
|
# Accept the function definition node for signature analysis.
|
|
346
400
|
self, ast_node: Union[ast.FunctionDef, ast.AsyncFunctionDef],
|
|
@@ -20,16 +20,16 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
29
29
|
|
|
30
|
-
FILE VERSION DATE : 2026-07-
|
|
30
|
+
FILE VERSION DATE : 2026-07-11
|
|
31
31
|
|
|
32
|
-
FILE VERSION : 1.0.
|
|
32
|
+
FILE VERSION : 1.0.1
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
STATUS : Stable
|
|
@@ -86,7 +86,7 @@ class FunctionChecker(CheckerBase):
|
|
|
86
86
|
source_lines (list): Source lines for contextual messages.
|
|
87
87
|
list_violations (list): Collected naming violations.
|
|
88
88
|
string_currentclass (str): Current class context for method detection.
|
|
89
|
-
|
|
89
|
+
is_astvisitor (bool): Whether current class inherits ast.NodeVisitor.
|
|
90
90
|
|
|
91
91
|
PUBLIC METHODS :
|
|
92
92
|
visit_ClassDef(class_node: ast.ClassDef) -> None:
|
|
@@ -130,7 +130,7 @@ class FunctionChecker(CheckerBase):
|
|
|
130
130
|
# Track the current class context for method detection.
|
|
131
131
|
self.string_currentclass: str = ""
|
|
132
132
|
# Track whether the current class inherits from ast.NodeVisitor.
|
|
133
|
-
self.
|
|
133
|
+
self.is_astvisitor: bool = False
|
|
134
134
|
|
|
135
135
|
def _init_add_violations_function_(
|
|
136
136
|
# Accept the violation category for grouping in the report.
|
|
@@ -180,17 +180,17 @@ class FunctionChecker(CheckerBase):
|
|
|
180
180
|
# Save the previous class context before entering the new class.
|
|
181
181
|
string_previous = self.string_currentclass
|
|
182
182
|
# Save the previous visitor flag before entering the new class.
|
|
183
|
-
was_visitor = self.
|
|
183
|
+
was_visitor = self.is_astvisitor
|
|
184
184
|
# Set the current class context for method detection.
|
|
185
185
|
self.string_currentclass = class_node.name
|
|
186
186
|
# Determine whether this class inherits from ast.NodeVisitor for visit_* exemption.
|
|
187
|
-
self.
|
|
187
|
+
self.is_astvisitor = self._init_detect_visitor_function_(class_node)
|
|
188
188
|
# Visit child nodes within the class body.
|
|
189
189
|
self.generic_visit(class_node)
|
|
190
190
|
# Restore the previous class context after leaving the class.
|
|
191
191
|
self.string_currentclass = string_previous
|
|
192
192
|
# Restore the previous visitor flag after leaving the class.
|
|
193
|
-
self.
|
|
193
|
+
self.is_astvisitor = was_visitor
|
|
194
194
|
|
|
195
195
|
def visit_FunctionDef(self, function_node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> None:
|
|
196
196
|
"""
|
|
@@ -214,7 +214,7 @@ class FunctionChecker(CheckerBase):
|
|
|
214
214
|
# Indicate whether this is a method or a module-level function.
|
|
215
215
|
is_method=bool_ismethod,
|
|
216
216
|
# Pass the AST visitor flag for targeted visit_* exemption.
|
|
217
|
-
is_astvisitor=self.
|
|
217
|
+
is_astvisitor=self.is_astvisitor,
|
|
218
218
|
)
|
|
219
219
|
# Use the "function" category for all function and method violations.
|
|
220
220
|
string_category = "function"
|
|
@@ -20,16 +20,16 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
29
29
|
|
|
30
|
-
FILE VERSION DATE : 2026-07-
|
|
30
|
+
FILE VERSION DATE : 2026-07-11
|
|
31
31
|
|
|
32
|
-
FILE VERSION : 1.0.
|
|
32
|
+
FILE VERSION : 1.0.1
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
STATUS : Stable
|
|
@@ -489,8 +489,20 @@ def is_private_method_format(string_name: str) -> bool:
|
|
|
489
489
|
:return: True when the name matches the private method format pattern.
|
|
490
490
|
:rtype: bool
|
|
491
491
|
"""
|
|
492
|
-
#
|
|
493
|
-
|
|
492
|
+
# Match the _init_..._function_ pattern with fully spelled lowercase word groups.
|
|
493
|
+
match_result = re.match(r'^_init_([a-z]+(_[a-z]+)*)_function_$', string_name)
|
|
494
|
+
# Reject names that do not match the basic private method pattern.
|
|
495
|
+
if not match_result:
|
|
496
|
+
# Exit early when the name structure does not match _init_..._function_ format.
|
|
497
|
+
return False
|
|
498
|
+
# Extract the descriptor portion between _init_ and _function_.
|
|
499
|
+
string_descriptor = match_result.group(1)
|
|
500
|
+
# Split the descriptor into individual word segments by underscore.
|
|
501
|
+
list_words = string_descriptor.split('_')
|
|
502
|
+
# Count the number of fully spelled words in the descriptor.
|
|
503
|
+
int_wordcount = len(list_words)
|
|
504
|
+
# Enforce the 2-to-8 word range per CLASP Stage 3.3 Section 4.3.6.
|
|
505
|
+
return 2 <= int_wordcount <= 8
|
|
494
506
|
|
|
495
507
|
|
|
496
508
|
def validate_variable_name(string_name: str) -> list:
|
|
@@ -20,16 +20,16 @@ MAINTAINER :
|
|
|
20
20
|
|
|
21
21
|
PROJECT CREATE DATE : 2026-06-17
|
|
22
22
|
|
|
23
|
-
PROJECT VERSION DATE : 2026-07-
|
|
23
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
24
24
|
|
|
25
|
-
PROJECT VERSION : 0.5.
|
|
25
|
+
PROJECT VERSION : 0.5.2
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
FILE CREATE DATE : 2026-06-17
|
|
29
29
|
|
|
30
|
-
FILE VERSION DATE : 2026-07-
|
|
30
|
+
FILE VERSION DATE : 2026-07-11
|
|
31
31
|
|
|
32
|
-
FILE VERSION : 1.0.
|
|
32
|
+
FILE VERSION : 1.0.2
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
STATUS : Stable
|
|
@@ -352,16 +352,24 @@ class VariableChecker(ast.NodeVisitor):
|
|
|
352
352
|
:param ast_node: The assignment AST node whose targets contain variable names.
|
|
353
353
|
:type ast_node: ast.Assign
|
|
354
354
|
"""
|
|
355
|
-
# Detect
|
|
355
|
+
# Detect ALL_CAPS assignments as constant naming violations.
|
|
356
356
|
for target_node in ast_node.targets:
|
|
357
|
+
# Track the variable name string to validate, regardless of node type.
|
|
358
|
+
target_name = ""
|
|
357
359
|
# Check simple Name targets for ALL_CAPS pattern suggesting a constant.
|
|
358
360
|
if isinstance(target_node, ast.Name):
|
|
359
|
-
#
|
|
361
|
+
# Extract the identifier from the Name node.
|
|
360
362
|
target_name = target_node.id
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
# Check attribute targets only for self or cls instance variables.
|
|
364
|
+
elif isinstance(target_node, ast.Attribute):
|
|
365
|
+
# Only extract the attribute name when the object is self or cls.
|
|
366
|
+
if isinstance(target_node.value, ast.Name) and target_node.value.id in ('self', 'cls'):
|
|
367
|
+
# Extract the attribute name from the Attribute node.
|
|
368
|
+
target_name = target_node.attr
|
|
369
|
+
# Validate the extracted name when it is not exempt from checks.
|
|
370
|
+
if target_name and target_name not in names_exempt:
|
|
371
|
+
# Detect any uppercase letter in the variable name.
|
|
372
|
+
if target_name != target_name.lower():
|
|
365
373
|
# Build a unique key to prevent duplicate reports.
|
|
366
374
|
int_lineno = getattr(ast_node, 'lineno', 0)
|
|
367
375
|
# Guard against nodes that lack a reliable line number.
|
|
@@ -417,10 +425,22 @@ class VariableChecker(ast.NodeVisitor):
|
|
|
417
425
|
:param ast_node: The assignment AST node to inspect for boolean literal values.
|
|
418
426
|
:type ast_node: ast.Assign
|
|
419
427
|
"""
|
|
420
|
-
#
|
|
428
|
+
# Check Name and Attribute targets for boolean literal assignments.
|
|
421
429
|
for target_node in ast_node.targets:
|
|
422
|
-
#
|
|
423
|
-
|
|
430
|
+
# Track the variable name regardless of target node type.
|
|
431
|
+
target_name = ""
|
|
432
|
+
# Extract the name from simple Name targets.
|
|
433
|
+
if isinstance(target_node, ast.Name):
|
|
434
|
+
# Retrieve the identifier from the Name node.
|
|
435
|
+
target_name = target_node.id
|
|
436
|
+
# Extract the attribute name only for self.xxx or cls.xxx Attribute targets.
|
|
437
|
+
elif isinstance(target_node, ast.Attribute):
|
|
438
|
+
# Only retrieve the attribute name when the object is self or cls.
|
|
439
|
+
if isinstance(target_node.value, ast.Name) and target_node.value.id in ('self', 'cls'):
|
|
440
|
+
# Retrieve the attribute name portion from the Attribute node.
|
|
441
|
+
target_name = target_node.attr
|
|
442
|
+
# Skip when no valid name was extracted or the name is exempt.
|
|
443
|
+
if not target_name or target_name in names_exempt:
|
|
424
444
|
# Proceed to the next target.
|
|
425
445
|
continue
|
|
426
446
|
# Detect boolean literal assignments for prefix verification.
|
|
@@ -431,8 +451,6 @@ class VariableChecker(ast.NodeVisitor):
|
|
|
431
451
|
if ast_node.value.value not in (True, False):
|
|
432
452
|
# Skip non-boolean constants.
|
|
433
453
|
continue
|
|
434
|
-
# Extract the variable name for inspection.
|
|
435
|
-
target_name = target_node.id
|
|
436
454
|
# Extract the first underscore-separated group for prefix detection.
|
|
437
455
|
list_groups = target_name.split("_")
|
|
438
456
|
# Skip variables that already use the mandatory boolean prefix.
|
|
@@ -491,10 +509,20 @@ class VariableChecker(ast.NodeVisitor):
|
|
|
491
509
|
"""
|
|
492
510
|
# Check that bool-annotated variables use the mandatory boolean prefix.
|
|
493
511
|
if isinstance(ast_node.annotation, ast.Name) and ast_node.annotation.id == "bool":
|
|
494
|
-
#
|
|
495
|
-
|
|
496
|
-
|
|
512
|
+
# Track the variable name regardless of target node type.
|
|
513
|
+
target_name = ""
|
|
514
|
+
# Extract the name from simple Name targets.
|
|
515
|
+
if isinstance(ast_node.target, ast.Name):
|
|
516
|
+
# Retrieve the variable name from the Name node.
|
|
497
517
|
target_name = ast_node.target.id
|
|
518
|
+
# Extract the attribute name only for self.xxx or cls.xxx Attribute targets.
|
|
519
|
+
elif isinstance(ast_node.target, ast.Attribute):
|
|
520
|
+
# Only retrieve the attribute name when the object is self or cls.
|
|
521
|
+
if isinstance(ast_node.target.value, ast.Name) and ast_node.target.value.id in ('self', 'cls'):
|
|
522
|
+
# Retrieve the attribute name portion from the Attribute node.
|
|
523
|
+
target_name = ast_node.target.attr
|
|
524
|
+
# Validate the bool prefix when a name was extracted and is not exempt.
|
|
525
|
+
if target_name and target_name not in names_exempt:
|
|
498
526
|
# Extract the first underscore-separated group.
|
|
499
527
|
list_groups = target_name.split("_")
|
|
500
528
|
# Flag bool-annotated variables missing is_ or has_ prefix.
|
|
@@ -707,10 +735,12 @@ class VariableChecker(ast.NodeVisitor):
|
|
|
707
735
|
elif isinstance(target, ast.Starred):
|
|
708
736
|
# Recursively walk the value inside the starred expression.
|
|
709
737
|
self._init_walk_target_function_(target.value)
|
|
710
|
-
#
|
|
738
|
+
# Validate instance variable names only when assigned via self.attr or cls.attr.
|
|
711
739
|
elif isinstance(target, ast.Attribute):
|
|
712
|
-
#
|
|
713
|
-
|
|
740
|
+
# Only validate attribute names on self or cls instances.
|
|
741
|
+
if isinstance(target.value, ast.Name) and target.value.id in ('self', 'cls'):
|
|
742
|
+
# Extract the attribute name part beyond the dot for validation.
|
|
743
|
+
self._init_check_name_function_(target.attr, target)
|
|
714
744
|
# Skip subscript assignments (obj[key] = ...) as these are not variable definitions.
|
|
715
745
|
elif isinstance(target, ast.Subscript):
|
|
716
746
|
# Take no action for subscript assignment targets.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CLASPLint
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: CLASP Stage 3.3 / PEP 2606 Static Analysis Tool — enforces naming and comment conventions beyond PEP 8.
|
|
5
5
|
Author: Matt Belfast Brown
|
|
6
6
|
Author-email: Matt Belfast Brown <thedayofthedo@gmail.com>
|
|
@@ -27,11 +27,11 @@ Requires-Python: >=3.8
|
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
|
|
30
|
-
# CLASPLint
|
|
30
|
+
# CLASPLint
|
|
31
31
|
|
|
32
32
|
[](https://www.python.org/)
|
|
33
33
|
[](./LICENSE)
|
|
34
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
35
35
|
|
|
36
36
|
> CLASP Stage 3.3 / PEP 2606 static analysis tool. Enforces naming and comment conventions beyond PEP 8 —
|
|
37
37
|
> checks variables, dictionary keys, functions, classes, comments, and log messages for standards
|
|
@@ -210,7 +210,7 @@ CLASPLint supports **Python 3.8 through 3.14**. The minimum version is 3.8 due t
|
|
|
210
210
|
|
|
211
211
|
[](https://www.python.org/)
|
|
212
212
|
[](./LICENSE)
|
|
213
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
214
214
|
|
|
215
215
|
> **CLASP Stage 3.3 / PEP 2606** 静态分析工具。在 PEP 8 **之上**强制执行命名与注释规范 ——
|
|
216
216
|
> 检查变量、字典键、函数、类、注释和日志消息是否符合标准。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CLASPLint
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: CLASP Stage 3.3 / PEP 2606 Static Analysis Tool — enforces naming and comment conventions beyond PEP 8.
|
|
5
5
|
Author: Matt Belfast Brown
|
|
6
6
|
Author-email: Matt Belfast Brown <thedayofthedo@gmail.com>
|
|
@@ -27,11 +27,11 @@ Requires-Python: >=3.8
|
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
|
|
30
|
-
# CLASPLint
|
|
30
|
+
# CLASPLint
|
|
31
31
|
|
|
32
32
|
[](https://www.python.org/)
|
|
33
33
|
[](./LICENSE)
|
|
34
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
35
35
|
|
|
36
36
|
> CLASP Stage 3.3 / PEP 2606 static analysis tool. Enforces naming and comment conventions beyond PEP 8 —
|
|
37
37
|
> checks variables, dictionary keys, functions, classes, comments, and log messages for standards
|
|
@@ -210,7 +210,7 @@ CLASPLint supports **Python 3.8 through 3.14**. The minimum version is 3.8 due t
|
|
|
210
210
|
|
|
211
211
|
[](https://www.python.org/)
|
|
212
212
|
[](./LICENSE)
|
|
213
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
214
214
|
|
|
215
215
|
> **CLASP Stage 3.3 / PEP 2606** 静态分析工具。在 PEP 8 **之上**强制执行命名与注释规范 ——
|
|
216
216
|
> 检查变量、字典键、函数、类、注释和日志消息是否符合标准。
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# CLASPLint
|
|
1
|
+
# CLASPLint
|
|
2
2
|
|
|
3
3
|
[](https://www.python.org/)
|
|
4
4
|
[](./LICENSE)
|
|
5
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
6
6
|
|
|
7
7
|
> CLASP Stage 3.3 / PEP 2606 static analysis tool. Enforces naming and comment conventions beyond PEP 8 —
|
|
8
8
|
> checks variables, dictionary keys, functions, classes, comments, and log messages for standards
|
|
@@ -181,7 +181,7 @@ CLASPLint supports **Python 3.8 through 3.14**. The minimum version is 3.8 due t
|
|
|
181
181
|
|
|
182
182
|
[](https://www.python.org/)
|
|
183
183
|
[](./LICENSE)
|
|
184
|
-
[](https://pypi.org/project/CLASPLint/)
|
|
185
185
|
|
|
186
186
|
> **CLASP Stage 3.3 / PEP 2606** 静态分析工具。在 PEP 8 **之上**强制执行命名与注释规范 ——
|
|
187
187
|
> 检查变量、字典键、函数、类、注释和日志消息是否符合标准。
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "CLASPLint"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.2"
|
|
8
8
|
description = "CLASP Stage 3.3 / PEP 2606 Static Analysis Tool — enforces naming and comment conventions beyond PEP 8."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "GPL-3.0-only"}
|
|
@@ -23,16 +23,16 @@ MAINTAINER :
|
|
|
23
23
|
|
|
24
24
|
PROJECT CREATE DATE : 2026-06-17
|
|
25
25
|
|
|
26
|
-
PROJECT VERSION DATE : 2026-07-
|
|
26
|
+
PROJECT VERSION DATE : 2026-07-11
|
|
27
27
|
|
|
28
|
-
PROJECT VERSION : 0.5.
|
|
28
|
+
PROJECT VERSION : 0.5.2
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
FILE CREATE DATE : 2026-06-17
|
|
32
32
|
|
|
33
|
-
FILE VERSION DATE : 2026-07-
|
|
33
|
+
FILE VERSION DATE : 2026-07-11
|
|
34
34
|
|
|
35
|
-
FILE VERSION : 0.
|
|
35
|
+
FILE VERSION : 1.0.1
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
STATUS : Stable
|
|
@@ -75,7 +75,7 @@ setup(
|
|
|
75
75
|
# Declare the package name used for PyPI registration and pip install.
|
|
76
76
|
name="CLASPLint",
|
|
77
77
|
# Declare the semantic version following major.minor.patch convention.
|
|
78
|
-
version="0.5.
|
|
78
|
+
version="0.5.2",
|
|
79
79
|
|
|
80
80
|
# Provide a brief description of the tool for PyPI and help text.
|
|
81
81
|
description="CLASP Stage 3.3 / PEP 2606 Static Analysis Tool",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|