docstring-format-checker 1.6.0__tar.gz → 1.6.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.
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/PKG-INFO +1 -1
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/pyproject.toml +1 -1
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/src/docstring_format_checker/cli.py +12 -1
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/src/docstring_format_checker/core.py +229 -132
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/README.md +0 -0
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/src/docstring_format_checker/__init__.py +0 -0
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/src/docstring_format_checker/config.py +0 -0
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/src/docstring_format_checker/utils/__init__.py +0 -0
- {docstring_format_checker-1.6.0 → docstring_format_checker-1.6.2}/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: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
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>
|
|
@@ -543,8 +543,19 @@ def _format_error_output(error: DocstringError) -> list[str]:
|
|
|
543
543
|
"""
|
|
544
544
|
lines: list[str] = [_create_error_header(error)]
|
|
545
545
|
individual_errors: list[str] = _split_error_messages(error.message)
|
|
546
|
+
|
|
546
547
|
for individual_error in individual_errors:
|
|
547
|
-
|
|
548
|
+
# Check if this error has multi-line content (e.g., parameter type mismatches)
|
|
549
|
+
if "\n" in individual_error:
|
|
550
|
+
# Split by newlines and add 4 spaces of extra indentation to each line
|
|
551
|
+
error_lines = individual_error.split("\n")
|
|
552
|
+
lines.append(f" - {error_lines[0]}") # First line gets the bullet
|
|
553
|
+
for sub_line in error_lines[1:]:
|
|
554
|
+
if sub_line.strip(): # Only add non-empty lines
|
|
555
|
+
lines.append(f" {sub_line}") # Continuation lines get 4 spaces
|
|
556
|
+
else:
|
|
557
|
+
lines.append(f" - {individual_error}")
|
|
558
|
+
|
|
548
559
|
return lines
|
|
549
560
|
|
|
550
561
|
|
|
@@ -559,10 +559,14 @@ class DocstringChecker:
|
|
|
559
559
|
|
|
560
560
|
errors: list[str] = []
|
|
561
561
|
|
|
562
|
-
# Validate required sections
|
|
562
|
+
# Validate required sections are present
|
|
563
563
|
required_section_errors: list[str] = self._validate_all_required_sections(docstring, item)
|
|
564
564
|
errors.extend(required_section_errors)
|
|
565
565
|
|
|
566
|
+
# Validate all existing sections (required or not)
|
|
567
|
+
existing_section_errors: list[str] = self._validate_all_existing_sections(docstring, item)
|
|
568
|
+
errors.extend(existing_section_errors)
|
|
569
|
+
|
|
566
570
|
# Perform comprehensive validation checks
|
|
567
571
|
comprehensive_errors: list[str] = self._perform_comprehensive_validation(docstring)
|
|
568
572
|
errors.extend(comprehensive_errors)
|
|
@@ -578,10 +582,33 @@ class DocstringChecker:
|
|
|
578
582
|
item_type=item.item_type,
|
|
579
583
|
)
|
|
580
584
|
|
|
585
|
+
def _is_params_section_required(self, item: FunctionAndClassDetails) -> bool:
|
|
586
|
+
"""
|
|
587
|
+
!!! note "Summary"
|
|
588
|
+
Check if params section is required for this item.
|
|
589
|
+
|
|
590
|
+
Params:
|
|
591
|
+
item (FunctionAndClassDetails):
|
|
592
|
+
The function or class details.
|
|
593
|
+
|
|
594
|
+
Returns:
|
|
595
|
+
(bool):
|
|
596
|
+
True if params section is required, False otherwise.
|
|
597
|
+
"""
|
|
598
|
+
|
|
599
|
+
# For classes, params section not required (attributes handled differently)
|
|
600
|
+
if isinstance(item.node, ast.ClassDef):
|
|
601
|
+
return False
|
|
602
|
+
|
|
603
|
+
# For functions, only required if function has parameters (excluding self/cls)
|
|
604
|
+
# item.node is guaranteed to be FunctionDef or AsyncFunctionDef due to type constraints
|
|
605
|
+
params = [arg.arg for arg in item.node.args.args if arg.arg not in ("self", "cls")]
|
|
606
|
+
return len(params) > 0
|
|
607
|
+
|
|
581
608
|
def _validate_all_required_sections(self, docstring: str, item: FunctionAndClassDetails) -> list[str]:
|
|
582
609
|
"""
|
|
583
610
|
!!! note "Summary"
|
|
584
|
-
Validate all required sections are present
|
|
611
|
+
Validate all required sections are present.
|
|
585
612
|
|
|
586
613
|
Params:
|
|
587
614
|
docstring (str):
|
|
@@ -591,115 +618,127 @@ class DocstringChecker:
|
|
|
591
618
|
|
|
592
619
|
Returns:
|
|
593
620
|
(list[str]):
|
|
594
|
-
List of validation error messages.
|
|
621
|
+
List of validation error messages for missing required sections.
|
|
595
622
|
"""
|
|
596
623
|
|
|
597
624
|
errors: list[str] = []
|
|
598
625
|
for section in self.required_sections:
|
|
599
|
-
|
|
600
|
-
if
|
|
601
|
-
|
|
626
|
+
# Special handling for params section - only required if function/class has parameters
|
|
627
|
+
if section.name.lower() == "params":
|
|
628
|
+
if not self._is_params_section_required(item):
|
|
629
|
+
continue
|
|
630
|
+
|
|
631
|
+
# Only check if the section exists, don't validate content yet
|
|
632
|
+
if not self._section_exists(docstring, section):
|
|
633
|
+
errors.append(f"Missing required section: {section.name}")
|
|
602
634
|
return errors
|
|
603
635
|
|
|
604
|
-
def
|
|
605
|
-
self, docstring: str, section: SectionConfig, item: FunctionAndClassDetails
|
|
606
|
-
) -> Optional[str]:
|
|
636
|
+
def _validate_all_existing_sections(self, docstring: str, item: FunctionAndClassDetails) -> list[str]:
|
|
607
637
|
"""
|
|
608
638
|
!!! note "Summary"
|
|
609
|
-
Validate
|
|
639
|
+
Validate content of all existing sections (required or not).
|
|
610
640
|
|
|
611
641
|
Params:
|
|
612
642
|
docstring (str):
|
|
613
643
|
The docstring to validate.
|
|
614
|
-
section (SectionConfig):
|
|
615
|
-
The section configuration to validate against.
|
|
616
644
|
item (FunctionAndClassDetails):
|
|
617
645
|
The function or class details.
|
|
618
646
|
|
|
619
647
|
Returns:
|
|
620
|
-
(
|
|
621
|
-
|
|
648
|
+
(list[str]):
|
|
649
|
+
List of validation error messages for invalid section content.
|
|
622
650
|
"""
|
|
623
651
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
return None
|
|
652
|
+
errors: list[str] = []
|
|
653
|
+
for section in self.config.sections:
|
|
654
|
+
# Only validate if the section actually exists in the docstring
|
|
655
|
+
if self._section_exists(docstring, section):
|
|
656
|
+
section_error = self._validate_single_section_content(docstring, section, item)
|
|
657
|
+
if section_error:
|
|
658
|
+
errors.append(section_error)
|
|
659
|
+
return errors
|
|
633
660
|
|
|
634
|
-
def
|
|
661
|
+
def _section_exists(self, docstring: str, section: SectionConfig) -> bool:
|
|
635
662
|
"""
|
|
636
663
|
!!! note "Summary"
|
|
637
|
-
|
|
664
|
+
Check if a section exists in the docstring.
|
|
638
665
|
|
|
639
666
|
Params:
|
|
640
667
|
docstring (str):
|
|
641
|
-
The docstring to
|
|
668
|
+
The docstring to check.
|
|
642
669
|
section (SectionConfig):
|
|
643
670
|
The section configuration.
|
|
644
671
|
|
|
645
672
|
Returns:
|
|
646
|
-
(
|
|
647
|
-
|
|
673
|
+
(bool):
|
|
674
|
+
`True` if section exists, `False` otherwise.
|
|
648
675
|
"""
|
|
649
676
|
|
|
650
|
-
|
|
651
|
-
return f"Missing required section: {section.name}"
|
|
652
|
-
return None
|
|
677
|
+
section_name: str = section.name.lower()
|
|
653
678
|
|
|
654
|
-
|
|
679
|
+
# For free text sections, use the existing logic from _check_free_text_section
|
|
680
|
+
if section.type == "free_text":
|
|
681
|
+
return self._check_free_text_section(docstring, section)
|
|
682
|
+
|
|
683
|
+
# Check for admonition style sections (for non-free-text types)
|
|
684
|
+
if section.admonition and isinstance(section.admonition, str):
|
|
685
|
+
if section.prefix and isinstance(section.prefix, str):
|
|
686
|
+
# e.g., "!!! note" or "???+ abstract"
|
|
687
|
+
pattern: str = rf"{re.escape(section.prefix)}\s+{re.escape(section.admonition)}"
|
|
688
|
+
if re.search(pattern, docstring, re.IGNORECASE):
|
|
689
|
+
return True
|
|
690
|
+
|
|
691
|
+
# Check for standard sections with colons (e.g., "Params:", "Returns:")
|
|
692
|
+
pattern = rf"^[ \t]*{re.escape(section_name)}:[ \t]*$"
|
|
693
|
+
if re.search(pattern, docstring, re.IGNORECASE | re.MULTILINE):
|
|
694
|
+
return True
|
|
695
|
+
|
|
696
|
+
return False
|
|
697
|
+
|
|
698
|
+
def _validate_single_section_content(
|
|
655
699
|
self, docstring: str, section: SectionConfig, item: FunctionAndClassDetails
|
|
656
700
|
) -> Optional[str]:
|
|
657
701
|
"""
|
|
658
702
|
!!! note "Summary"
|
|
659
|
-
Validate
|
|
703
|
+
Validate the content of a single section based on its type.
|
|
660
704
|
|
|
661
705
|
Params:
|
|
662
706
|
docstring (str):
|
|
663
707
|
The docstring to validate.
|
|
664
708
|
section (SectionConfig):
|
|
665
|
-
The section configuration.
|
|
709
|
+
The section configuration to validate against.
|
|
666
710
|
item (FunctionAndClassDetails):
|
|
667
711
|
The function or class details.
|
|
668
712
|
|
|
669
713
|
Returns:
|
|
670
714
|
(Optional[str]):
|
|
671
|
-
Error message if
|
|
715
|
+
Error message if validation fails, None otherwise.
|
|
672
716
|
"""
|
|
673
717
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if section_name == "params" and isinstance(item.node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
677
|
-
# Check params section exists and is properly formatted
|
|
678
|
-
if not self._check_params_section(docstring, item.node):
|
|
679
|
-
return "Missing or invalid Params section"
|
|
680
|
-
|
|
681
|
-
# If validate_param_types is enabled, validate type annotations match
|
|
682
|
-
if self.config.global_config.validate_param_types:
|
|
683
|
-
type_error: Optional[str] = self._validate_param_types(docstring, item.node)
|
|
684
|
-
if type_error:
|
|
685
|
-
return type_error
|
|
718
|
+
if section.type == "list_name_and_type":
|
|
719
|
+
return self._validate_list_name_and_type_section(docstring, section, item)
|
|
686
720
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
return "Missing or invalid Returns section"
|
|
721
|
+
if section.type == "list_name":
|
|
722
|
+
return self._validate_list_name_section(docstring, section)
|
|
690
723
|
|
|
724
|
+
# For `section.type in ("free_text", "list_type")`
|
|
725
|
+
# these sections do not need content validation beyond existence
|
|
691
726
|
return None
|
|
692
727
|
|
|
693
|
-
def
|
|
728
|
+
def _validate_list_name_and_type_section(
|
|
729
|
+
self, docstring: str, section: SectionConfig, item: FunctionAndClassDetails
|
|
730
|
+
) -> Optional[str]:
|
|
694
731
|
"""
|
|
695
732
|
!!! note "Summary"
|
|
696
|
-
Validate
|
|
733
|
+
Validate list_name_and_type sections (params, returns).
|
|
697
734
|
|
|
698
735
|
Params:
|
|
699
736
|
docstring (str):
|
|
700
737
|
The docstring to validate.
|
|
701
738
|
section (SectionConfig):
|
|
702
739
|
The section configuration.
|
|
740
|
+
item (FunctionAndClassDetails):
|
|
741
|
+
The function or class details.
|
|
703
742
|
|
|
704
743
|
Returns:
|
|
705
744
|
(Optional[str]):
|
|
@@ -708,12 +747,20 @@ class DocstringChecker:
|
|
|
708
747
|
|
|
709
748
|
section_name: str = section.name.lower()
|
|
710
749
|
|
|
711
|
-
if section_name
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
750
|
+
if section_name == "params" and isinstance(item.node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
751
|
+
# Check params section exists and is properly formatted with detailed error reporting
|
|
752
|
+
is_valid, error_message = self._check_params_section_detailed(docstring, item.node)
|
|
753
|
+
if not is_valid:
|
|
754
|
+
return error_message
|
|
755
|
+
|
|
756
|
+
# If validate_param_types is enabled, validate type annotations match
|
|
757
|
+
if self.config.global_config.validate_param_types:
|
|
758
|
+
type_error: Optional[str] = self._validate_param_types(docstring, item.node)
|
|
759
|
+
if type_error:
|
|
760
|
+
return type_error
|
|
761
|
+
|
|
762
|
+
# For returns/return sections, no additional validation beyond existence
|
|
763
|
+
# The _section_exists check already verified the section is present
|
|
717
764
|
|
|
718
765
|
return None
|
|
719
766
|
|
|
@@ -732,8 +779,8 @@ class DocstringChecker:
|
|
|
732
779
|
(Optional[str]):
|
|
733
780
|
Error message if section is missing, None otherwise.
|
|
734
781
|
"""
|
|
735
|
-
|
|
736
|
-
|
|
782
|
+
# No additional validation beyond existence
|
|
783
|
+
# The _section_exists check already verified the section is present
|
|
737
784
|
return None
|
|
738
785
|
|
|
739
786
|
def _perform_comprehensive_validation(self, docstring: str) -> list[str]:
|
|
@@ -879,6 +926,113 @@ class DocstringChecker:
|
|
|
879
926
|
|
|
880
927
|
return True
|
|
881
928
|
|
|
929
|
+
def _extract_documented_params(self, docstring: str) -> list[str]:
|
|
930
|
+
"""
|
|
931
|
+
!!! note "Summary"
|
|
932
|
+
Extract parameter names from the Params section of a docstring.
|
|
933
|
+
|
|
934
|
+
Params:
|
|
935
|
+
docstring (str):
|
|
936
|
+
The docstring to parse.
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
(list[str]):
|
|
940
|
+
List of parameter names found in the Params section.
|
|
941
|
+
"""
|
|
942
|
+
documented_params: list[str] = []
|
|
943
|
+
param_pattern: str = r"^\s*(\w+)\s*\([^)]+\):"
|
|
944
|
+
lines: list[str] = docstring.split("\n")
|
|
945
|
+
in_params_section: bool = False
|
|
946
|
+
|
|
947
|
+
for line in lines:
|
|
948
|
+
# Check if we've entered the Params section
|
|
949
|
+
if "Params:" in line:
|
|
950
|
+
in_params_section = True
|
|
951
|
+
continue
|
|
952
|
+
|
|
953
|
+
# Check if we've left the Params section (next section starts)
|
|
954
|
+
if in_params_section and re.match(r"^[ ]{0,4}[A-Z]\w+:", line):
|
|
955
|
+
break
|
|
956
|
+
|
|
957
|
+
# Extract parameter name
|
|
958
|
+
if in_params_section:
|
|
959
|
+
match = re.match(param_pattern, line)
|
|
960
|
+
if match:
|
|
961
|
+
documented_params.append(match.group(1))
|
|
962
|
+
|
|
963
|
+
return documented_params
|
|
964
|
+
|
|
965
|
+
def _build_param_mismatch_error(self, missing_in_docstring: list[str], extra_in_docstring: list[str]) -> str:
|
|
966
|
+
"""
|
|
967
|
+
!!! note "Summary"
|
|
968
|
+
Build detailed error message for parameter mismatches.
|
|
969
|
+
|
|
970
|
+
Params:
|
|
971
|
+
missing_in_docstring (list[str]):
|
|
972
|
+
Parameters in signature but not in docstring.
|
|
973
|
+
extra_in_docstring (list[str]):
|
|
974
|
+
Parameters in docstring but not in signature.
|
|
975
|
+
|
|
976
|
+
Returns:
|
|
977
|
+
(str):
|
|
978
|
+
Formatted error message.
|
|
979
|
+
"""
|
|
980
|
+
error_parts: list[str] = []
|
|
981
|
+
|
|
982
|
+
if missing_in_docstring:
|
|
983
|
+
missing_str: str = "', '".join(missing_in_docstring)
|
|
984
|
+
error_parts.append(f" - In signature but not in docstring: '{missing_str}'")
|
|
985
|
+
|
|
986
|
+
if extra_in_docstring:
|
|
987
|
+
extra_str: str = "', '".join(extra_in_docstring)
|
|
988
|
+
error_parts.append(f" - In docstring but not in signature: '{extra_str}'")
|
|
989
|
+
|
|
990
|
+
return "Parameter mismatch:\n" + "\n".join(error_parts)
|
|
991
|
+
|
|
992
|
+
def _check_params_section_detailed(
|
|
993
|
+
self, docstring: str, node: Union[ast.FunctionDef, ast.AsyncFunctionDef]
|
|
994
|
+
) -> tuple[bool, Optional[str]]:
|
|
995
|
+
"""
|
|
996
|
+
!!! note "Summary"
|
|
997
|
+
Check if the Params section exists and documents all parameters, with detailed error reporting.
|
|
998
|
+
|
|
999
|
+
Params:
|
|
1000
|
+
docstring (str):
|
|
1001
|
+
The docstring to check.
|
|
1002
|
+
node (Union[ast.FunctionDef, ast.AsyncFunctionDef]):
|
|
1003
|
+
The function node to check.
|
|
1004
|
+
|
|
1005
|
+
Returns:
|
|
1006
|
+
(tuple[bool, Optional[str]]):
|
|
1007
|
+
Tuple of (is_valid, error_message). If valid, error_message is None.
|
|
1008
|
+
"""
|
|
1009
|
+
|
|
1010
|
+
# Get function parameters (excluding 'self' and 'cls' for methods)
|
|
1011
|
+
signature_params: list[str] = [arg.arg for arg in node.args.args if arg.arg not in ("self", "cls")]
|
|
1012
|
+
|
|
1013
|
+
if not signature_params:
|
|
1014
|
+
return (True, None) # No parameters to document
|
|
1015
|
+
|
|
1016
|
+
# Check if Params section exists
|
|
1017
|
+
if not re.search(r"Params:", docstring):
|
|
1018
|
+
return (False, "Params section not found in docstring")
|
|
1019
|
+
|
|
1020
|
+
# Extract documented parameters from docstring
|
|
1021
|
+
documented_params: list[str] = self._extract_documented_params(docstring)
|
|
1022
|
+
|
|
1023
|
+
# Find parameters in signature but not in docstring
|
|
1024
|
+
missing_in_docstring: list[str] = [p for p in signature_params if p not in documented_params]
|
|
1025
|
+
|
|
1026
|
+
# Find parameters in docstring but not in signature
|
|
1027
|
+
extra_in_docstring: list[str] = [p for p in documented_params if p not in signature_params]
|
|
1028
|
+
|
|
1029
|
+
# Build detailed error message if there are mismatches
|
|
1030
|
+
if missing_in_docstring or extra_in_docstring:
|
|
1031
|
+
error_message: str = self._build_param_mismatch_error(missing_in_docstring, extra_in_docstring)
|
|
1032
|
+
return (False, error_message)
|
|
1033
|
+
|
|
1034
|
+
return (True, None)
|
|
1035
|
+
|
|
882
1036
|
def _extract_param_types(self, node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> dict[str, str]:
|
|
883
1037
|
"""
|
|
884
1038
|
!!! note "Summary"
|
|
@@ -943,7 +1097,8 @@ class DocstringChecker:
|
|
|
943
1097
|
continue
|
|
944
1098
|
|
|
945
1099
|
# Check if we've left the Params section (next section starts)
|
|
946
|
-
|
|
1100
|
+
# Section headers have minimal indentation (0-4 spaces), not deep indentation like param descriptions
|
|
1101
|
+
if in_params_section and re.match(r"^[ ]{0,4}[A-Z]\w+:", line):
|
|
947
1102
|
break
|
|
948
1103
|
|
|
949
1104
|
# Extract parameter name and type
|
|
@@ -1053,45 +1208,22 @@ class DocstringChecker:
|
|
|
1053
1208
|
mismatches: list[tuple[str, str, str]] = self._compare_param_types(signature_types, docstring_types)
|
|
1054
1209
|
|
|
1055
1210
|
if mismatches:
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
]
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
"""
|
|
1066
|
-
!!! note "Summary"
|
|
1067
|
-
Check if the Returns section exists.
|
|
1068
|
-
|
|
1069
|
-
Params:
|
|
1070
|
-
docstring (str):
|
|
1071
|
-
The docstring to check.
|
|
1072
|
-
|
|
1073
|
-
Returns:
|
|
1074
|
-
(bool):
|
|
1075
|
-
`True` if the section exists, `False` otherwise.
|
|
1076
|
-
"""
|
|
1077
|
-
|
|
1078
|
-
return bool(re.search(r"Returns:", docstring))
|
|
1079
|
-
|
|
1080
|
-
def _check_raises_section(self, docstring: str) -> bool:
|
|
1081
|
-
"""
|
|
1082
|
-
!!! note "Summary"
|
|
1083
|
-
Check if the Raises section exists.
|
|
1211
|
+
# Format each mismatch with parameter name on one line, signature and docstring indented below
|
|
1212
|
+
# Use 2 spaces for params, 4 for sig/doc (suitable for table output)
|
|
1213
|
+
# List output will add additional indentation via CLI formatting
|
|
1214
|
+
mismatch_blocks: list[str] = []
|
|
1215
|
+
for name, sig_type, doc_type in mismatches:
|
|
1216
|
+
sig_type: str = sig_type.replace("'", '"')
|
|
1217
|
+
doc_type: str = doc_type.replace("'", '"')
|
|
1218
|
+
param_block: str = f"""'{name}':\n - signature: '{sig_type}'\n - docstring: '{doc_type}' """
|
|
1219
|
+
mismatch_blocks.append(param_block)
|
|
1084
1220
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
The docstring to check.
|
|
1221
|
+
# Join all parameter blocks with proper indentation
|
|
1222
|
+
formatted_details: str = "\n - ".join([""] + mismatch_blocks)
|
|
1088
1223
|
|
|
1089
|
-
|
|
1090
|
-
(bool):
|
|
1091
|
-
`True` if the section exists, `False` otherwise.
|
|
1092
|
-
"""
|
|
1224
|
+
return f"Parameter type mismatch:{formatted_details}"
|
|
1093
1225
|
|
|
1094
|
-
return
|
|
1226
|
+
return None
|
|
1095
1227
|
|
|
1096
1228
|
def _has_both_returns_and_yields(self, docstring: str) -> bool:
|
|
1097
1229
|
"""
|
|
@@ -1237,41 +1369,6 @@ class DocstringChecker:
|
|
|
1237
1369
|
|
|
1238
1370
|
return errors
|
|
1239
1371
|
|
|
1240
|
-
def _check_yields_section(self, docstring: str) -> bool:
|
|
1241
|
-
"""
|
|
1242
|
-
!!! note "Summary"
|
|
1243
|
-
Check if the Yields section exists.
|
|
1244
|
-
|
|
1245
|
-
Params:
|
|
1246
|
-
docstring (str):
|
|
1247
|
-
The docstring to check.
|
|
1248
|
-
|
|
1249
|
-
Returns:
|
|
1250
|
-
(bool):
|
|
1251
|
-
`True` if the section exists, `False` otherwise.
|
|
1252
|
-
"""
|
|
1253
|
-
|
|
1254
|
-
return bool(re.search(r"Yields:", docstring))
|
|
1255
|
-
|
|
1256
|
-
def _check_simple_section(self, docstring: str, section_name: str) -> bool:
|
|
1257
|
-
"""
|
|
1258
|
-
!!! note "Summary"
|
|
1259
|
-
Check if a simple named section exists.
|
|
1260
|
-
|
|
1261
|
-
Params:
|
|
1262
|
-
docstring (str):
|
|
1263
|
-
The docstring to check.
|
|
1264
|
-
section_name (str):
|
|
1265
|
-
The name of the section to check for.
|
|
1266
|
-
|
|
1267
|
-
Returns:
|
|
1268
|
-
(bool):
|
|
1269
|
-
`True` if the section exists, `False` otherwise.
|
|
1270
|
-
"""
|
|
1271
|
-
|
|
1272
|
-
pattern: str = rf"{re.escape(section_name)}:"
|
|
1273
|
-
return bool(re.search(pattern, docstring, re.IGNORECASE))
|
|
1274
|
-
|
|
1275
1372
|
def _normalize_section_name(self, section_name: str) -> str:
|
|
1276
1373
|
"""
|
|
1277
1374
|
!!! note "Summary"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|