Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX parsing of type-only return params #175

Merged
merged 1 commit into from Apr 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 16 additions & 9 deletions numpydoc/docscrape.py
Expand Up @@ -220,15 +220,18 @@ 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():
header = r.read().strip()
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)
Expand Down Expand Up @@ -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':
Expand Down Expand Up @@ -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 += ['']
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
25 changes: 13 additions & 12 deletions numpydoc/docscrape_sphinx.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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'),
Expand Down
36 changes: 19 additions & 17 deletions numpydoc/tests/test_docscrape.py
Expand Up @@ -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()


Expand All @@ -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_
Expand Down Expand Up @@ -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:
Expand All @@ -608,12 +608,12 @@ def test_sphinx_str():

:Raises:

**RuntimeError**
RuntimeError
Some error

:Warns:

**RuntimeWarning**
RuntimeWarning
Some warning

.. warning::
Expand Down Expand Up @@ -687,7 +687,7 @@ def test_sphinx_yields_str():
**b** : int
The number of bananas.

**int**
int
The number of unknowns.
""")

Expand Down Expand Up @@ -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():
Expand Down Expand Up @@ -995,7 +997,7 @@ def test_use_blockquotes():

GHI

**JKL**
JKL

MNO
''')
Expand Down