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

Commit 74ca377

Browse files
committed
Factor out sections extraction.
1 parent 8e2bc99 commit 74ca377

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
@@ -960,12 +960,13 @@ def _check_google_section(cls, docstring, definition, context):
960960
if capitalized_section in ("Args", "Arguments"):
961961
yield from cls._check_args_section(docstring, definition, context)
962962

963-
@staticmethod
964-
def _get_section_contexts(lines, valid_section_names):
963+
@classmethod
964+
def _get_section_contexts(cls, lines, valid_section_names):
965965
"""Generate `SectionContext` objects for valid sections.
966966
967967
Given a list of `valid_section_names`, generate an
968968
`Iterable[SectionContext]` which provides:
969+
* Convention
969970
* Section Name
970971
* String value of the previous line
971972
* The section line
@@ -977,6 +978,14 @@ def _get_section_contexts(lines, valid_section_names):
977978
"""
978979
lower_section_names = [s.lower() for s in valid_section_names]
979980

981+
convention = (
982+
'numpy'
983+
if valid_section_names == cls.NUMPY_SECTION_NAMES
984+
else 'google'
985+
if valid_section_names == cls.GOOGLE_SECTION_NAMES
986+
else 'unknown'
987+
)
988+
980989
def _suspected_as_section(_line):
981990
result = get_leading_words(_line.lower())
982991
return result in lower_section_names
@@ -989,6 +998,7 @@ def _suspected_as_section(_line):
989998
SectionContext = namedtuple(
990999
'SectionContext',
9911000
(
1001+
'convention',
9921002
'section_name',
9931003
'previous_line',
9941004
'line',
@@ -1002,6 +1012,7 @@ def _suspected_as_section(_line):
10021012
# `following_lines` member is until the end of the docstring.
10031013
contexts = (
10041014
SectionContext(
1015+
convention,
10051016
get_leading_words(lines[i].strip()),
10061017
lines[i - 1],
10071018
lines[i],
@@ -1022,6 +1033,7 @@ def _suspected_as_section(_line):
10221033
for a, b in pairwise(contexts, None):
10231034
end = -1 if b is None else b.original_index
10241035
yield SectionContext(
1036+
convention,
10251037
a.section_name,
10261038
a.previous_line,
10271039
a.line,
@@ -1030,10 +1042,33 @@ def _suspected_as_section(_line):
10301042
b is None,
10311043
)
10321044

1033-
def _check_numpy_sections(self, lines, definition, docstring):
1034-
"""NumPy-style docstring sections checks.
1045+
@classmethod
1046+
def _get_section_contexts_autodetect(cls, docstring):
1047+
"""Generate `SectionContext` objects for valid sections.
1048+
1049+
Generate `Iterable[SectionContext]` as in `_get_section_contexts`, but
1050+
auto-detecting the docstring convention, with preference for 'numpy'.
1051+
"""
1052+
if not docstring:
1053+
return
1054+
lines = docstring.split("\n")
1055+
if len(lines) < 2:
1056+
return
1057+
found_numpy = False
1058+
for ctx in cls._get_section_contexts(lines, cls.NUMPY_SECTION_NAMES):
1059+
found_numpy = True
1060+
yield ctx
1061+
if found_numpy:
1062+
return
1063+
for ctx in cls._get_section_contexts(lines, cls.GOOGLE_SECTION_NAMES):
1064+
yield ctx
1065+
1066+
@check_for(Definition)
1067+
def check_docstring_sections(self, definition, docstring):
1068+
"""Check for docstring sections.
10351069
1036-
Check the general format of a sectioned docstring:
1070+
If a Numpy section is found, check the
1071+
general format of a sectioned Numpy docstring:
10371072
'''This is my one-liner.
10381073
10391074
Short Summary
@@ -1046,21 +1081,10 @@ def _check_numpy_sections(self, lines, definition, docstring):
10461081
10471082
'''
10481083
1049-
Section names appear in `NUMPY_SECTION_NAMES`.
10501084
Yields all violation from `_check_numpy_section` for each valid
1051-
Numpy-style section.
1052-
"""
1053-
found_any_numpy_section = False
1054-
for ctx in self._get_section_contexts(lines, self.NUMPY_SECTION_NAMES):
1055-
found_any_numpy_section = True
1056-
yield from self._check_numpy_section(docstring, definition, ctx)
1085+
Numpy-style section (as listed in `NUMPY_SECTION_NAMES`).
10571086
1058-
return found_any_numpy_section
1059-
1060-
def _check_google_sections(self, lines, definition, docstring):
1061-
"""Google-style docstring section checks.
1062-
1063-
Check the general format of a sectioned docstring:
1087+
Otherwise, check the general format of a sectioned Google docstring:
10641088
'''This is my one-liner.
10651089
10661090
Note:
@@ -1071,32 +1095,18 @@ def _check_google_sections(self, lines, definition, docstring):
10711095
10721096
'''
10731097
1074-
Section names appear in `GOOGLE_SECTION_NAMES`.
10751098
Yields all violation from `_check_google_section` for each valid
1076-
Google-style section.
1099+
Google-style section (as listed in `GOOGLE_SECTION_NAMES`).
10771100
"""
1078-
for ctx in self._get_section_contexts(
1079-
lines, self.GOOGLE_SECTION_NAMES
1080-
):
1081-
yield from self._check_google_section(docstring, definition, ctx)
1082-
1083-
@check_for(Definition)
1084-
def check_docstring_sections(self, definition, docstring):
1085-
"""Check for docstring sections."""
1086-
if not docstring:
1087-
return
1088-
1089-
lines = docstring.split("\n")
1090-
if len(lines) < 2:
1091-
return
1092-
1093-
found_numpy = yield from self._check_numpy_sections(
1094-
lines, definition, docstring
1095-
)
1096-
if not found_numpy:
1097-
yield from self._check_google_sections(
1098-
lines, definition, docstring
1099-
)
1101+
for ctx in self._get_section_contexts_autodetect(docstring):
1102+
if ctx.convention == 'numpy':
1103+
yield from self._check_numpy_section(
1104+
docstring, definition, ctx
1105+
)
1106+
elif ctx.convention == 'google':
1107+
yield from self._check_google_section(
1108+
docstring, definition, ctx
1109+
)
11001110

11011111

11021112
parse = Parser()

0 commit comments

Comments
 (0)