xdoctest.docstr.docscrape_google module¶
Handles parsing of information out of google style docstrings
It is not clear which of these GoogleStyleDocs1 GoogleStyleDocs2 is the standard or if there is one.
This code has been exported to a standalone package
This is similar to:
It hasn’t been decided if this will remain vendored in xdoctest or pulled in as a dependency.
References
https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google
http://www.sphinx-doc.org/en/stable/ext/example_google.html#example-google
- class xdoctest.docstr.docscrape_google.DocBlock(text, offset)¶
Bases:
tuple
Create new instance of DocBlock(text, offset)
- offset¶
Alias for field number 1
- text¶
Alias for field number 0
- xdoctest.docstr.docscrape_google.split_google_docblocks(docstr)[source]¶
Breaks a docstring into parts defined by google style
- Parameters:
docstr (str) – a docstring
- Returns:
list of 2-tuples where the first item is a google style docstring tag and the second item is the bock corresponding to that tag. The block itself is a 2-tuple where the first item is the unindented text and the second item is the line offset indicating that blocks location in the docstring.
- Return type:
Note
Unknown or “freeform” sections are given a generic “__DOC__” tag. A section tag may be specified multiple times.
CommandLine
xdoctest xdoctest.docstr.docscrape_google split_google_docblocks:2
Example
>>> from xdoctest.docstr.docscrape_google import * # NOQA >>> from xdoctest import utils >>> docstr = utils.codeblock( ... ''' ... one line description ... ... multiline ... description ... ... Args: ... foo: bar ... ... Returns: ... None ... ... Example: ... >>> print('eg1') ... eg1 ... ... Example: ... >>> print('eg2') ... eg2 ... ''') >>> groups = split_google_docblocks(docstr) >>> assert len(groups) == 5 >>> [g[0] for g in groups] ['__DOC__', 'Args', 'Returns', 'Example', 'Example']
Example
>>> from xdoctest.docstr.docscrape_google import * # NOQA >>> docstr = split_google_docblocks.__doc__ >>> groups = split_google_docblocks(docstr)
Example
>>> from xdoctest.docstr.docscrape_google import * # NOQA >>> from xdoctest import utils >>> docstr = utils.codeblock( ... ''' ... a description with a leading space ... ... Example: ... >>> foobar ... ''') >>> groups = split_google_docblocks(docstr) >>> print('groups = {!r}'.format(groups))
Example
>>> from xdoctest.docstr.docscrape_google import * # NOQA >>> from xdoctest import utils >>> docstr = utils.codeblock( ... ''' ... Example: ... >>> foobar ... ''') >>> # Check that line offsets are valid if the first line is not blank >>> groups = split_google_docblocks(docstr) >>> offset = groups[0][1][1] >>> print('offset = {!r}'.format(offset)) >>> assert offset == 0 >>> # Check that line offsets are valid if the first line is blank >>> groups = split_google_docblocks(chr(10) + docstr) >>> offset = groups[0][1][1] >>> print('offset = {!r}'.format(offset)) >>> assert offset == 1
- xdoctest.docstr.docscrape_google.parse_google_args(docstr)[source]¶
Generates dictionaries of argument hints based on a google docstring
- Parameters:
docstr (str) – a google-style docstring
- Yields:
Dict[str, str] – dictionaries of parameter hints
Example
>>> docstr = parse_google_args.__doc__ >>> argdict_list = list(parse_google_args(docstr)) >>> print([sorted(d.items()) for d in argdict_list]) [[('desc', 'a google-style docstring'), ('name', 'docstr'), ('type', 'str')]]
- xdoctest.docstr.docscrape_google.parse_google_returns(docstr, return_annot=None)[source]¶
Generates dictionaries of possible return hints based on a google docstring
- Parameters:
docstr (str) – a google-style docstring
return_annot (str | None) – the return type annotation (if one exists)
- Yields:
Dict[str, str] – dictionaries of return value hints
Example
>>> docstr = parse_google_returns.__doc__ >>> retdict_list = list(parse_google_returns(docstr)) >>> print([sorted(d.items()) for d in retdict_list]) [[('desc', 'dictionaries of return value hints'), ('type', 'Dict[str, str]')]]
Example
>>> docstr = split_google_docblocks.__doc__ >>> retdict_list = list(parse_google_returns(docstr)) >>> print([sorted(d.items())[1] for d in retdict_list]) [('type', 'List[Tuple[str, DocBlock]]')]
- xdoctest.docstr.docscrape_google.parse_google_retblock(lines, return_annot=None)[source]¶
Parse information out of a returns or yeilds block.
A returns or yeids block should be formatted as one or more
'{type}:{description}'
strings. The description can occupy multiple lines, but the indentation should increase.- Parameters:
lines (str) – unindented lines from a Returns or Yields section
return_annot (str | None) – the return type annotation (if one exists)
- Yields:
Dict[str, str] – each dict specifies the return type and its description
Example
>>> # Test various ways that retlines can be written >>> assert len(list(parse_google_retblock('list: a desc'))) == 1 >>> # --- >>> hints = list(parse_google_retblock('\n'.join([ ... 'entire line can be desc', ... ' ', ... ' if a return type annotation is given', ... ]), return_annot='int')) >>> assert len(hints) == 1 >>> # --- >>> hints = list(parse_google_retblock('\n'.join([ ... 'bool: a description', ... ' with a newline', ... ]))) >>> assert len(hints) == 1 >>> # --- >>> hints = list(parse_google_retblock('\n'.join([ ... 'int or bool: a description', ... ' ', ... ' with a separated newline', ... ' ', ... ]))) >>> assert len(hints) == 1 >>> # --- >>> hints = list(parse_google_retblock('\n'.join([ ... # Multiple types can be specified ... 'threading.Thread: a description', ... '(int, str): a tuple of int and str', ... 'tuple: a tuple of int and str', ... 'Tuple[int, str]: a tuple of int and str', ... ]))) >>> assert len(hints) == 4 >>> # --- >>> # If the colon is not specified nothing will be parsed >>> # according to the "official" spec, but lets try and do it anyway >>> hints = list(parse_google_retblock('\n'.join([ ... 'list', ... 'Tuple[int, str]', ... ]))) >>> assert len(hints) == 2 >>> assert len(list(parse_google_retblock('no type, just desc'))) == 1 ...
- xdoctest.docstr.docscrape_google.parse_google_argblock(lines, clean_desc=True)[source]¶
Parse out individual items from google-style args blocks.
- Parameters:
lines (str) – the unindented lines from an Args docstring section
clean_desc (bool) – if True, will strip the description of newlines and indents. Defaults to True.
- Yields:
Dict[str, str | None] – A dictionary containing keys, “name”, “type”, and “desc” corresponding to an argument in the Args block.
Example
>>> # Test various ways that arglines can be written >>> line_list = [ ... '', ... 'foo1 (int): a description', ... 'foo2: a description\n with a newline', ... 'foo3 (int or str): a description', ... 'foo4 (int or threading.Thread): a description', ... # ... # this is sphynx-like typing style ... 'param1 (:obj:`str`, optional): ', ... 'param2 (:obj:`list` of :obj:`str`):', ... # ... # the Type[type] syntax is defined by the python typeing module ... 'attr1 (Optional[int]): Description of `attr1`.', ... 'attr2 (List[str]): Description of `attr2`.', ... 'attr3 (Dict[str, str]): Description of `attr3`.', ... '*args : variable positional args description', ... '**kwargs : keyword arguments description', ... 'malformed and unparseable', ... 'param_no_desc1', # todo: this should be parseable ... 'param_no_desc2:', ... 'param_no_desc3 ()', # todo: this should be parseable ... 'param_no_desc4 ():', ... 'param_no_desc5 (str)', # todo: this should be parseable ... 'param_no_desc6 (str):', ... ] >>> lines = '\n'.join(line_list) >>> argdict_list = list(parse_google_argblock(lines)) >>> # All lines except the first should be accepted >>> assert len(argdict_list) == len(line_list) - 5 >>> assert argdict_list[1]['desc'] == 'a description with a newline'