From 3edcef73ddb756e310089616d51968b89bd58c31 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 3 May 2018 00:28:47 +0200 Subject: [PATCH] FIX parsing of type-only return params --- numpydoc/docscrape.py | 25 ++++++++++++++-------- numpydoc/docscrape_sphinx.py | 25 +++++++++++----------- numpydoc/tests/test_docscrape.py | 36 +++++++++++++++++--------------- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/numpydoc/docscrape.py b/numpydoc/docscrape.py index 02afd88a..32245a97 100644 --- a/numpydoc/docscrape.py +++ b/numpydoc/docscrape.py @@ -220,7 +220,7 @@ def _read_sections(self): else: yield name, self._strip(data[2:]) - def _parse_param_list(self, content): + def _parse_param_list(self, content, single_element_is_type=False): r = Reader(content) params = [] while not r.eof(): @@ -228,7 +228,10 @@ def _parse_param_list(self, content): if ' : ' in header: arg_name, arg_type = header.split(' : ')[:2] else: - arg_name, arg_type = header, '' + if single_element_is_type: + arg_name, arg_type = '', header + else: + arg_name, arg_type = header, '' desc = r.read_to_next_unindented_line() desc = dedent_lines(desc) @@ -393,10 +396,12 @@ def _parse(self): self._error_location("The section %s appears twice" % section) - if section in ('Parameters', 'Returns', 'Yields', 'Receives', - 'Raises', 'Warns', 'Other Parameters', 'Attributes', + if section in ('Parameters', 'Other Parameters', 'Attributes', 'Methods'): self[section] = self._parse_param_list(content) + elif section in ('Returns', 'Yields', 'Raises', 'Warns', 'Receives'): + self[section] = self._parse_param_list( + content, single_element_is_type=True) elif section.startswith('.. index::'): self['index'] = self._parse_index(section, content) elif section == 'See Also': @@ -452,10 +457,12 @@ def _str_param_list(self, name): if self[name]: out += self._str_header(name) for param in self[name]: + parts = [] + if param.name: + parts.append(param.name) if param.type: - out += ['%s : %s' % (param.name, param.type)] - else: - out += [param.name] + parts.append(param.type) + out += [' : '.join(parts)] if param.desc and ''.join(param.desc).strip(): out += self._str_indent(param.desc) out += [''] @@ -637,7 +644,7 @@ def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, if _members is ALL: _members = None _exclude = config.get('exclude-members', []) - + if config.get('show_class_members', True) and _exclude is not ALL: def splitlines_x(s): if not s: @@ -649,7 +656,7 @@ def splitlines_x(s): if not self[field]: doc_list = [] for name in sorted(items): - if (name in _exclude or + if (name in _exclude or (_members and name not in _members)): continue try: diff --git a/numpydoc/docscrape_sphinx.py b/numpydoc/docscrape_sphinx.py index 9b23235a..aad64c73 100644 --- a/numpydoc/docscrape_sphinx.py +++ b/numpydoc/docscrape_sphinx.py @@ -70,19 +70,19 @@ def _str_extended_summary(self): return self['Extended Summary'] + [''] def _str_returns(self, name='Returns'): - typed_fmt = '**%s** : %s' - untyped_fmt = '**%s**' + named_fmt = '**%s** : %s' + unnamed_fmt = '%s' out = [] if self[name]: out += self._str_field_list(name) out += [''] for param in self[name]: - if param.type: - out += self._str_indent([typed_fmt % (param.name.strip(), + if param.name: + out += self._str_indent([named_fmt % (param.name.strip(), param.type)]) else: - out += self._str_indent([untyped_fmt % param.name.strip()]) + out += self._str_indent([unnamed_fmt % param.type.strip()]) if not param.desc: out += self._str_indent(['..'], 8) else: @@ -209,12 +209,13 @@ def _str_param_list(self, name, fake_autosummary=False): display_param, desc = self._process_param(param.name, param.desc, fake_autosummary) - + parts = [] + if display_param: + parts.append(display_param) if param.type: - out += self._str_indent(['%s : %s' % (display_param, - param.type)]) - else: - out += self._str_indent([display_param]) + parts.append(param.type) + out += self._str_indent([' : '.join(parts)]) + if desc and self.use_blockquotes: out += [''] elif not desc: @@ -376,8 +377,8 @@ def __str__(self, indent=0, func_role="obj"): 'yields': self._str_returns('Yields'), 'receives': self._str_returns('Receives'), 'other_parameters': self._str_param_list('Other Parameters'), - 'raises': self._str_param_list('Raises'), - 'warns': self._str_param_list('Warns'), + 'raises': self._str_returns('Raises'), + 'warns': self._str_returns('Warns'), 'warnings': self._str_warnings(), 'see_also': self._str_see_also(func_role), 'notes': self._str_section('Notes'), diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index b4b7e038..e5e3f1f3 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -211,14 +211,14 @@ def test_returns(): assert desc[-1].endswith('distribution.') arg, arg_type, desc = doc['Returns'][1] - assert arg == 'list of str' - assert arg_type == '' + assert arg == '' + assert arg_type == 'list of str' assert desc[0].startswith('This is not a real') assert desc[-1].endswith('anonymous return values.') arg, arg_type, desc = doc['Returns'][2] - assert arg == 'no_description' - assert arg_type == '' + assert arg == '' + assert arg_type == 'no_description' assert not ''.join(desc).strip() @@ -227,7 +227,7 @@ def test_yields(): assert len(section) == 3 truth = [('a', 'int', 'apples.'), ('b', 'int', 'bananas.'), - ('int', '', 'unknowns.')] + ('', 'int', 'unknowns.')] for (arg, arg_type, desc), (arg_, arg_type_, end) in zip(section, truth): assert arg == arg_ assert arg_type == arg_type_ @@ -594,11 +594,11 @@ def test_sphinx_str(): In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. - **list of str** + list of str This is not a real return value. It exists to test anonymous return values. - **no_description** + no_description .. :Other Parameters: @@ -608,12 +608,12 @@ def test_sphinx_str(): :Raises: - **RuntimeError** + RuntimeError Some error :Warns: - **RuntimeWarning** + RuntimeWarning Some warning .. warning:: @@ -687,7 +687,7 @@ def test_sphinx_yields_str(): **b** : int The number of bananas. - **int** + int The number of unknowns. """) @@ -754,16 +754,18 @@ def test_empty_extended_summary(): def test_raises(): assert len(doc5['Raises']) == 1 - name, _, desc = doc5['Raises'][0] - assert name == 'LinAlgException' - assert desc == ['If array is singular.'] + param = doc5['Raises'][0] + assert param.name == '' + assert param.type == 'LinAlgException' + assert param.desc == ['If array is singular.'] def test_warns(): assert len(doc5['Warns']) == 1 - name, _, desc = doc5['Warns'][0] - assert name == 'SomeWarning' - assert desc == ['If needed'] + param = doc5['Warns'][0] + assert param.name == '' + assert param.type == 'SomeWarning' + assert param.desc == ['If needed'] def test_see_also(): @@ -995,7 +997,7 @@ def test_use_blockquotes(): GHI - **JKL** + JKL MNO ''')