diff options
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | doc/intro.rst | 3 | ||||
| -rw-r--r-- | sphinx/domains/python.py | 38 |
3 files changed, 30 insertions, 13 deletions
@@ -54,6 +54,8 @@ Features added - The :rst:role:`ref` role can now also reference tables by caption. - The :rst:dir:`include` directive now supports absolute paths, which are interpreted as relative to the source directory. + - In the Python domain, references like ``:func:`.name``` now look for + matching names with any prefix if no direct match is found. * Configuration: diff --git a/doc/intro.rst b/doc/intro.rst index 33f97a3f..33a89fa6 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -16,6 +16,9 @@ Though there is support for that kind of docs as well (which is intended to be freely mixed with hand-written content), if you need pure API docs have a look at `Epydoc <http://epydoc.sf.net/>`_, which also understands reST. +.. function:: Sphinxy.add_domain() + +:func:`.add_domain` Conversion from other systems ----------------------------- diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index b97b9b42..fc808699 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -547,7 +547,7 @@ class PythonDomain(Domain): def find_obj(self, env, modname, classname, name, type, searchorder=0): """ Find a Python object for "name", perhaps using the given module and/or - classname. + classname. Returns a list of (name, object entry) tuples. """ # skip parens if name[-2:] == '()': @@ -557,6 +557,7 @@ class PythonDomain(Domain): return None, None objects = self.data['objects'] + matches = [] newname = None if searchorder == 1: @@ -567,6 +568,11 @@ class PythonDomain(Domain): 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)] else: if name in objects: newname = name @@ -585,14 +591,14 @@ class PythonDomain(Domain): elif type in ('func', 'meth') and '.' not in name and \ 'object.' + name in objects: newname = 'object.' + name - if newname is None: - return None, None - return newname, objects[newname] + if newname is not None: + matches.append((newname, objects[newname])) + return matches def resolve_xref(self, env, fromdocname, builder, - typ, target, node, contnode): - if (typ == 'mod' or - typ == 'obj' and target in self.data['modules']): + 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: @@ -607,13 +613,19 @@ class PythonDomain(Domain): modname = node.get('py:module') clsname = node.get('py:class') searchorder = node.hasattr('refspecific') and 1 or 0 - name, obj = self.find_obj(env, modname, clsname, - target, typ, searchorder) - if not obj: + matches = self.find_obj(env, modname, clsname, target, + type, searchorder) + if not matches: return None - else: - return make_refnode(builder, fromdocname, obj[0], name, - contnode, name) + 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) def get_objects(self): for modname, info in self.data['modules'].iteritems(): |
