Skip to content
This repository was archived by the owner on Nov 3, 2023. It is now read-only.

Commit c8e81d6

Browse files
committed
Factor out sections extraction.
1 parent 0a78a1d commit c8e81d6

File tree

1 file changed

+52
-42
lines changed

1 file changed

+52
-42
lines changed

src/pydocstyle/checker.py

+52-42
Original file line numberDiff line numberDiff line change
@@ -901,12 +901,13 @@ def _check_google_section(cls, docstring, definition, context):
901901
if capitalized_section in ("Args", "Arguments"):
902902
yield from cls._check_args_section(docstring, definition, context)
903903

904-
@staticmethod
905-
def _get_section_contexts(lines, valid_section_names):
904+
@classmethod
905+
def _get_section_contexts(cls, lines, valid_section_names):
906906
"""Generate `SectionContext` objects for valid sections.
907907
908908
Given a list of `valid_section_names`, generate an
909909
`Iterable[SectionContext]` which provides:
910+
* Convention
910911
* Section Name
911912
* String value of the previous line
912913
* The section line
@@ -918,6 +919,14 @@ def _get_section_contexts(lines, valid_section_names):
918919
"""
919920
lower_section_names = [s.lower() for s in valid_section_names]
920921

922+
convention = (
923+
'numpy'
924+
if valid_section_names == cls.NUMPY_SECTION_NAMES
925+
else 'google'
926+
if valid_section_names == cls.GOOGLE_SECTION_NAMES
927+
else 'unknown'
928+
)
929+
921930
def _suspected_as_section(_line):
922931
result = get_leading_words(_line.lower())
923932
return result in lower_section_names
@@ -930,6 +939,7 @@ def _suspected_as_section(_line):
930939
SectionContext = namedtuple(
931940
'SectionContext',
932941
(
942+
'convention',
933943
'section_name',
934944
'previous_line',
935945
'line',
@@ -943,6 +953,7 @@ def _suspected_as_section(_line):
943953
# `following_lines` member is until the end of the docstring.
944954
contexts = (
945955
SectionContext(
956+
convention,
946957
get_leading_words(lines[i].strip()),
947958
lines[i - 1],
948959
lines[i],
@@ -963,6 +974,7 @@ def _suspected_as_section(_line):
963974
for a, b in pairwise(contexts, None):
964975
end = -1 if b is None else b.original_index
965976
yield SectionContext(
977+
convention,
966978
a.section_name,
967979
a.previous_line,
968980
a.line,
@@ -971,10 +983,33 @@ def _suspected_as_section(_line):
971983
b is None,
972984
)
973985

974-
def _check_numpy_sections(self, lines, definition, docstring):
975-
"""NumPy-style docstring sections checks.
986+
@classmethod
987+
def _get_section_contexts_autodetect(cls, docstring):
988+
"""Generate `SectionContext` objects for valid sections.
989+
990+
Generate `Iterable[SectionContext]` as in `_get_section_contexts`, but
991+
auto-detecting the docstring convention, with preference for 'numpy'.
992+
"""
993+
if not docstring:
994+
return
995+
lines = docstring.split("\n")
996+
if len(lines) < 2:
997+
return
998+
found_numpy = False
999+
for ctx in cls._get_section_contexts(lines, cls.NUMPY_SECTION_NAMES):
1000+
found_numpy = True
1001+
yield ctx
1002+
if found_numpy:
1003+
return
1004+
for ctx in cls._get_section_contexts(lines, cls.GOOGLE_SECTION_NAMES):
1005+
yield ctx
1006+
1007+
@check_for(Definition)
1008+
def check_docstring_sections(self, definition, docstring):
1009+
"""Check for docstring sections.
9761010
977-
Check the general format of a sectioned docstring:
1011+
If a Numpy section is found, check the
1012+
general format of a sectioned Numpy docstring:
9781013
'''This is my one-liner.
9791014
9801015
Short Summary
@@ -987,21 +1022,10 @@ def _check_numpy_sections(self, lines, definition, docstring):
9871022
9881023
'''
9891024
990-
Section names appear in `NUMPY_SECTION_NAMES`.
9911025
Yields all violation from `_check_numpy_section` for each valid
992-
Numpy-style section.
993-
"""
994-
found_any_numpy_section = False
995-
for ctx in self._get_section_contexts(lines, self.NUMPY_SECTION_NAMES):
996-
found_any_numpy_section = True
997-
yield from self._check_numpy_section(docstring, definition, ctx)
1026+
Numpy-style section (as listed in `NUMPY_SECTION_NAMES`).
9981027
999-
return found_any_numpy_section
1000-
1001-
def _check_google_sections(self, lines, definition, docstring):
1002-
"""Google-style docstring section checks.
1003-
1004-
Check the general format of a sectioned docstring:
1028+
Otherwise, check the general format of a sectioned Google docstring:
10051029
'''This is my one-liner.
10061030
10071031
Note:
@@ -1012,32 +1036,18 @@ def _check_google_sections(self, lines, definition, docstring):
10121036
10131037
'''
10141038
1015-
Section names appear in `GOOGLE_SECTION_NAMES`.
10161039
Yields all violation from `_check_google_section` for each valid
1017-
Google-style section.
1040+
Google-style section (as listed in `GOOGLE_SECTION_NAMES`).
10181041
"""
1019-
for ctx in self._get_section_contexts(
1020-
lines, self.GOOGLE_SECTION_NAMES
1021-
):
1022-
yield from self._check_google_section(docstring, definition, ctx)
1023-
1024-
@check_for(Definition)
1025-
def check_docstring_sections(self, definition, docstring):
1026-
"""Check for docstring sections."""
1027-
if not docstring:
1028-
return
1029-
1030-
lines = docstring.split("\n")
1031-
if len(lines) < 2:
1032-
return
1033-
1034-
found_numpy = yield from self._check_numpy_sections(
1035-
lines, definition, docstring
1036-
)
1037-
if not found_numpy:
1038-
yield from self._check_google_sections(
1039-
lines, definition, docstring
1040-
)
1042+
for ctx in self._get_section_contexts_autodetect(docstring):
1043+
if ctx.convention == 'numpy':
1044+
yield from self._check_numpy_section(
1045+
docstring, definition, ctx
1046+
)
1047+
elif ctx.convention == 'google':
1048+
yield from self._check_google_section(
1049+
docstring, definition, ctx
1050+
)
10411051

10421052

10431053
parse = Parser()

0 commit comments

Comments
 (0)