docstring-format-checker 0.6.0__tar.gz → 0.7.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.6.0
3
+ Version: 0.7.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.6.0"
3
+ version = "v0.7.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"
@@ -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.6.0"
7
+ __version__ = "v0.7.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 - each individual error on its own line
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
- # Split error message into individual errors for list mode
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
- formatted_error = f"- {individual_error}"
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
- formatted_error = f"- {error.message.strip()}"
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,8 +992,29 @@ 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
- if current_section.type == "list_name_and_type":
1017
+ elif current_section.type == "list_name_and_type":
991
1018
  # Pattern: name (type): or (type):
992
1019
  # But skip if it doesn't look like a parameter definition (e.g., has multiple words before the colon)
993
1020
  colon_part = stripped_line.split(":")[0].strip()
@@ -1003,13 +1030,4 @@ class DocstringChecker:
1003
1030
  f"parenthesized types, see: '{stripped_line}'"
1004
1031
  )
1005
1032
 
1006
- # For list_type sections, check format like "(Type):"
1007
- elif current_section.type == "list_type":
1008
- # Pattern: (Type):
1009
- if not re.search(r"^\s*\([^)]+\):", stripped_line):
1010
- errors.append(
1011
- f"Section '{current_section.name}' (type: '{current_section.type}') requires "
1012
- f"parenthesized types, see: '{stripped_line}'"
1013
- )
1014
-
1015
1033
  return errors