Skip to content

Commit

Permalink
Fix #3351: intersphinx does not refers context
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Feb 15, 2017
1 parent c4fc611 commit 0779cae
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ Features added
Bugs fixed
----------

* #3351: intersphinx does not refers context like ``py:module``, ``py:class``
and so on.

Deprecated
----------

Expand Down
5 changes: 5 additions & 0 deletions sphinx/domains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,8 @@ def get_type_name(self, type, primary=False):
if primary:
return type.lname
return _('%s %s') % (self.label, type.lname)

def get_full_qualified_name(self, node):
# type: (nodes.Node) -> unicode
"""Return full qualified name for given node."""
return None
10 changes: 10 additions & 0 deletions sphinx/domains/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,16 @@ def get_objects(self):
if type != 'module': # modules are already handled
yield (refname, refname, type, docname, refname, 1)

def get_full_qualified_name(self, node):
# type: (nodes.Node) -> unicode
modname = node.get('py:module')
clsname = node.get('py:class')
target = node.get('reftarget')
if target is None:
return None
else:
return '.'.join(filter(None, [modname, clsname, target]))


def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
Expand Down
8 changes: 8 additions & 0 deletions sphinx/ext/intersphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,21 @@ def missing_reference(app, env, node, contnode):
return
objtypes = ['%s:%s' % (domain, objtype) for objtype in objtypes]
to_try = [(inventories.main_inventory, target)]
if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
if full_qualified_name:
to_try.append((inventories.main_inventory, full_qualified_name))
in_set = None
if ':' in target:
# first part may be the foreign doc set name
setname, newtarget = target.split(':', 1)
if setname in inventories.named_inventory:
in_set = setname
to_try.append((inventories.named_inventory[setname], newtarget))
if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
if full_qualified_name:
to_try.append((inventories.named_inventory[setname], full_qualified_name))
for inventory, target in to_try:
for objtype in objtypes:
if objtype not in inventory or target not in inventory[objtype]:
Expand Down
34 changes: 32 additions & 2 deletions tests/test_domain_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
:license: BSD, see LICENSE for details.
"""

from mock import Mock

from six import text_type
from docutils import nodes

from sphinx import addnodes
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain


def parse(sig):
Expand All @@ -26,7 +29,6 @@ def parse(sig):


def test_function_signatures():

rv = parse('func(a=1) -> int object')
assert text_type(rv) == u'a=1'

Expand All @@ -44,3 +46,31 @@ def test_function_signatures():

rv = parse('func(a=[][, b=None])')
assert text_type(rv) == u'a=[], [b=None]'


def test_get_full_qualified_name():
env = Mock(domaindata={})
domain = PythonDomain(env)

# non-python references
node = nodes.reference()
assert domain.get_full_qualified_name(node) is None

# simple reference
node = nodes.reference(reftarget='func')
assert domain.get_full_qualified_name(node) == 'func'

# with py:module context
kwargs = {'py:module': 'module1'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'module1.func'

# with py:class context
kwargs = {'py:class': 'Class'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'Class.func'

# with both py:module and py:class context
kwargs = {'py:module': 'module1', 'py:class': 'Class'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
12 changes: 12 additions & 0 deletions tests/test_ext_intersphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@ def reference_check(*args, **kwds):
assert rn is None
assert contnode[0].astext() == 'py3k:unknown'

# no context data
kwargs = {}
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
rn = missing_reference(app, app.env, node, contnode)
assert rn is None

# context data (like py:module) help to search objects
kwargs = {'py:module': 'module1'}
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
rn = missing_reference(app, app.env, node, contnode)
assert rn[0].astext() == 'func()'

# check relative paths
rn = reference_check('py', 'mod', 'py3krel:module1', 'foo')
assert rn['refuri'] == 'py3k/foo.html#module-module1'
Expand Down

0 comments on commit 0779cae

Please sign in to comment.