#481, #482: fix `.name` reference matching.

#482: When doing a non-exact search, match only the given type of object.
#481: Apply non-exact search for Python reference targets with ``.name`` for modules too.
This commit is contained in:
Georg Brandl
2010-08-05 13:39:23 +02:00
parent 8c91fb78ce
commit 580e1c90d3
15 changed files with 124 additions and 104 deletions

View File

@@ -1,6 +1,12 @@
Release 1.0.2 (in development)
==============================
* #482: When doing a non-exact search, match only the given type
of object.
* #481: Apply non-exact search for Python reference targets with
``.name`` for modules too.
* #484: Fix crash when duplicating a parameter in an info field list.
* #487: Fix setting the default role to one provided by the

View File

@@ -255,11 +255,11 @@ All serialization builders outputs one file per source file and a few special
files. They also copy the reST source files in the directory ``_sources``
under the output directory.
The :class:`PickleHTMLBuilder` is a builtin subclass that implements the pickle
The :class:`.PickleHTMLBuilder` is a builtin subclass that implements the pickle
serialization interface.
The files per source file have the extensions of
:attr:`~SerializingHTMLBuilder.out_suffix`, and are arranged in directories
:attr:`~.SerializingHTMLBuilder.out_suffix`, and are arranged in directories
just as the source files are. They unserialize to a dictionary (or dictionary
like structure) with these keys:
@@ -290,7 +290,7 @@ like structure) with these keys:
The special files are located in the root output directory. They are:
:attr:`SerializingHTMLBuilder.globalcontext_filename`
:attr:`.SerializingHTMLBuilder.globalcontext_filename`
A pickled dict with these keys:
``project``, ``copyright``, ``release``, ``version``
@@ -309,7 +309,7 @@ The special files are located in the root output directory. They are:
``titles``
A dictionary of all documents' titles, as HTML strings.
:attr:`SerializingHTMLBuilder.searchindex_filename`
:attr:`.SerializingHTMLBuilder.searchindex_filename`
An index that can be used for searching the documentation. It is a pickled
list with these entries:

View File

@@ -8,8 +8,6 @@ import sphinx
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
'sphinx.ext.autosummary', 'sphinx.ext.extlinks']
#intersphinx_mapping = {'python': ('http://docs.python.org/dev', None)}
master_doc = 'contents'
templates_path = ['_templates']
exclude_patterns = ['_build']
@@ -66,6 +64,10 @@ man_pages = [
'template generator', '', 1),
]
# We're not using intersphinx right now, but if we did, this would be part of
# the mapping:
intersphinx_mapping = {'python': ('http://docs.python.org/dev', None)}
# -- Extension interface -------------------------------------------------------

View File

@@ -346,12 +346,12 @@ Project information
A boolean that decides whether module names are prepended to all
:term:`object` names (for object types where a "module" of some kind is
defined), e.g. for :rst:dir:`function` directives. Default is ``True``.
defined), e.g. for :rst:dir:`py:function` directives. Default is ``True``.
.. confval:: show_authors
A boolean that decides whether :rst:dir:`moduleauthor` and :rst:dir:`sectionauthor`
directives produce any output in the built files.
A boolean that decides whether :rst:dir:`codeauthor` and
:rst:dir:`sectionauthor` directives produce any output in the built files.
.. confval:: modindex_common_prefix
@@ -388,6 +388,8 @@ Options for HTML output
These options influence HTML as well as HTML Help output, and other builders
that use Sphinx' HTMLWriter class.
.. XXX document html_context
.. confval:: html_theme
The "theme" that the HTML output should use. See the :doc:`section about
@@ -553,19 +555,6 @@ that use Sphinx' HTMLWriter class.
This will render the template ``customdownload.html`` as the page
``download.html``.
.. note::
Earlier versions of Sphinx had a value called :confval:`html_index` which
was a clumsy way of controlling the content of the "index" document. If
you used this feature, migrate it by adding an ``'index'`` key to this
setting, with your custom template as the value, and in your custom
template, use ::
{% extend "defindex.html" %}
{% block tables %}
... old template content ...
{% endblock %}
.. confval:: html_domain_indices
If true, generate domain-specific indices in addition to the general index.

View File

@@ -138,11 +138,12 @@ declarations:
.. rst:directive:: .. py:currentmodule:: name
This directive tells Sphinx that the classes, functions etc. documented from
here are in the given module (like :rst:dir:`py:module`), but it will not create
index entries, an entry in the Global Module Index, or a link target for
:rst:role:`mod`. This is helpful in situations where documentation for things in
a module is spread over multiple files or sections -- one location has the
:rst:dir:`py:module` directive, the others only :rst:dir:`py:currentmodule`.
here are in the given module (like :rst:dir:`py:module`), but it will not
create index entries, an entry in the Global Module Index, or a link target
for :rst:role:`py:mod`. This is helpful in situations where documentation
for things in a module is spread over multiple files or sections -- one
location has the :rst:dir:`py:module` directive, the others only
:rst:dir:`py:currentmodule`.
The following directives are provided for module and class contents:
@@ -363,6 +364,9 @@ dot, this order is reversed. For example, in the documentation of Python's
:mod:`codecs` module, ``:py:func:`open``` always refers to the built-in
function, while ``:py:func:`.open``` refers to :func:`codecs.open`.
A similar heuristic is used to determine whether the name is an attribute of the
currently documented class.
Also, if the name is prefixed with a dot, and no exact match is found, the
target is taken as a suffix and all object names with that suffix are
searched. For example, ``:py:meth:`.TarFile.close``` references the
@@ -370,8 +374,9 @@ searched. For example, ``:py:meth:`.TarFile.close``` references the
``tarfile``. Since this can get ambiguous, if there is more than one possible
match, you will get a warning from Sphinx.
A similar heuristic is used to determine whether the name is an attribute of the
currently documented class.
Note that you can combine the ``~`` and ``.`` prefixes:
``:py:meth:`~.TarFile.close``` will reference the ``tarfile.TarFile.close()``
method, but the visible link caption will only be ``close()``.
.. _c-domain:

View File

@@ -210,7 +210,7 @@ the following public API:
standard Sphinx roles (see :ref:`xref-syntax`).
This method is also available under the deprecated alias
:meth:`add_description_unit`.
``add_description_unit``.
.. method:: Sphinx.add_crossref_type(directivename, rolename, indextemplate='', ref_nodeclass=None, objname='')
@@ -272,6 +272,8 @@ the following public API:
This allows to auto-document new types of objects. See the source of the
autodoc module for examples on how to subclass :class:`Documenter`.
.. XXX add real docs for Documenter and subclassing
.. versionadded:: 0.6
.. method:: Sphinx.add_autodoc_attrgetter(type, getter)

View File

@@ -27,20 +27,21 @@ two locations for documentation, while at the same time avoiding
auto-generated-looking pure API documentation.
:mod:`autodoc` provides several directives that are versions of the usual
:rst:dir:`module`, :rst:dir:`class` and so forth. On parsing time, they import the
corresponding module and extract the docstring of the given objects, inserting
them into the page source under a suitable :rst:dir:`module`, :rst:dir:`class` etc.
directive.
:rst:dir:`py:module`, :rst:dir:`py:class` and so forth. On parsing time, they
import the corresponding module and extract the docstring of the given objects,
inserting them into the page source under a suitable :rst:dir:`py:module`,
:rst:dir:`py:class` etc. directive.
.. note::
Just as :rst:dir:`class` respects the current :rst:dir:`module`, :rst:dir:`autoclass`
will also do so, and likewise with :rst:dir:`method` and :rst:dir:`class`.
Just as :rst:dir:`py:class` respects the current :rst:dir:`py:module`,
:rst:dir:`autoclass` will also do so. Likewise, :rst:dir:`automethod` will
respect the current :rst:dir:`py:class`.
.. rst:directive:: automodule
autoclass
autoexception
autoclass
autoexception
Document a module, class or exception. All three directives will by default
only insert the docstring of the object itself::
@@ -127,23 +128,24 @@ directive.
.. versionadded:: 0.4
* The :rst:dir:`automodule`, :rst:dir:`autoclass` and :rst:dir:`autoexception` directives
also support a flag option called ``show-inheritance``. When given, a list
of base classes will be inserted just below the class signature (when used
with :rst:dir:`automodule`, this will be inserted for every class that is
documented in the module).
* The :rst:dir:`automodule`, :rst:dir:`autoclass` and
:rst:dir:`autoexception` directives also support a flag option called
``show-inheritance``. When given, a list of base classes will be inserted
just below the class signature (when used with :rst:dir:`automodule`, this
will be inserted for every class that is documented in the module).
.. versionadded:: 0.4
* All autodoc directives support the ``noindex`` flag option that has the
same effect as for standard :rst:dir:`function` etc. directives: no index
entries are generated for the documented object (and all autodocumented
members).
same effect as for standard :rst:dir:`py:function` etc. directives: no
index entries are generated for the documented object (and all
autodocumented members).
.. versionadded:: 0.4
* :rst:dir:`automodule` also recognizes the ``synopsis``, ``platform`` and
``deprecated`` options that the standard :rst:dir:`module` directive supports.
``deprecated`` options that the standard :rst:dir:`py:module` directive
supports.
.. versionadded:: 0.5
@@ -213,8 +215,8 @@ There are also new config values that you can set:
``"class"``
Only the class' docstring is inserted. This is the default. You can
still document ``__init__`` as a separate method using :rst:dir:`automethod`
or the ``members`` option to :rst:dir:`autoclass`.
still document ``__init__`` as a separate method using
:rst:dir:`automethod` or the ``members`` option to :rst:dir:`autoclass`.
``"both"``
Both the class' and the ``__init__`` method's docstring are concatenated
and inserted.

View File

@@ -17,7 +17,7 @@ It adds this directive:
This directive has one or more arguments, each giving a module or class
name. Class names can be unqualified; in that case they are taken to exist
in the currently described module (see :rst:dir:`module`).
in the currently described module (see :rst:dir:`py:module`).
For each given class, and each class in each given module, the base classes
are determined. Then, from all classes and their base classes, a graph is

View File

@@ -17,15 +17,15 @@ if possible, reuse that support too.
.. note::
:mod:`sphinx.ext.mathbase` is not meant to be added to the
:confval:`extensions` config value, instead, use either
:mod:`sphinx.ext.pngmath` or :mod:`sphinx.ext.jsmath` as described below.
:mod:`.mathbase` is not meant to be added to the :confval:`extensions` config
value, instead, use either :mod:`sphinx.ext.pngmath` or
:mod:`sphinx.ext.jsmath` as described below.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
further translation is necessary when building LaTeX output.
:mod:`mathbase` defines these new markup elements:
:mod:`.mathbase` defines these new markup elements:
.. rst:role:: math

View File

@@ -260,7 +260,7 @@ in a different style:
.. rst:role:: samp
A piece of literal text, such as code. Within the contents, you can use
curly braces to indicate a "variable" part, as in :rst:dir:`file`. For
curly braces to indicate a "variable" part, as in :rst:role:`file`. For
example, in ``:samp:`print 1+{variable}```, the part ``variable`` would be
emphasized.

View File

@@ -151,7 +151,7 @@ The special document names (and pages generated for them) are:
:ref:`object descriptions <basic-domain-markup>`, and from :rst:dir:`index`
directives.
The module index contains one entry per :rst:dir:`module` directive.
The Python module index contains one entry per :rst:dir:`py:module` directive.
The search page contains a form that uses the generated JSON search index and
JavaScript to full-text search the generated documents for search words; it

View File

@@ -21,10 +21,10 @@ No. You have several other options:
configuration value accordingly.
* You can :ref:`write a custom builder <writing-builders>` that derives from
:class:`~sphinx.builders.StandaloneHTMLBuilder` and calls your template engine
of choice.
:class:`~sphinx.builders.html.StandaloneHTMLBuilder` and calls your template
engine of choice.
* You can use the :class:`~sphinx.builders.PickleHTMLBuilder` that produces
* You can use the :class:`~sphinx.builders.html.PickleHTMLBuilder` that produces
pickle files with the page contents, and postprocess them using a custom tool,
or use them in your Web application.
@@ -261,9 +261,9 @@ in the future.
.. data:: file_suffix
The value of the builder's :attr:`out_suffix` attribute, i.e. the file name
extension that the output files will get. For a standard HTML builder, this
is usually ``.html``.
The value of the builder's :attr:`~.SerializingHTMLBuilder.out_suffix`
attribute, i.e. the file name extension that the output files will get. For
a standard HTML builder, this is usually ``.html``.
.. data:: has_source

View File

@@ -356,6 +356,9 @@ class PyModule(Directive):
env.domaindata['py']['modules'][modname] = \
(env.docname, self.options.get('synopsis', ''),
self.options.get('platform', ''), 'deprecated' in self.options)
# make a duplicate entry in 'objects' to facilitate searching for the
# module in PythonDomain.find_obj()
env.domaindata['py']['objects'][modname] = (env.docname, 'module')
targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
self.state.document.note_explicit_target(targetnode)
ret = [targetnode]
@@ -544,7 +547,7 @@ class PythonDomain(Domain):
if fn == docname:
del self.data['modules'][modname]
def find_obj(self, env, modname, classname, name, type, searchorder=0):
def find_obj(self, env, modname, classname, name, type, searchmode=0):
"""
Find a Python object for "name", perhaps using the given module and/or
classname. Returns a list of (name, object entry) tuples.
@@ -560,22 +563,31 @@ class PythonDomain(Domain):
matches = []
newname = None
if searchorder == 1:
if modname and classname and \
modname + '.' + classname + '.' + name in objects:
newname = modname + '.' + classname + '.' + name
elif modname and modname + '.' + name in objects:
newname = modname + '.' + name
elif name in objects:
newname = name
else:
# "fuzzy" searching mode
searchname = '.' + name
matches = [(name, objects[name]) for name in objects
if name.endswith(searchname)]
if searchmode == 1:
objtypes = self.objtypes_for_role(type)
if modname and classname:
fullname = modname + '.' + classname + '.' + name
if fullname in objects and objects[fullname][1] in objtypes:
newname = fullname
if not newname:
if modname and modname + '.' + name in objects and \
objects[modname + '.' + name][1] in objtypes:
newname = modname + '.' + name
elif name in objects and objects[name][1] in objtypes:
newname = name
else:
# "fuzzy" searching mode
searchname = '.' + name
matches = [(name, objects[name]) for name in objects
if name.endswith(searchname)
and objects[name][1] in objtypes]
else:
# NOTE: searching for exact match, object type is not considered
if name in objects:
newname = name
elif type == 'mod':
# only exact matches allowed for modules
return []
elif classname and classname + '.' + name in objects:
newname = classname + '.' + name
elif modname and modname + '.' + name in objects:
@@ -597,33 +609,35 @@ class PythonDomain(Domain):
def resolve_xref(self, env, fromdocname, builder,
type, target, node, contnode):
if (type == 'mod' or
type == 'obj' and target in self.data['modules']):
docname, synopsis, platform, deprecated = \
self.data['modules'].get(target, ('','','', ''))
if not docname:
return None
else:
title = '%s%s%s' % ((platform and '(%s) ' % platform),
synopsis,
(deprecated and ' (deprecated)' or ''))
return make_refnode(builder, fromdocname, docname,
'module-' + target, contnode, title)
modname = node.get('py:module')
clsname = node.get('py:class')
searchmode = node.hasattr('refspecific') and 1 or 0
matches = self.find_obj(env, modname, clsname, target,
type, searchmode)
if not matches:
return None
elif len(matches) > 1:
env.warn(fromdocname,
'more than one target found for cross-reference '
'%r: %s' % (target,
', '.join(match[0] for match in matches)),
node.line)
name, obj = matches[0]
if obj[1] == 'module':
# get additional info for modules
docname, synopsis, platform, deprecated = self.data['modules'][name]
assert docname == obj[0]
title = name
if synopsis:
title += ': ' + synopsis
if deprecated:
title += _(' (deprecated)')
if platform:
title += ' (' + platform + ')'
return make_refnode(builder, fromdocname, docname,
'module-' + name, contnode, title)
else:
modname = node.get('py:module')
clsname = node.get('py:class')
searchorder = node.hasattr('refspecific') and 1 or 0
matches = self.find_obj(env, modname, clsname, target,
type, searchorder)
if not matches:
return None
elif len(matches) > 1:
env.warn(fromdocname,
'more than one target found for cross-reference '
'%r: %s' % (target,
', '.join(match[0] for match in matches)),
node.line)
name, obj = matches[0]
return make_refnode(builder, fromdocname, obj[0], name,
contnode, name)

View File

@@ -28,7 +28,7 @@ class ReSTMarkup(ObjectDescription):
"""
def add_target_and_index(self, name, sig, signode):
targetname = name + '-' + self.objtype
targetname = self.objtype + '-' + name
if targetname not in self.state.document.ids:
signode['names'].append(targetname)
signode['ids'].append(targetname)

View File

@@ -63,7 +63,7 @@ default_settings = {
# This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files.
ENV_VERSION = 37
ENV_VERSION = 38
default_substitutions = set([