docstring-format-checker 0.6.0__tar.gz → 0.8.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.
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/PKG-INFO +1 -1
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/pyproject.toml +1 -1
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/__init__.py +1 -1
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/cli.py +10 -16
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/core.py +64 -23
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/README.md +0 -0
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/config.py +0 -0
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/utils/__init__.py +0 -0
- {docstring_format_checker-0.6.0 → docstring_format_checker-0.8.0}/src/docstring_format_checker/utils/exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docstring-format-checker
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.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>
|
|
@@ -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.
|
|
7
|
+
__version__ = "v0.8.0"
|
|
8
8
|
__author__ = "Chris Mahoney"
|
|
9
9
|
__email__ = "docstring-format-checker@data-science-extensions.com"
|
|
10
10
|
|
|
@@ -434,30 +434,24 @@ def _display_results(results: dict[str, list[DocstringError]], quiet: bool, outp
|
|
|
434
434
|
console.print(table)
|
|
435
435
|
|
|
436
436
|
else:
|
|
437
|
-
# Show compact output
|
|
437
|
+
# Show compact output with grouped errors under function/class headers
|
|
438
438
|
for file_path, errors in results.items():
|
|
439
439
|
console.print(f"{NEW_LINE}{_cyan(file_path)}")
|
|
440
440
|
for error in errors:
|
|
441
|
-
#
|
|
441
|
+
# Print the header line with line number, item type and name
|
|
442
|
+
if error.line_number > 0:
|
|
443
|
+
console.print(f" [red]Line {error.line_number}[/red] - {error.item_type} '{error.item_name}':")
|
|
444
|
+
else:
|
|
445
|
+
console.print(f" {_red('Error')} - {error.item_type} '{error.item_name}':")
|
|
446
|
+
|
|
447
|
+
# Split error message into individual errors and indent them
|
|
442
448
|
if "; " in error.message:
|
|
443
449
|
individual_errors = [msg.strip() for msg in error.message.split("; ") if msg.strip()]
|
|
444
450
|
for individual_error in individual_errors:
|
|
445
|
-
|
|
446
|
-
if error.line_number > 0:
|
|
447
|
-
console.print(
|
|
448
|
-
f" [red]Line {error.line_number}[/red] - {error.item_type} '{error.item_name}': {formatted_error}"
|
|
449
|
-
)
|
|
450
|
-
else:
|
|
451
|
-
console.print(f" {_red('Error')}: {formatted_error}")
|
|
451
|
+
console.print(f" - {individual_error}")
|
|
452
452
|
else:
|
|
453
453
|
# Single error message
|
|
454
|
-
|
|
455
|
-
if error.line_number > 0:
|
|
456
|
-
console.print(
|
|
457
|
-
f" [red]Line {error.line_number}[/red] - {error.item_type} '{error.item_name}': {formatted_error}"
|
|
458
|
-
)
|
|
459
|
-
else:
|
|
460
|
-
console.print(f" {_red('Error')}: {formatted_error}")
|
|
454
|
+
console.print(f" - {error.message.strip()}")
|
|
461
455
|
|
|
462
456
|
# Summary - more descriptive message
|
|
463
457
|
if total_functions == 1:
|
|
@@ -924,6 +924,7 @@ class DocstringChecker:
|
|
|
924
924
|
# Check each line in the docstring
|
|
925
925
|
lines: list[str] = docstring.split("\n")
|
|
926
926
|
current_section = None
|
|
927
|
+
type_line_indent = None # Track indentation of type definition lines
|
|
927
928
|
|
|
928
929
|
for i, line in enumerate(lines):
|
|
929
930
|
stripped_line: str = line.strip()
|
|
@@ -938,6 +939,7 @@ class DocstringChecker:
|
|
|
938
939
|
current_section: Optional[SectionConfig] = next(
|
|
939
940
|
(s for s in parentheses_sections if s.name.lower() == section_name), None
|
|
940
941
|
)
|
|
942
|
+
type_line_indent = None # Reset for new section
|
|
941
943
|
continue
|
|
942
944
|
|
|
943
945
|
# Non-admonition sections - only match actual section headers, not indented content
|
|
@@ -955,6 +957,7 @@ class DocstringChecker:
|
|
|
955
957
|
current_section = next(
|
|
956
958
|
(s for s in parentheses_sections if s.name.lower() == section_name), None
|
|
957
959
|
)
|
|
960
|
+
type_line_indent = None # Reset for new section
|
|
958
961
|
continue
|
|
959
962
|
# If it doesn't match a known section, fall through to content processing
|
|
960
963
|
|
|
@@ -962,6 +965,9 @@ class DocstringChecker:
|
|
|
962
965
|
if current_section and stripped_line and not stripped_line.startswith(("!", "?", "#")):
|
|
963
966
|
# Look for parameter/type definitions
|
|
964
967
|
if ":" in stripped_line:
|
|
968
|
+
# Calculate current line indentation
|
|
969
|
+
current_indent = len(line) - len(line.lstrip())
|
|
970
|
+
|
|
965
971
|
# Skip description lines that start with common description words
|
|
966
972
|
description_prefixes = [
|
|
967
973
|
"default:",
|
|
@@ -986,30 +992,65 @@ class DocstringChecker:
|
|
|
986
992
|
):
|
|
987
993
|
continue
|
|
988
994
|
|
|
995
|
+
# For list_type sections, we need special handling
|
|
996
|
+
if current_section.type == "list_type":
|
|
997
|
+
# Check if this line has parentheses at the beginning
|
|
998
|
+
if re.search(r"^\s*\([^)]+\):", stripped_line):
|
|
999
|
+
# This is a valid type definition line, remember its indentation
|
|
1000
|
+
type_line_indent = current_indent
|
|
1001
|
+
continue
|
|
1002
|
+
else:
|
|
1003
|
+
# If no type definition has been found yet, allow lines with colons as possible descriptions
|
|
1004
|
+
if type_line_indent is None:
|
|
1005
|
+
continue
|
|
1006
|
+
# Check if this is a description line (more indented than type line)
|
|
1007
|
+
if current_indent > type_line_indent:
|
|
1008
|
+
# This is a description line, skip validation
|
|
1009
|
+
continue
|
|
1010
|
+
else:
|
|
1011
|
+
# This should be a type definition but doesn't have proper format
|
|
1012
|
+
errors.append(
|
|
1013
|
+
f"Section '{current_section.name}' (type: '{current_section.type}') requires "
|
|
1014
|
+
f"parenthesized types, see: '{stripped_line}'"
|
|
1015
|
+
)
|
|
989
1016
|
# For list_name_and_type sections, check format like "name (type):" or "(type):"
|
|
990
|
-
|
|
991
|
-
#
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
if any(
|
|
996
|
-
word in colon_part.lower() for word in ["default", "output", "format", "show", "example"]
|
|
997
|
-
):
|
|
1017
|
+
elif current_section.type == "list_name_and_type":
|
|
1018
|
+
# Check if this line has parentheses and looks like a parameter definition
|
|
1019
|
+
if re.search(r"\([^)]+\):", stripped_line):
|
|
1020
|
+
# This is a valid parameter definition line, remember its indentation
|
|
1021
|
+
type_line_indent = current_indent
|
|
998
1022
|
continue
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1023
|
+
else:
|
|
1024
|
+
# Check if this is likely a description line based on various criteria
|
|
1025
|
+
colon_part = stripped_line.split(":")[0].strip()
|
|
1026
|
+
|
|
1027
|
+
# Skip if it contains phrases that indicate it's a description, not a parameter
|
|
1028
|
+
if any(
|
|
1029
|
+
word in colon_part.lower()
|
|
1030
|
+
for word in ["default", "output", "format", "show", "example"]
|
|
1031
|
+
):
|
|
1032
|
+
continue
|
|
1033
|
+
|
|
1034
|
+
# Skip if it starts with bullet points or list markers
|
|
1035
|
+
if stripped_line.strip().startswith(("-", "*", "•", "+")):
|
|
1036
|
+
continue
|
|
1037
|
+
|
|
1038
|
+
# If we have found a parameter definition, check if this is a description line
|
|
1039
|
+
if type_line_indent is not None:
|
|
1040
|
+
# Skip if this is more indented than the parameter definition (description line)
|
|
1041
|
+
if current_indent > type_line_indent:
|
|
1042
|
+
continue
|
|
1043
|
+
|
|
1044
|
+
# Skip if the line before the colon contains multiple words (likely description)
|
|
1045
|
+
words_before_colon = colon_part.split()
|
|
1046
|
+
if len(words_before_colon) > 2: # More than "param_name (type)"
|
|
1047
|
+
continue
|
|
1048
|
+
|
|
1049
|
+
# Only flag lines that could reasonably be parameter definitions
|
|
1050
|
+
if ":" in stripped_line and not stripped_line.strip().startswith("#"):
|
|
1051
|
+
errors.append(
|
|
1052
|
+
f"Section '{current_section.name}' (type: '{current_section.type}') requires "
|
|
1053
|
+
f"parenthesized types, see: '{stripped_line}'"
|
|
1054
|
+
)
|
|
1014
1055
|
|
|
1015
1056
|
return errors
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|