Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
- Numpydoc: Keep indented text before a section's first item in the long description instead of dropping it
- Numpydoc: Split a `Raises` or `Warns` item's head such as `ValueError : if bad.` after its type, taking `if bad.` as the start of the description, instead of making the whole line the type
- Numpydoc: Compose sections and deprecations in the items' order, keeping the blank lines read
- Numpydoc: Accept a title's underline of any length, or of `=` signs
- Epydoc: Match fields only at their header, so field-like text in a description no longer replaces it and a header without its colon no longer stalls the parser (thanks to @akshitkhokhani)
- Epydoc: Take a param's key and kind from its `@param`, `@keyword` or `@ivar` field, instead of `type` when its `@type` field comes first
- Epydoc: Give a name described by two fields, such as `@param x:` and `@ivar x:`, an item for each instead of keeping the last
Expand Down
7 changes: 5 additions & 2 deletions docstring_parser/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@

# Any line that could start a field or a section in some style: a ReST
# ``:field``, an Epydoc ``@field``, a Google title ending in a colon, or a
# Numpydoc dashes underline or ``..`` directive.
# Numpydoc underline of dashes or equals signs, or ``..`` directive.
_FIELD_LINE = re.compile(
r"^[^\S\n]*[:@]" r"|:[^\S\n]*$" r"|^[^\S\n]*-+[^\S\n]*$" r"|^[^\S\n]*\.\.",
r"^[^\S\n]*[:@]"
r"|:[^\S\n]*$"
r"|^[^\S\n]*(?:-+|=+)[^\S\n]*$"
r"|^[^\S\n]*\.\.",
flags=re.M,
)

Expand Down
33 changes: 28 additions & 5 deletions docstring_parser/numpydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class Section:

:param title: section title. For most sections, this is a heading like
"Parameters" which appears on its own line, underlined by
en-dashes ('-') on the following line.
dashes ('-') or equals signs ('=') on the following line.
:param key: meta key string. In the parsed ``DocstringMeta`` instance this
is the ``key`` of the parsed ``DocstringMeta``.
"""
Expand All @@ -172,8 +172,9 @@ def _title_pattern(self) -> str:
"""
if self._spec is not None and self._spec.bare:
return rf"^({re.escape(self.title)})[ \t]*$"
dashes = "-" * len(self.title)
return rf"^({re.escape(self.title)})\s*?\n{dashes}\s*$"
# As in napoleon, the underline may be shorter or longer than the
# title, and made of equals signs as a ReST heading's may be.
return rf"^({re.escape(self.title)})\s*?\n(?:-{{2,}}|={{2,}})\s*$"

def _parse(self, text: str) -> T.Iterable[DocstringMeta]:
"""Parse ``DocstringMeta`` objects from the body of this section.
Expand Down Expand Up @@ -660,11 +661,33 @@ def process_one(
head = None

if isinstance(one, DocstringParam) and written is not None:
head = f"{one.arg_name} : {written}"
# With no name, a space before the colon would indent the line.
head = (
f"{one.arg_name} : {written}"
if one.arg_name
else f": {written}"
)
elif one.type_name and head:
head += f" : {one.type_name}"
elif one.type_name:
head = one.type_name
# A colon on the first line of a return's type would read back
# as one after its name, unless a colon before it says there
# is none.
if (
isinstance(one, DocstringReturns)
and ":" in one.type_name.split("\n", 1)[0]
):
head = f": {one.type_name}"
else:
head = one.type_name
elif (
isinstance(one, DocstringReturns)
and head
and one.type_name is not None
):
# A return's name alone would read back as its type; the colon
# after it says the type is empty.
head += " :"
elif not head:
head = ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,53 @@

=== parse numpydoc
short_description: 'Computes the bins used internally by `histogram`.'
long_description: |
Parameters
==========
a : ndarray
Ravelled data array
bins, range
Forwarded arguments from `histogram`.
weights : ndarray, optional
Ravelled weights array, or None

Returns
=======
bin_edges : ndarray
Array of bin edges
uniform_bins : (Number, Number, int):
The upper bound, lowerbound, and number of bins, used in the optimized
implementation of `histogram` that works on uniform bins.
blank_after_short_description: True
blank_after_long_description: False
style: numpydoc
- DocstringParam
description: 'Ravelled data array'
kind: param
key: 'param'
arg_name: 'a'
type_name: 'ndarray'
is_optional: False
- DocstringParam
description: 'Forwarded arguments from `histogram`.'
kind: param
key: 'param'
arg_name: 'bins, range'
is_optional: False
- DocstringParam
description: 'Ravelled weights array, or None'
kind: param
key: 'param'
arg_name: 'weights'
type_name: 'ndarray'
is_optional: True
raw_type_name: 'ndarray, optional'
- DocstringReturns
description: 'Array of bin edges'
kind: returns
key: 'returns'
type_name: 'ndarray'
is_generator: False
return_name: 'bin_edges'
- DocstringReturns
description: |
The upper bound, lowerbound, and number of bins, used in the optimized
implementation of `histogram` that works on uniform bins.
kind: returns
key: 'returns'
type_name: '(Number, Number, int):'
is_generator: False
return_name: 'uniform_bins'
=== detect
rest
numpydoc
=== compose numpydoc
Computes the bins used internally by `histogram`.

Parameters
==========
----------
a : ndarray
Ravelled data array
bins, range
Expand All @@ -57,7 +77,7 @@ weights : ndarray, optional
Ravelled weights array, or None

Returns
=======
-------
bin_edges : ndarray
Array of bin edges
uniform_bins : (Number, Number, int):
Expand Down
38 changes: 38 additions & 0 deletions docstring_parser/tests/cases/numpydoc/compose_returns_01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Test that compose keeps a return's empty type, and a colon in its type.
=== input
Short.

Returns
-------
total :
The total.
: a: b
Odd.
=== parse numpydoc
short_description: 'Short.'
blank_after_short_description: True
blank_after_long_description: False
style: numpydoc
- DocstringReturns
description: 'The total.'
kind: returns
key: 'returns'
type_name: ''
is_generator: False
return_name: 'total'
- DocstringReturns
description: 'Odd.'
kind: returns
key: 'returns'
type_name: 'a: b'
is_generator: False
return_name: ''
=== compose numpydoc
Short.

Returns
-------
total :
The total.
: a: b
Odd.
43 changes: 43 additions & 0 deletions docstring_parser/tests/cases/numpydoc/underline_01.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Test that a title's underline may be shorter or longer than the title.
=== input
Short.

Parameters
---
x : int
The x.

Returns
--------------
int
The sum.
=== parse numpydoc
short_description: 'Short.'
blank_after_short_description: True
blank_after_long_description: False
style: numpydoc
- DocstringParam
description: 'The x.'
kind: param
key: 'param'
arg_name: 'x'
type_name: 'int'
is_optional: False
- DocstringReturns
description: 'The sum.'
kind: returns
key: 'returns'
type_name: 'int'
is_generator: False
=== compose numpydoc
Short.

Parameters
----------
x : int
The x.

Returns
-------
int
The sum.
45 changes: 45 additions & 0 deletions docstring_parser/tests/cases/numpydoc/underline_02.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Test that a title may be underlined with equals signs.
=== input
Short.

Parameters
==========
x : int
The x.

Returns
=======
int
The sum.
=== parse numpydoc
short_description: 'Short.'
blank_after_short_description: True
blank_after_long_description: False
style: numpydoc
- DocstringParam
description: 'The x.'
kind: param
key: 'param'
arg_name: 'x'
type_name: 'int'
is_optional: False
- DocstringReturns
description: 'The sum.'
kind: returns
key: 'returns'
type_name: 'int'
is_generator: False
=== detect
numpydoc
=== compose numpydoc
Short.

Parameters
----------
x : int
The x.

Returns
-------
int
The sum.
Loading