diff options
author | Eric Larson <larson.eric.d@gmail.com> | 2019-04-15 12:45:40 -0400 |
---|---|---|
committer | Eric Larson <larson.eric.d@gmail.com> | 2019-04-17 21:22:04 -0400 |
commit | 4c9698e4fdc2bafcad441027ee97bf70131a8585 (patch) | |
tree | 970ca2e6f658074b5b3b1132c9e9a6f772e8f7b0 | |
parent | 807f4e02cdb95e7e4c564b440629aeda5832299a (diff) | |
download | numpydoc-4c9698e4fdc2bafcad441027ee97bf70131a8585.tar.gz |
ENH: Just use obj
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .travis.yml | 12 | ||||
-rw-r--r-- | doc/Makefile | 2 | ||||
-rw-r--r-- | doc/conf.py | 5 | ||||
-rw-r--r-- | doc/example.py | 8 | ||||
-rw-r--r-- | doc/install.rst | 23 | ||||
-rw-r--r-- | numpydoc/docscrape_sphinx.py | 17 | ||||
-rw-r--r-- | numpydoc/numpydoc.py | 12 | ||||
-rw-r--r-- | numpydoc/tests/test_docscrape.py | 38 | ||||
-rw-r--r-- | numpydoc/tests/test_numpydoc.py | 5 | ||||
-rw-r--r-- | numpydoc/tests/test_xref.py | 58 | ||||
-rw-r--r-- | numpydoc/xref.py | 92 |
12 files changed, 136 insertions, 137 deletions
@@ -8,3 +8,4 @@ *.swo build dist +doc/_build diff --git a/.travis.yml b/.travis.yml index c19e178..8ffb2bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,21 @@ # After changing this file, check it on: # http://lint.travis-ci.org/ language: python +dist: xenial sudo: false -env: - - SPHINX_SPEC="Sphinx==1.2.3" - - SPHINX_SPEC="Sphinx" matrix: include: - - python: 3.6 + - python: 3.7 + env: SPHINX_SPEC="==1.2.3" SPHINXOPTS="" + - python: 3.7 - python: 2.7 - env: - - SPHINXOPTS='-W' cache: directories: - $HOME/.cache/pip before_install: - sudo apt-get install texlive texlive-latex-extra latexmk - pip install --upgrade pip setuptools # Upgrade pip and setuptools to get ones with `wheel` support - - pip install pytest numpy matplotlib ${SPHINX_SPEC} + - pip install pytest numpy matplotlib sphinx${SPHINX_SPEC} script: - | python setup.py sdist diff --git a/doc/Makefile b/doc/Makefile index 508376e..0612444 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -nWT --keep-going SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build diff --git a/doc/conf.py b/doc/conf.py index ef2788e..e23939e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -82,6 +82,8 @@ import numpydoc release = numpydoc.__version__ version = re.sub(r'(\d+\.\d+)\.\d+(.*)', r'\1\2', numpydoc.__version__) version = re.sub(r'(\.dev\d+).*?$', r'\1', version) +numpydoc_xref_param_type = True +numpydoc_xref_ignore = {'optional', 'type_without_description', 'BadException'} # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -269,5 +271,6 @@ latex_documents = [ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('http://docs.python.org/', None), - 'scikitlearn': ('http://scikit-learn.org/stable/', None), + 'numpy': ('https://www.numpy.org/devdocs', None), + 'sklearn': ('http://scikit-learn.org/stable/', None), } diff --git a/doc/example.py b/doc/example.py index 1bae2d5..592c2b1 100644 --- a/doc/example.py +++ b/doc/example.py @@ -78,10 +78,10 @@ def foo(var1, var2, long_var_name='hi'): See Also -------- - otherfunc : relationship (optional) - newfunc : Relationship (optional), which could be fairly long, in which - case the line wraps here. - thirdfunc, fourthfunc, fifthfunc + numpy.array : relationship (optional) + numpy.ndarray : Relationship (optional), which could be fairly long, in + which case the line wraps here. + numpy.dot, numpy.linalg.norm, numpy.eye Notes ----- diff --git a/doc/install.rst b/doc/install.rst index 18e22bb..2d2c074 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -70,26 +70,21 @@ numpydoc_xref_aliases : dict intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), 'numpy': ('https://docs.scipy.org/doc/numpy', None), + ... } - A useful ``dict`` may look like the following:: + The default ``numpydoc_xref_aliases`` will supply some common ``Python`` + standard library and ``NumPy`` names for you. Then for your module, a useful + ``dict`` may look like the following (e.g., if you were documenting + :mod:`sklearn.model_selection`):: numpydoc_xref_aliases = { - # python - 'sequence': ':term:`python:sequence`', - 'iterable': ':term:`python:iterable`', - 'string': 'str', - # numpy - 'array': 'numpy.ndarray', - 'dtype': 'numpy.dtype', - 'ndarray': 'numpy.ndarray', - 'matrix': 'numpy.matrix', - 'array-like': ':term:`numpy:array_like`', - 'array_like': ':term:`numpy:array_like`', + 'LeaveOneOut': 'sklearn.model_selection.LeaveOneOut', + ... } - This option depends on the ``numpydoc_xref_param_type`` option - being ``True``. + This option depends on the ``numpydoc_xref_param_type`` option + being ``True``. numpydoc_xref_ignore : set Words not to cross-reference. Most likely, these are common words used in parameter type descriptions that may be confused for diff --git a/numpydoc/docscrape_sphinx.py b/numpydoc/docscrape_sphinx.py index a77390b..a4cc71d 100644 --- a/numpydoc/docscrape_sphinx.py +++ b/numpydoc/docscrape_sphinx.py @@ -17,7 +17,7 @@ import sphinx from sphinx.jinja2glue import BuiltinTemplateLoader from .docscrape import NumpyDocString, FunctionDoc, ClassDoc -from .xref import make_xref_param_type +from .xref import make_xref if sys.version_info[0] >= 3: sixu = lambda s: s @@ -85,7 +85,7 @@ class SphinxDocString(NumpyDocString): for param in self[name]: param_type = param.type if param_type and self.xref_param_type: - param_type = make_xref_param_type( + param_type = make_xref( param_type, self.xref_aliases, self.xref_ignore) @@ -93,7 +93,7 @@ class SphinxDocString(NumpyDocString): out += self._str_indent([named_fmt % (param.name.strip(), param_type)]) else: - out += self._str_indent([unnamed_fmt % param_type.strip()]) + out += self._str_indent([unnamed_fmt % param_type.strip()]) if not param.desc: out += self._str_indent(['..'], 8) else: @@ -168,10 +168,8 @@ class SphinxDocString(NumpyDocString): prefix = getattr(self, '_name', '') if prefix: - autosum_prefix = '~%s.' % prefix link_prefix = '%s.' % prefix else: - autosum_prefix = '' link_prefix = '' # Referenced object has a docstring @@ -227,14 +225,13 @@ class SphinxDocString(NumpyDocString): if param_type: param_type = param.type if self.xref_param_type: - param_type = make_xref_param_type( + param_type = make_xref( param_type, self.xref_aliases, self.xref_ignore) -(??) 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: diff --git a/numpydoc/numpydoc.py b/numpydoc/numpydoc.py index fc713a9..e1b8f26 100644 --- a/numpydoc/numpydoc.py +++ b/numpydoc/numpydoc.py @@ -37,7 +37,7 @@ if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") from .docscrape_sphinx import get_doc_object -from .xref import xref_param_type_role +from .xref import DEFAULT_LINKS from . import __version__ if sys.version_info[0] >= 3: @@ -223,7 +223,7 @@ def setup(app, get_doc_object_=get_doc_object): app.setup_extension('sphinx.ext.autosummary') - app.add_role('xref_param_type', xref_param_type_role) + app.connect('builder-inited', update_config) app.connect('autodoc-process-docstring', mangle_docstrings) app.connect('autodoc-process-signature', mangle_signature) app.connect('doctree-read', relabel_references) @@ -248,6 +248,14 @@ def setup(app, get_doc_object_=get_doc_object): 'parallel_read_safe': True} return metadata + +def update_config(app): + """Update the configuration with default values.""" + for key, value in DEFAULT_LINKS.items(): + if key not in app.config.numpydoc_xref_aliases: + app.config.numpydoc_xref_aliases[key] = value + + # ------------------------------------------------------------------------------ # Docstring-mangling domains # ------------------------------------------------------------------------------ diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index 8bb05d7..f684466 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -1,6 +1,7 @@ # -*- encoding:utf-8 -*- from __future__ import division, absolute_import, print_function +from collections import namedtuple import re import sys import textwrap @@ -8,6 +9,7 @@ import warnings import jinja2 +from numpydoc.numpydoc import update_config from numpydoc.docscrape import ( NumpyDocString, FunctionDoc, @@ -382,11 +384,11 @@ def _strip_blank_lines(s): return s -def line_by_line_compare(a, b): +def line_by_line_compare(a, b, n_lines=None): a = textwrap.dedent(a) b = textwrap.dedent(b) - a = [l.rstrip() for l in _strip_blank_lines(a).split('\n')] - b = [l.rstrip() for l in _strip_blank_lines(b).split('\n')] + a = [l.rstrip() for l in _strip_blank_lines(a).split('\n')][:n_lines] + b = [l.rstrip() for l in _strip_blank_lines(b).split('\n')][:n_lines] assert len(a) == len(b) for ii, (aa, bb) in enumerate(zip(a, b)): assert aa == bb @@ -518,8 +520,7 @@ b : int The number of bananas. int The number of unknowns. - -.. index:: """) +""") def test_receives_str(): @@ -537,8 +538,7 @@ b : int The number of bananas. c : int The number of oranges. - -.. index:: """) +""") def test_no_index_in_str(): @@ -1200,8 +1200,6 @@ def test_class_members_doc(): b c - .. index:: - """) @@ -1422,7 +1420,7 @@ A top section before .. rubric:: Methods - ''') + ''', 5) xref_doc_txt = """ @@ -1442,7 +1440,7 @@ p3 : list[int] List of integers p4 : :class:`pandas.DataFrame` A dataframe -p5 : sequence of int +p5 : sequence of `int` A sequence Returns @@ -1458,37 +1456,39 @@ Test xref in Parameters, Other Parameters and Returns :Parameters: - **p1** : :xref_param_type:`int` + **p1** : :class:`python:int` Integer value - **p2** : :xref_param_type:`float`, optional + **p2** : :class:`python:float`, optional Integer value :Returns: - **out** : :xref_param_type:`array <numpy.ndarray>` + **out** : :obj:`array <numpy.ndarray>` Numerical return value :Other Parameters: - **p3** : :xref_param_type:`list`\[:xref_param_type:`int`] + **p3** : :class:`python:list`\[:class:`python:int`] List of integers **p4** : :class:`pandas.DataFrame` A dataframe - **p5** : :term:`python:sequence` of :xref_param_type:`int` + **p5** : :obj:`python:sequence` of `int` A sequence """ def test_xref(): xref_aliases = { - 'sequence': ':term:`python:sequence`', - 'iterable': ':term:`python:iterable`', - 'array': 'numpy.ndarray', + 'sequence': ':obj:`python:sequence`', } + config = namedtuple('numpydoc_xref_aliases', + 'numpydoc_xref_aliases')(xref_aliases) + app = namedtuple('config', 'config')(config) + update_config(app) xref_ignore = {'of', 'default', 'optional'} diff --git a/numpydoc/tests/test_numpydoc.py b/numpydoc/tests/test_numpydoc.py index 0fd3c37..635a271 100644 --- a/numpydoc/tests/test_numpydoc.py +++ b/numpydoc/tests/test_numpydoc.py @@ -10,6 +10,9 @@ class MockConfig(): numpydoc_show_class_members = True numpydoc_show_inherited_class_members = True numpydoc_class_members_toctree = True + numpydoc_xref_param_type = False + numpydoc_xref_aliases = {} + numpydoc_xref_ignore = set() templates_path = [] numpydoc_edit_link = False numpydoc_citation_re = '[a-z0-9_.-]+' @@ -41,7 +44,7 @@ A top section before doc = mangle_docstrings(MockApp(), 'class', 'str', str, {'members': ['upper']}, lines) assert 'rpartition' not in [x.strip() for x in lines] assert 'upper' in [x.strip() for x in lines] - + lines = s.split('\n') doc = mangle_docstrings(MockApp(), 'class', 'str', str, {'exclude-members': ALL}, lines) assert 'rpartition' not in [x.strip() for x in lines] diff --git a/numpydoc/tests/test_xref.py b/numpydoc/tests/test_xref.py index 0595026..6e3170e 100644 --- a/numpydoc/tests/test_xref.py +++ b/numpydoc/tests/test_xref.py @@ -1,7 +1,7 @@ # -*- encoding:utf-8 -*- from __future__ import division, absolute_import, print_function -from numpydoc.xref import make_xref_param_type +from numpydoc.xref import make_xref xref_aliases = { # python @@ -20,49 +20,49 @@ xref_aliases = { # Comes mainly from numpy data = r""" (...) array_like, float, optional -(...) :term:`numpy:array_like`, :xref_param_type:`float`, optional +(...) :term:`numpy:array_like`, :obj:`float`, optional (2,) ndarray -(2,) :xref_param_type:`ndarray <numpy.ndarray>` +(2,) :obj:`ndarray <numpy.ndarray>` (...,M,N) array_like (...,M,N) :term:`numpy:array_like` (..., M, N) array_like -(..., :xref_param_type:`M`, :xref_param_type:`N`) :term:`numpy:array_like` +(..., :obj:`M`, :obj:`N`) :term:`numpy:array_like` (float, float), optional -(:xref_param_type:`float`, :xref_param_type:`float`), optional +(:obj:`float`, :obj:`float`), optional 1-D array or sequence -1-D :xref_param_type:`array <numpy.ndarray>` or :term:`python:sequence` +1-D :obj:`array <numpy.ndarray>` or :term:`python:sequence` array of str or unicode-like -:xref_param_type:`array <numpy.ndarray>` of :xref_param_type:`str` or unicode-like +:obj:`array <numpy.ndarray>` of :obj:`str` or unicode-like array_like of float -:term:`numpy:array_like` of :xref_param_type:`float` +:term:`numpy:array_like` of :obj:`float` bool or callable -:xref_param_type:`bool` or :xref_param_type:`callable` +:obj:`bool` or :obj:`callable` int in [0, 255] -:xref_param_type:`int` in [0, 255] +:obj:`int` in [0, 255] int or None, optional -:xref_param_type:`int` or :xref_param_type:`None`, optional +:obj:`int` or :obj:`None`, optional list of str or array_like -:xref_param_type:`list` of :xref_param_type:`str` or :term:`numpy:array_like` +:obj:`list` of :obj:`str` or :term:`numpy:array_like` sequence of array_like :term:`python:sequence` of :term:`numpy:array_like` str or pathlib.Path -:xref_param_type:`str` or :xref_param_type:`pathlib.Path` +:obj:`str` or :obj:`pathlib.Path` {'', string}, optional -{'', :xref_param_type:`string <str>`}, optional +{'', :obj:`string <str>`}, optional {'C', 'F', 'A', or 'K'}, optional {'C', 'F', 'A', or 'K'}, optional @@ -71,55 +71,55 @@ str or pathlib.Path {'linear', 'lower', 'higher', 'midpoint', 'nearest'} {False, True, 'greedy', 'optimal'} -{:xref_param_type:`False`, :xref_param_type:`True`, 'greedy', 'optimal'} +{:obj:`False`, :obj:`True`, 'greedy', 'optimal'} {{'begin', 1}, {'end', 0}}, {string, int} -{{'begin', 1}, {'end', 0}}, {:xref_param_type:`string <str>`, :xref_param_type:`int`} +{{'begin', 1}, {'end', 0}}, {:obj:`string <str>`, :obj:`int`} callable f'(x,*args) -:xref_param_type:`callable` f'(x,*args) +:obj:`callable` f'(x,*args) callable ``fhess(x, *args)``, optional -:xref_param_type:`callable` ``fhess(x, *args)``, optional +:obj:`callable` ``fhess(x, *args)``, optional spmatrix (format: ``csr``, ``bsr``, ``dia`` or coo``) -:xref_param_type:`spmatrix` (format: ``csr``, ``bsr``, ``dia`` or coo``) +:obj:`spmatrix` (format: ``csr``, ``bsr``, ``dia`` or coo``) :ref:`strftime <strftime-strptime-behavior>` :ref:`strftime <strftime-strptime-behavior>` callable or :ref:`strftime <strftime-strptime-behavior>` -:xref_param_type:`callable` or :ref:`strftime <strftime-strptime-behavior>` +:obj:`callable` or :ref:`strftime <strftime-strptime-behavior>` callable or :ref:`strftime behavior <strftime-strptime-behavior>` -:xref_param_type:`callable` or :ref:`strftime behavior <strftime-strptime-behavior>` +:obj:`callable` or :ref:`strftime behavior <strftime-strptime-behavior>` list(int) -:xref_param_type:`list`\(:xref_param_type:`int`) +:obj:`list`\(:obj:`int`) list[int] -:xref_param_type:`list`\[:xref_param_type:`int`] +:obj:`list`\[:obj:`int`] dict(str, int) -:xref_param_type:`dict`\(:xref_param_type:`str`, :xref_param_type:`int`) +:obj:`dict`\(:obj:`str`, :obj:`int`) dict[str, int] -:xref_param_type:`dict`\[:xref_param_type:`str`, :xref_param_type:`int`] +:obj:`dict`\[:obj:`str`, :obj:`int`] tuple(float, float) -:xref_param_type:`tuple`\(:xref_param_type:`float`, :xref_param_type:`float`) +:obj:`tuple`\(:obj:`float`, :obj:`float`) dict[tuple(str, str), int] -:xref_param_type:`dict`\[:xref_param_type:`tuple`\(:xref_param_type:`str`, :xref_param_type:`str`), :xref_param_type:`int`] +:obj:`dict`\[:obj:`tuple`\(:obj:`str`, :obj:`str`), :obj:`int`] """ # noqa: E501 xref_ignore = {'or', 'in', 'of', 'default', 'optional'} -def test_make_xref_param_type(): +def test_make_xref(): for s in data.strip().split('\n\n'): param_type, expected_result = s.split('\n') - result = make_xref_param_type( + result = make_xref( param_type, xref_aliases, xref_ignore diff --git a/numpydoc/xref.py b/numpydoc/xref.py index 11c3fbe..6554220 100644 --- a/numpydoc/xref.py +++ b/numpydoc/xref.py @@ -1,9 +1,5 @@ import re -from docutils import nodes -from sphinx import addnodes -from sphinx.util.nodes import split_explicit_title - # When sphinx (including the napoleon extension) parses the parameters # section of a docstring, it converts the information into field lists. # Some items in the list are for the parameter type. When the type fields @@ -13,9 +9,7 @@ from sphinx.util.nodes import split_explicit_title # numpydoc does not create field lists, so the type information is # not placed into fields that can be processed to make links. Instead, # when parsing the type information we identify tokens that are link -# worthy and wrap them around a special role (xref_param_type_role). -# When the role is processed, we create pending_xref nodes which are -# later turned into links. +# worthy and wrap them around a :obj: role. # Note: we never split on commas that are not followed by a space # You risk creating bad rst markup if you do so. @@ -64,14 +58,44 @@ TEXT_SPLIT_RE = re.compile( CONTAINER_CHARS = set('[](){}') - -def make_xref_param_type(param_type, xref_aliases, xref_ignore): - """Enclose str in a role that creates a cross-reference. - - The role ``xref_param_type`` *may be* added to any token - that looks like type information and no other. The - function tries to be clever and catch type information - in different disguises. +# Save people some time and add some common standard aliases +DEFAULT_LINKS = { + # Python + 'None': ':data:`python:None`', + 'bool': ':ref:`bool <python:bltin-boolean-values>`', + 'boolean': ':ref:`bool <python:bltin-boolean-values>`', + 'True': ':data:`python:True`', + 'False': ':data:`python:False`', + 'list': ':class:`python:list`', + 'tuple': ':class:`python:tuple`', + 'str': ':class:`python:str`', + 'string': ':class:`python:str`', + 'dict': ':class:`python:dict`', + 'float': ':class:`python:float`', + 'int': ':class:`python:int`', + 'callable': ':func:`python:callable`', + 'iterable': ':term:`python:iterable`', + 'sequence': ':term:`python:sequence`', + 'contextmanager': ':func:`python:contextlib.contextmanager`', + 'namedtuple': ':func:`python:collections.namedtuple`', + 'generator': ':term:`python:generator`', + # NumPy + 'array': 'numpy.ndarray', + 'ndarray': 'numpy.ndarray', + 'np.ndarray': 'numpy.ndarray', + 'array-like': ':term:`numpy:array_like`', + 'array_like': ':term:`numpy:array_like`', + 'scalar': ':ref:`scalar <numpy:arrays.scalars>`', + 'RandomState': 'numpy.random.RandomState', + 'np.random.RandomState': 'numpy.random.RandomState', + 'np.inf': ':data:`numpy.inf`', + 'np.nan': ':data:`numpy.nan`', + 'numpy': ':mod:`numpy`', +} + + +def make_xref(param_type, xref_aliases, xref_ignore): + """Enclose str in a :obj: role. Parameters ---------- @@ -87,7 +111,7 @@ def make_xref_param_type(param_type, xref_aliases, xref_ignore): ------- out : str Text with parts that may be wrapped in a - ``xref_param_type`` role. + ``:obj:`` role. """ if param_type in xref_aliases: link, title = xref_aliases[param_type], param_type @@ -97,9 +121,9 @@ def make_xref_param_type(param_type, xref_aliases, xref_ignore): if QUALIFIED_NAME_RE.match(link) and link not in xref_ignore: if link != title: - return ':xref_param_type:`%s <%s>`' % (title, link) + return ':obj:`%s <%s>`' % (title, link) else: - return ':xref_param_type:`%s`' % link + return ':obj:`%s`' % link def _split_and_apply_re(s, pattern): """ @@ -115,7 +139,7 @@ def make_xref_param_type(param_type, xref_aliases, xref_ignore): if pattern.match(tok): results.append(tok) else: - res = make_xref_param_type( + res = make_xref( tok, xref_aliases, xref_ignore) # Openning brackets immediated after a role is # bad markup. Detect that and add backslash. @@ -157,33 +181,3 @@ def make_xref_param_type(param_type, xref_aliases, xref_ignore): # Common splitter tokens return _split_and_apply_re(param_type, TEXT_SPLIT_RE) - - -def xref_param_type_role(role, rawtext, text, lineno, inliner, - options={}, content=[]): - """ - Add a pending_xref for the param_type of a field list - """ - has_title, title, target = split_explicit_title(text) - env = inliner.document.settings.env - if has_title: - target = target.lstrip('~') - else: - if target.startswith(('~', '.')): - prefix, target = target[0], target[1:] - if prefix == '.': - modname = env.ref_context.get('py:module') - target = target[1:] - target = '%s.%s' % (modname, target) - elif prefix == '~': - title = target.split('.')[-1] - - domain = 'py' - contnode = nodes.literal(title, title) - refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False, - reftype='class', reftarget=target) - refnode += contnode - # attach information about the current scope - if env: - env.get_domain(domain).process_field_xref(refnode) - return [refnode], [] |