summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Gommers <ralf.gommers@gmail.com>2021-01-01 13:36:09 +0000
committerGitHub <noreply@github.com>2021-01-01 13:36:09 +0000
commit8275f4e9d32c232f66516351e69c6a09eb7f16d6 (patch)
tree3bb8d143fc74310b6d5a271a888cebd35886c373
parent42100606815dfd5fd18a64fad1a004b577031439 (diff)
parentf2f1867cb35e0b613a6b3f9dacd49dfbfa1cda5c (diff)
downloadnumpydoc-8275f4e9d32c232f66516351e69c6a09eb7f16d6.tar.gz
Merge pull request #295 from rossbar/xref_conf
ENH: Add configuration option for parameter cross-referencing
-rw-r--r--doc/install.rst16
-rw-r--r--numpydoc/docscrape_sphinx.py6
-rw-r--r--numpydoc/tests/test_xref.py106
-rw-r--r--numpydoc/xref.py26
4 files changed, 144 insertions, 10 deletions
diff --git a/doc/install.rst b/doc/install.rst
index 46b26f8..d80e7a7 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -76,14 +76,26 @@ numpydoc_xref_aliases : dict
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
+numpydoc_xref_ignore : set or ``"all"``
+ How to handle terms not in ``numpydoc_xref_aliases`` when
+ ``numpydoc_xref_aliases=True``. The value can either be a ``set``
+ containing terms to ignore, or ``"all"``. In the former case, the set
+ contains words not to cross-reference. Most likely, these are common words
used in parameter type descriptions that may be confused for
classes of the same name. For example::
numpydoc_xref_ignore = {'type', 'optional', 'default'}
The default is an empty set.
+
+ If the ``numpydoc_xref_ignore="all"``, then all unrecognized terms are
+ ignored, i.e. terms not in ``numpydoc_xref_aliases`` are *not* wrapped in
+ ``:obj:`` roles.
+ This configuration parameter may be useful if you only want create
+ cross references for a small number of terms. In this case, including the
+ desired cross reference mappings in ``numpydoc_xref_aliases`` and setting
+ ``numpydoc_xref_ignore="all"`` is more convenient than explicitly listing
+ terms to ignore in a set.
numpydoc_edit_link : bool
.. deprecated:: edit your HTML template instead
diff --git a/numpydoc/docscrape_sphinx.py b/numpydoc/docscrape_sphinx.py
index b6f5754..38a49ba 100644
--- a/numpydoc/docscrape_sphinx.py
+++ b/numpydoc/docscrape_sphinx.py
@@ -73,7 +73,8 @@ class SphinxDocString(NumpyDocString):
param_type = make_xref(
param_type,
self.xref_aliases,
- self.xref_ignore)
+ self.xref_ignore
+ )
if param.name:
out += self._str_indent([named_fmt % (param.name.strip(),
param_type)])
@@ -213,7 +214,8 @@ class SphinxDocString(NumpyDocString):
param_type = make_xref(
param_type,
self.xref_aliases,
- self.xref_ignore)
+ self.xref_ignore
+ )
parts.append(param_type)
out += self._str_indent([' : '.join(parts)])
diff --git a/numpydoc/tests/test_xref.py b/numpydoc/tests/test_xref.py
index 5d16919..aa14970 100644
--- a/numpydoc/tests/test_xref.py
+++ b/numpydoc/tests/test_xref.py
@@ -102,6 +102,101 @@ dict[tuple(str, str), int]
:class:`python:dict`\[:class:`python:tuple`\(:class:`python:str`, :class:`python:str`), :class:`python:int`]
""" # noqa: E501
+data_ignore_obj = r"""
+(...) array_like, float, optional
+(...) :term:`numpy:array_like`, :class:`python:float`, optional
+
+(2,) ndarray
+(2,) :obj:`ndarray <numpy.ndarray>`
+
+(...,M,N) array_like
+(...,M,N) :term:`numpy:array_like`
+
+(..., M, N) array_like
+(..., M, N) :term:`numpy:array_like`
+
+(float, float), optional
+(:class:`python:float`, :class:`python:float`), optional
+
+1-D array or sequence
+1-D :obj:`array <numpy.ndarray>` or :term:`python:sequence`
+
+array of str or unicode-like
+:obj:`array <numpy.ndarray>` of :class:`python:str` or unicode-like
+
+array_like of float
+:term:`numpy:array_like` of :class:`python:float`
+
+bool or callable
+:ref:`bool <python:bltin-boolean-values>` or :func:`python:callable`
+
+int in [0, 255]
+:class:`python:int` in [0, 255]
+
+int or None, optional
+:class:`python:int` or :data:`python:None`, optional
+
+list of str or array_like
+:class:`python:list` of :class:`python:str` or :term:`numpy:array_like`
+
+sequence of array_like
+:term:`python:sequence` of :term:`numpy:array_like`
+
+str or pathlib.Path
+:class:`python:str` or pathlib.Path
+
+{'', string}, optional
+{'', :class:`python:str`}, optional
+
+{'C', 'F', 'A', or 'K'}, optional
+{'C', 'F', 'A', or 'K'}, optional
+
+{'linear', 'lower', 'higher', 'midpoint', 'nearest'}
+{'linear', 'lower', 'higher', 'midpoint', 'nearest'}
+
+{False, True, 'greedy', 'optimal'}
+{:data:`python:False`, :data:`python:True`, 'greedy', 'optimal'}
+
+{{'begin', 1}, {'end', 0}}, {string, int}
+{{'begin', 1}, {'end', 0}}, {:class:`python:str`, :class:`python:int`}
+
+callable f'(x,*args)
+:func:`python:callable` f'(x,*args)
+
+callable ``fhess(x, *args)``, optional
+:func:`python:callable` ``fhess(x, *args)``, optional
+
+spmatrix (format: ``csr``, ``bsr``, ``dia`` or coo``)
+spmatrix (format: ``csr``, ``bsr``, ``dia`` or coo``)
+
+:ref:`strftime <strftime-strptime-behavior>`
+:ref:`strftime <strftime-strptime-behavior>`
+
+callable or :ref:`strftime <strftime-strptime-behavior>`
+:func:`python:callable` or :ref:`strftime <strftime-strptime-behavior>`
+
+callable or :ref:`strftime behavior <strftime-strptime-behavior>`
+:func:`python:callable` or :ref:`strftime behavior <strftime-strptime-behavior>`
+
+list(int)
+:class:`python:list`\(:class:`python:int`)
+
+list[int]
+:class:`python:list`\[:class:`python:int`]
+
+dict(str, int)
+:class:`python:dict`\(:class:`python:str`, :class:`python:int`)
+
+dict[str, int]
+:class:`python:dict`\[:class:`python:str`, :class:`python:int`]
+
+tuple(float, float)
+:class:`python:tuple`\(:class:`python:float`, :class:`python:float`)
+
+dict[tuple(str, str), int]
+:class:`python:dict`\[:class:`python:tuple`\(:class:`python:str`, :class:`python:str`), :class:`python:int`]
+""" # noqa: E501
+
xref_ignore = {'or', 'in', 'of', 'default', 'optional'}
@@ -111,3 +206,14 @@ xref_ignore = {'or', 'in', 'of', 'default', 'optional'}
)
def test_make_xref(param_type, expected_result):
assert make_xref(param_type, xref_aliases, xref_ignore) == expected_result
+
+@pytest.mark.parametrize(
+ ('param_type', 'expected_result'),
+ [tuple(s.split('\n')) for s in data_ignore_obj.strip().split('\n\n')]
+)
+def test_make_xref_ignore_unknown(param_type, expected_result):
+ assert make_xref(param_type, xref_aliases, xref_ignore="all") == expected_result
+
+def test_xref_ignore_is_all():
+ with pytest.raises(TypeError, match="must be a set or 'all'"):
+ make_xref("array_like", xref_aliases, xref_ignore="foo")
diff --git a/numpydoc/xref.py b/numpydoc/xref.py
index 7c6612e..7e98b96 100644
--- a/numpydoc/xref.py
+++ b/numpydoc/xref.py
@@ -106,8 +106,11 @@ def make_xref(param_type, xref_aliases, xref_ignore):
xref_aliases : dict
Mapping used to resolve common abbreviations and aliases
to fully qualified names that can be cross-referenced.
- xref_ignore : set
- Words not to cross-reference.
+ xref_ignore : set or "all"
+ A set containing words not to cross-reference. Instead of a set, the
+ string 'all' can be given to ignore all unrecognized terms.
+ Unrecognized terms include those that are not in `xref_aliases` and
+ are not already wrapped in a reST role.
Returns
-------
@@ -115,17 +118,29 @@ def make_xref(param_type, xref_aliases, xref_ignore):
Text with fully-qualified names and terms that may be wrapped in a
``:obj:`` role.
"""
+ ignore_set = xref_ignore
+ wrap_unknown = True
+ if isinstance(xref_ignore, str):
+ if xref_ignore.lower() == "all":
+ wrap_unknown = False
+ ignore_set = set()
+ else:
+ raise TypeError(
+ "xref_ignore must be a set or 'all', got {}".format(xref_ignore)
+ )
+
if param_type in xref_aliases:
link, title = xref_aliases[param_type], param_type
param_type = link
else:
link = title = param_type
- if QUALIFIED_NAME_RE.match(link) and link not in xref_ignore:
+ if QUALIFIED_NAME_RE.match(link) and link not in ignore_set:
if link != title:
return ':obj:`%s <%s>`' % (title, link)
- else:
+ if wrap_unknown:
return ':obj:`%s`' % link
+ return link
def _split_and_apply_re(s, pattern):
"""
@@ -141,8 +156,7 @@ def make_xref(param_type, xref_aliases, xref_ignore):
if pattern.match(tok):
results.append(tok)
else:
- res = make_xref(
- tok, xref_aliases, xref_ignore)
+ res = make_xref(tok, xref_aliases, xref_ignore)
# Opening brackets immediately after a role is
# bad markup. Detect that and add backslash.
# :role:`type`( to :role:`type`\(