Beispiel #1
0
    def __init__(self,
                 docstring,
                 config=None,
                 app=None,
                 what='',
                 name='',
                 obj=None,
                 options=None):
        self._config = config
        self._app = app

        if not self._config:
            from sphinx.ext.napoleon import Config
            self._config = self._app and self._app.config or Config()

        if not what:
            if inspect.isclass(obj):
                what = 'class'
            elif inspect.ismodule(obj):
                what = 'module'
            elif isinstance(obj, collections.Callable):
                what = 'function'
            else:
                what = 'object'

        self._what = what
        self._name = name
        self._obj = obj
        self._opt = options
        if isinstance(docstring, string_types):
            docstring = docstring.splitlines()
        self._lines = docstring
        self._line_iter = modify_iter(docstring, modifier=lambda s: s.rstrip())
        self._parsed_lines = []
        self._is_in_section = False
        self._section_indent = 0
        if not hasattr(self, '_directive_sections'):
            self._directive_sections = []
        if not hasattr(self, '_sections'):
            self._sections = {
                'args': self._parse_parameters_section,
                'arguments': self._parse_parameters_section,
                'attributes': self._parse_attributes_section,
                'example': self._parse_examples_section,
                'examples': self._parse_examples_section,
                'keyword args': self._parse_keyword_arguments_section,
                'keyword arguments': self._parse_keyword_arguments_section,
                'methods': self._parse_methods_section,
                'note': self._parse_note_section,
                'notes': self._parse_notes_section,
                'other parameters': self._parse_other_parameters_section,
                'parameters': self._parse_parameters_section,
                'return': self._parse_returns_section,
                'returns': self._parse_returns_section,
                'raises': self._parse_raises_section,
                'references': self._parse_references_section,
                'see also': self._parse_see_also_section,
                'warning': self._parse_warning_section,
                'warnings': self._parse_warning_section,
                'warns': self._parse_warns_section,
                'yield': self._parse_yields_section,
                'yields': self._parse_yields_section,
            }
        self._parse()
 def test_docstrings(self):
     config = Config(napoleon_use_param=False, napoleon_use_rtype=False)
     for docstring, expected in self.docstrings:
         actual = str(NumpyDocstring(dedent(docstring), config))
         expected = dedent(expected)
         self.assertEqual(expected, actual)
Beispiel #3
0
    def __init__(self,
                 docstring: Union[str, List[str]],
                 config: SphinxConfig = None,
                 app: Sphinx = None,
                 what: str = '',
                 name: str = '',
                 obj: Any = None,
                 options: Any = None) -> None:
        self._config = config
        self._app = app

        if not self._config:
            from sphinx.ext.napoleon import Config
            self._config = self._app.config if self._app else Config(
            )  # type: ignore

        if not what:
            if inspect.isclass(obj):
                what = 'class'
            elif inspect.ismodule(obj):
                what = 'module'
            elif callable(obj):
                what = 'function'
            else:
                what = 'object'

        self._what = what
        self._name = name
        self._obj = obj
        self._opt = options
        if isinstance(docstring, str):
            lines = docstring.splitlines()
        else:
            lines = docstring
        self._line_iter = modify_iter(lines, modifier=lambda s: s.rstrip())
        self._parsed_lines = []  # type: List[str]
        self._is_in_section = False
        self._section_indent = 0
        if not hasattr(self, '_directive_sections'):
            self._directive_sections = []  # type: List[str]
        if not hasattr(self, '_sections'):
            self._sections = {
                'args': self._parse_parameters_section,
                'arguments': self._parse_parameters_section,
                'attention': partial(self._parse_admonition, 'attention'),
                'attributes': self._parse_attributes_section,
                'caution': partial(self._parse_admonition, 'caution'),
                'danger': partial(self._parse_admonition, 'danger'),
                'error': partial(self._parse_admonition, 'error'),
                'example': self._parse_examples_section,
                'examples': self._parse_examples_section,
                'hint': partial(self._parse_admonition, 'hint'),
                'important': partial(self._parse_admonition, 'important'),
                'keyword args': self._parse_keyword_arguments_section,
                'keyword arguments': self._parse_keyword_arguments_section,
                'methods': self._parse_methods_section,
                'note': partial(self._parse_admonition, 'note'),
                'notes': self._parse_notes_section,
                'other parameters': self._parse_other_parameters_section,
                'parameters': self._parse_parameters_section,
                'receive': self._parse_receives_section,
                'receives': self._parse_receives_section,
                'return': self._parse_returns_section,
                'returns': self._parse_returns_section,
                'raise': self._parse_raises_section,
                'raises': self._parse_raises_section,
                'references': self._parse_references_section,
                'see also': self._parse_see_also_section,
                'tip': partial(self._parse_admonition, 'tip'),
                'todo': partial(self._parse_admonition, 'todo'),
                'warning': partial(self._parse_admonition, 'warning'),
                'warnings': partial(self._parse_admonition, 'warning'),
                'warn': self._parse_warns_section,
                'warns': self._parse_warns_section,
                'yield': self._parse_yields_section,
                'yields': self._parse_yields_section,
            }  # type: Dict[str, Callable]

        self._load_custom_sections()

        self._parse()
    def test_raises_types(self):
        docstrings = [("""
Example Function

Raises
------
  RuntimeError

      A setting wasn't specified, or was invalid.
  ValueError

      Something something value error.

""", """
Example Function

:raises: * :exc:`RuntimeError` -- A setting wasn't specified, or was invalid.
         * :exc:`ValueError` -- Something something value error.
"""),
                      ################################
                      ("""
Example Function

Raises
------
InvalidDimensionsError

""", """
Example Function

:raises: :exc:`InvalidDimensionsError`
"""),
                      ################################
                      ("""
Example Function

Raises
------
Invalid Dimensions Error

""", """
Example Function

:raises: Invalid Dimensions Error
"""),
                      ################################
                      ("""
Example Function

Raises
------
Invalid Dimensions Error
    With description

""", """
Example Function

:raises: *Invalid Dimensions Error* -- With description
"""),
                      ################################
                      ("""
Example Function

Raises
------
InvalidDimensionsError
    If the dimensions couldn't be parsed.

""", """
Example Function

:raises: :exc:`InvalidDimensionsError` -- If the dimensions couldn't be parsed.
"""),
                      ################################
                      ("""
Example Function

Raises
------
Invalid Dimensions Error
    If the dimensions couldn't be parsed.

""", """
Example Function

:raises: *Invalid Dimensions Error* -- If the dimensions couldn't be parsed.
"""),
                      ################################
                      ("""
Example Function

Raises
------
If the dimensions couldn't be parsed.

""", """
Example Function

:raises: If the dimensions couldn't be parsed.
"""),
                      ################################
                      ("""
Example Function

Raises
------
:class:`exc.InvalidDimensionsError`

""", """
Example Function

:raises: :class:`exc.InvalidDimensionsError`
"""),
                      ################################
                      ("""
Example Function

Raises
------
:class:`exc.InvalidDimensionsError`
    If the dimensions couldn't be parsed.

""", """
Example Function

:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
                          """be parsed.
"""),
                      ################################
                      ("""
Example Function

Raises
------
:class:`exc.InvalidDimensionsError`
    If the dimensions couldn't be parsed,
    then a :class:`exc.InvalidDimensionsError` will be raised.

""", """
Example Function

:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
                          """be parsed,
         then a :class:`exc.InvalidDimensionsError` will be raised.
"""),
                      ################################
                      ("""
Example Function

Raises
------
:class:`exc.InvalidDimensionsError`
    If the dimensions couldn't be parsed.
:class:`exc.InvalidArgumentsError`
    If the arguments are invalid.

""", """
Example Function

:raises: * :class:`exc.InvalidDimensionsError` -- If the dimensions """
                          """couldn't be parsed.
         * :class:`exc.InvalidArgumentsError` -- If the arguments """
                          """are invalid.
"""),
                      ################################
                      ("""
Example Function

Raises
------
:class:`exc.InvalidDimensionsError`
:class:`exc.InvalidArgumentsError`

""", """
Example Function

:raises: * :class:`exc.InvalidDimensionsError`
         * :class:`exc.InvalidArgumentsError`
""")]
        for docstring, expected in docstrings:
            config = Config()
            app = mock.Mock()
            actual = str(NumpyDocstring(docstring, config, app, "method"))
            self.assertEqual(expected, actual)
    def test_list_in_parameter_description(self):
        docstring = """One line summary.

Parameters:
    no_list (int):
    one_bullet_empty (int):
        *
    one_bullet_single_line (int):
        - first line
    one_bullet_two_lines (int):
        +   first line
            continued
    two_bullets_single_line (int):
        -  first line
        -  second line
    two_bullets_two_lines (int):
        * first line
          continued
        * second line
          continued
    one_enumeration_single_line (int):
        1.  first line
    one_enumeration_two_lines (int):
        1)   first line
             continued
    two_enumerations_one_line (int):
        (iii) first line
        (iv) second line
    two_enumerations_two_lines (int):
        a. first line
           continued
        b. second line
           continued
    one_definition_one_line (int):
        item 1
            first line
    one_definition_two_lines (int):
        item 1
            first line
            continued
    two_definitions_one_line (int):
        item 1
            first line
        item 2
            second line
    two_definitions_two_lines (int):
        item 1
            first line
            continued
        item 2
            second line
            continued
    one_definition_blank_line (int):
        item 1

            first line

            extra first line

    two_definitions_blank_lines (int):
        item 1

            first line

            extra first line

        item 2

            second line

            extra second line

    definition_after_inline_text (int): text line

        item 1
            first line

    definition_after_normal_text (int):
        text line

        item 1
            first line
"""

        expected = """One line summary.

:param no_list:
:type no_list: int
:param one_bullet_empty:
                         *
:type one_bullet_empty: int
:param one_bullet_single_line:
                               - first line
:type one_bullet_single_line: int
:param one_bullet_two_lines:
                             +   first line
                                 continued
:type one_bullet_two_lines: int
:param two_bullets_single_line:
                                -  first line
                                -  second line
:type two_bullets_single_line: int
:param two_bullets_two_lines:
                              * first line
                                continued
                              * second line
                                continued
:type two_bullets_two_lines: int
:param one_enumeration_single_line:
                                    1.  first line
:type one_enumeration_single_line: int
:param one_enumeration_two_lines:
                                  1)   first line
                                       continued
:type one_enumeration_two_lines: int
:param two_enumerations_one_line:
                                  (iii) first line
                                  (iv) second line
:type two_enumerations_one_line: int
:param two_enumerations_two_lines:
                                   a. first line
                                      continued
                                   b. second line
                                      continued
:type two_enumerations_two_lines: int
:param one_definition_one_line:
                                item 1
                                    first line
:type one_definition_one_line: int
:param one_definition_two_lines:
                                 item 1
                                     first line
                                     continued
:type one_definition_two_lines: int
:param two_definitions_one_line:
                                 item 1
                                     first line
                                 item 2
                                     second line
:type two_definitions_one_line: int
:param two_definitions_two_lines:
                                  item 1
                                      first line
                                      continued
                                  item 2
                                      second line
                                      continued
:type two_definitions_two_lines: int
:param one_definition_blank_line:
                                  item 1

                                      first line

                                      extra first line
:type one_definition_blank_line: int
:param two_definitions_blank_lines:
                                    item 1

                                        first line

                                        extra first line

                                    item 2

                                        second line

                                        extra second line
:type two_definitions_blank_lines: int
:param definition_after_inline_text: text line

                                     item 1
                                         first line
:type definition_after_inline_text: int
:param definition_after_normal_text: text line

                                     item 1
                                         first line
:type definition_after_normal_text: int
"""
        config = Config(napoleon_use_param=True)
        actual = str(GoogleDocstring(docstring, config))
        self.assertEqual(expected, actual)

        expected = """One line summary.

:Parameters: * **no_list** (*int*)
             * **one_bullet_empty** (*int*) --

               *
             * **one_bullet_single_line** (*int*) --

               - first line
             * **one_bullet_two_lines** (*int*) --

               +   first line
                   continued
             * **two_bullets_single_line** (*int*) --

               -  first line
               -  second line
             * **two_bullets_two_lines** (*int*) --

               * first line
                 continued
               * second line
                 continued
             * **one_enumeration_single_line** (*int*) --

               1.  first line
             * **one_enumeration_two_lines** (*int*) --

               1)   first line
                    continued
             * **two_enumerations_one_line** (*int*) --

               (iii) first line
               (iv) second line
             * **two_enumerations_two_lines** (*int*) --

               a. first line
                  continued
               b. second line
                  continued
             * **one_definition_one_line** (*int*) --

               item 1
                   first line
             * **one_definition_two_lines** (*int*) --

               item 1
                   first line
                   continued
             * **two_definitions_one_line** (*int*) --

               item 1
                   first line
               item 2
                   second line
             * **two_definitions_two_lines** (*int*) --

               item 1
                   first line
                   continued
               item 2
                   second line
                   continued
             * **one_definition_blank_line** (*int*) --

               item 1

                   first line

                   extra first line
             * **two_definitions_blank_lines** (*int*) --

               item 1

                   first line

                   extra first line

               item 2

                   second line

                   extra second line
             * **definition_after_inline_text** (*int*) -- text line

               item 1
                   first line
             * **definition_after_normal_text** (*int*) -- text line

               item 1
                   first line
"""
        config = Config(napoleon_use_param=False)
        actual = str(GoogleDocstring(docstring, config))
        self.assertEqual(expected, actual)
Beispiel #6
0
def command_doc(module):
    """
    Document command classes
    """

    mod = importlib.import_module(module)

    print(".. automodule:: {}".format(module))

    config =  Config()
    cls_str = """.. py:function:: {}{}
    {}

        .. rubric:: Available entries:

    {}  

        .. rubric:: Available events:

    {}

    """

    cmd_str = """.. py:function:: {}{}
    {}
    """

    cls_str = inspect.cleandoc(cls_str)
    cmd_str = inspect.cleandoc(cmd_str)

    def indent_text(txt, num=4):
        return "\n".join((num * " ") + i for i in txt)

    def doc_process(docstr, obj, retval=True, indent=4,
                        config=config, docstring=docstring,
                        inspect=inspect, process_docstring=process_docstring,
                        indent_text=indent_text):
        docstr = docstring.GoogleDocstring(inspect.cleandoc(docstr), config, obj=obj)
        docslines = str(docstr).splitlines()
        process_docstring(None, '', '', obj, config, docslines)
        if docslines:
            r = docslines.pop(0)
            # put rtype last
            if retval:
                docslines.append(r)

        # indent
        if indent:
            docstr = indent_text(docslines, indent)
        else:
            docstr = "\n".join(docslines)
        return docstr

    for name, obj in inspect.getmembers(mod, inspect.isclass):
        if not obj.__name__.startswith('_') and obj.__module__ == mod.__name__ and issubclass(obj, command.CoreCommand):
            if getattr(obj, 'main', False):
                objfunc = obj.main
            else:
                objfunc = obj.__init__

            sig = sinspect.Signature(objfunc, bound_method=True)
            obj._get_commands()
            entries = []
            events = []
            e_objfunc = None
            for x, e in sorted(obj._entries.items()):
                esig = sinspect.Signature(objfunc)
                esig.signature = e.signature

                ex_local = {'happypanda': happypanda, 'collections': collections}
                ex_local.update(mod.__dict__)
                ex_local.update(globals())
                exec("def e_objfunc{}:None".format(esig.signature), ex_local, ex_local)
                e_objfunc = ex_local['e_objfunc']

                entries.append("    - {}".format(cmd_str.format(x, esig.format_args(), str(doc_process(e.__doc__, e_objfunc, False, indent=8)))))

            for x, e in sorted(obj._events.items()):

                esig = sinspect.Signature(objfunc)
                esig.signature = e.signature

                ex_local = {'happypanda': happypanda, 'collections': collections}
                ex_local.update(mod.__dict__)
                ex_local.update(globals())
                exec("def e_objfunc{}:None".format(esig.signature), ex_local, ex_local)
                e_objfunc = ex_local['e_objfunc']

                events.append("    - {}".format(cmd_str.format(x, esig.format_args(), str(doc_process(e.__doc__, e_objfunc, False, indent=8)))))

            retval = sig.signature.return_annotation
            sig.signature = sig.signature.replace(return_annotation=inspect.Signature.empty)


            docstr = doc_process(obj.__doc__, objfunc)

            print(cls_str.format(name, sig.format_args(), str(docstr), '\n'.join(entries), '\n'.join(events)))
Beispiel #7
0
import re
from textwrap import dedent
from types import FunctionType

import pytest
import sphinx
import yaml
from sphinx.ext.napoleon import _skip_member
from sphinx.ext.napoleon import Config
from sphinx.ext.napoleon import docstring
from sphinx.ext.napoleon.docstring import NumpyDocstring

from cfme.utils.log import get_rel_path
from cfme.utils.log import logger

config = Config(napoleon_use_param=True, napoleon_use_rtype=True)


def get_meta(obj):
    doc = getattr(obj, '__doc__') or ''
    p = GoogleDocstring(stripper(doc), config)
    return p.metadata


def pytest_collection_modifyitems(items):
    output = {}
    for item in items:
        item_class = item.location[0]
        item_class = item_class[:item_class.rfind('.')].replace('/', '.')
        item_name = item.location[2]
        item_param = re.findall(r'\.*(\[.*\])', item_name)
Beispiel #8
0
from sherpa.astro import ui

from sphinx.ext.napoleon import Config
from sphinx.ext.napoleon.docstring import NumpyDocstring

__all__ = ("sym_to_rst", "sym_to_sig", "doc_to_rst", "unwanted",
           "find_synonyms")

# Any special configuration for the parsing?
#
# This uses ivar rather than attribute when parsing
# attributes - and I can not easily work out how to process
# the latter.
#
config = Config(napoleon_use_ivar=True)


def sym_to_docstring(name, sym):
    """Return the docstring for the symbol.

    This is needed to work around some subtleties in how models
    are wrapped. It also applies known "corrections" to the docstring.
    Fortunately there are no known required corrections.

    Parameters
    ----------
    name : str
        The name of the symbol
    sym
        The Sherpa symbol.
Beispiel #9
0
 def napoleon_transform(comment):
     config = Config(napoleon_use_rtype=False)
     return str(docstring.GoogleDocstring(comment, config))
Beispiel #10
0
    def inspect_routes(self, app):
        """Inspects the views of Flask.

        :param app: The Flask application.
        :returns: 4-tuple like ``(method, paths, view_func, view_doc)``
        """
        if self.endpoints:
            routes = itertools.chain(*[
                get_routes(app, endpoint, self.order)
                for endpoint in self.endpoints
            ])
        else:
            routes = get_routes(app, order=self.order)

        for method, paths, endpoint in routes:
            try:
                blueprint, _, endpoint_internal = endpoint.rpartition('.')
                if self.blueprints and blueprint not in self.blueprints:
                    continue
                if blueprint in self.undoc_blueprints:
                    continue
            except ValueError:
                pass  # endpoint is not within a blueprint

            if endpoint in self.undoc_endpoints:
                continue

            try:
                static_url_path = app.static_url_path  # Flask 0.7 or higher
            except AttributeError:
                static_url_path = app.static_path  # Flask 0.6 or under
            if ('undoc-static' in self.options and endpoint == 'static'
                    and static_url_path + '/(path:filename)' in paths):
                continue
            view = app.view_functions[endpoint]

            if self.modules and view.__module__ not in self.modules:
                continue

            if self.undoc_modules and view.__module__ in self.modules:
                continue

            view_class = getattr(view, 'view_class', None)
            if view_class is None:
                view_func = view
            else:
                view_func = getattr(view_class, method.lower(), None)

            view_doc = view.__doc__ or ''
            if view_func and view_func.__doc__:
                view_doc = view_func.__doc__

            if not isinstance(view_doc, six.text_type):
                analyzer = ModuleAnalyzer.for_module(view.__module__)
                view_doc = force_decode(view_doc, analyzer.encoding)

            if not view_doc and 'include-empty-docstring' not in self.options:
                continue

            # select section (delimited by http:<method>) corresponding to method
            view_doc = filter_by_method(view_doc, method)

            # convert numpy-style docstrings into RST via napoleon
            from sphinx.ext.napoleon import Config, NumpyDocstring
            view_doc = str(
                NumpyDocstring(
                    '\n'.join(
                        NumpyDocstring('')._dedent(view_doc.split('\n'))),
                    Config()))

            yield (method, paths, view_func, view_doc)