def test_missing_reference_pydomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly normalize_intersphinx_mapping(app, app.config) load_mappings(app) # 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 # py:module context helps 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.astext() == 'func()' # py:attr context helps to search objects kwargs = {'py:module': 'module1'} node, contnode = fake_node('py', 'attr', 'Foo.bar', 'Foo.bar', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'Foo.bar'
def test_missing_reference_stddomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'cmd': ('https://docs.python.org/', inv_file), } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly normalize_intersphinx_mapping(app, app.config) load_mappings(app) # no context data kwargs = {} node, contnode = fake_node('std', 'option', '-l', '-l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn is None # std:program context helps to search objects kwargs = {'std:program': 'ls'} node, contnode = fake_node('std', 'option', '-l', 'ls -l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'ls -l' # refers inventory by name kwargs = {} node, contnode = fake_node('std', 'option', 'cmd:ls -l', '-l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == '-l'
def test_missing_reference_stddomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'cmd': ('https://docs.python.org/', inv_file), } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly load_mappings(app) # no context data kwargs = {} node, contnode = fake_node('std', 'option', '-l', '-l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn is None # std:program context helps to search objects kwargs = {'std:program': 'ls'} node, contnode = fake_node('std', 'option', '-l', 'ls -l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'ls -l' # refers inventory by name kwargs = {} node, contnode = fake_node('std', 'option', 'cmd:ls -l', '-l', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == '-l'
def replace_target_intersphinx(app, env, node, contnode): reftarget_replace = app.config.reftarget_replace target = node.get("reftarget", None) if target: for old, new in reftarget_replace.items(): node["reftarget"] = target.replace(old, new) return missing_reference(app, env, node, contnode)
def call_intersphinx(app, env, node, contnode): """ Call intersphinx and make links between Sage manuals relative. TESTS: Check that the link from the thematic tutorials to the reference manual is relative, see :trac:`20118`:: sage: from sage.env import SAGE_DOC # optional - dochtml sage: thematic_index = os.path.join(SAGE_DOC, "html", "en", "thematic_tutorials", "index.html") # optional - dochtml sage: for line in open(thematic_index).readlines(): # optional - dochtml ....: if "padics" in line: ....: _ = sys.stdout.write(line) <li><p><a class="reference external" href="../reference/padics/sage/rings/padics/tutorial.html#sage-rings-padics-tutorial" title="(in Sage... Reference Manual: p-Adics v...)"><span>Introduction to the p-adics</span></a></p></li> """ debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget']) builder = app.builder res = intersphinx.missing_reference(app, env, node, contnode) if res: # Replace absolute links to $SAGE_DOC by relative links: this # allows to copy the whole documentation tree somewhere else # without breaking links, see Trac #20118. if res['refuri'].startswith(SAGE_DOC): here = os.path.dirname(os.path.join(builder.outdir, node['refdoc'])) res['refuri'] = os.path.relpath(res['refuri'], here) debug_inf(app, "++++ Found at %s" % res['refuri']) else: debug_inf(app, "---- Intersphinx: %s not Found" % node['reftarget']) return res
def missing_reference(app, env, node, contnode): """Search the index for missing references. For example, resolve :class:`Event` to :class:`Event <gevent.event.Event>`""" # XXX methods and functions resolved by this function miss their () if intersphinx.missing_reference(app, env, node, contnode) is not None: # is there a better way to give intersphinx a bigger priority? return env = app.builder.env type = node['reftype'] target = node['reftarget'] modname = node.get('py:module') classname = node.get('py:class') if modname and classname: return def new_reference(refuri, reftitle): newnode = nodes.reference('', '') newnode['refuri'] = refuri newnode['reftitle'] = reftitle newnode['py:class'] = 'external-xref' newnode['classname'] = 'external-xref' newnode.append(contnode) msg = 'Resolved missing-reference: :%5s:`%s` -> %s' % (type, target, refuri) if noisy >= 1 or msg not in message_cache: print(msg) message_cache.add(msg) return newnode if noisy >= 1: print('Looking for %s' % [type, target, modname, classname]) print(node) for docname, items in env.indexentries.items(): if noisy >= 2: print(docname) for _x in items: if noisy >= 4: print(_x) (i_type, i_string, i_target, i_aliasname) = _x[:4] if noisy >= 3: print('---', [i_type, i_string, i_target, i_aliasname]) if i_aliasname.endswith(target): stripped_aliasname = i_aliasname[len(docname):] if stripped_aliasname: assert stripped_aliasname[0] == '.', repr(stripped_aliasname) stripped_aliasname = stripped_aliasname[1:] if stripped_aliasname == target: if noisy >= 1: print('--- found %s %s in %s' % (type, target, i_aliasname)) return new_reference(docname + '.html#' + i_aliasname, i_aliasname) if type == 'mod': modules = [x for x in env.indexentries.keys() if x.startswith('gevent.')] target = 'gevent.' + target if target in modules: return new_reference(target + '.html', target)
def resolve_intersphinx_aliases(app, env, node, contnode): alias = node.get('reftarget') if alias is not None and alias in reftarget_aliases: resolved_ref, text = reftarget_aliases[alias] node['reftarget'] = resolved_ref text_node = next(iter( contnode.traverse(lambda n: n.tagname == '#text'))) text_node.parent.replace(text, Text(text, '')) return missing_reference(app, env, node, contnode) return None
def __sphinx_issue_8127(app, env, node, contnode): reftarget = node.get("reftarget", None) if reftarget == "..": node["reftype"] = "data" node["reftarget"] = "Ellipsis" text_node = next(iter(contnode.traverse(lambda n: n.tagname == "#text"))) replacement_node = Text("...", "") if text_node.parent is not None: text_node.parent.replace(text_node, replacement_node) else: # e.g. happens in rtype fields contnode = replacement_node return missing_reference(app, env, node, contnode)
def test_missing_reference_jsdomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly load_mappings(app) # no context data kwargs = {} node, contnode = fake_node('js', 'meth', 'baz', 'baz()', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn is None # js:module and js:object context helps to search objects kwargs = {'js:module': 'foo', 'js:object': 'bar'} node, contnode = fake_node('js', 'meth', 'baz', 'baz()', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'baz()'
def test_missing_reference_pydomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly normalize_intersphinx_mapping(app, app.config) load_mappings(app) # 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 # py:module context helps 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.astext() == 'func()' # py:attr context helps to search objects kwargs = {'py:module': 'module1'} node, contnode = fake_node('py', 'attr', 'Foo.bar', 'Foo.bar', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'Foo.bar' # pending_xref_condition="resolved" node = addnodes.pending_xref('', reftarget='Foo.bar', refdomain='py', reftype='attr') node['py:module'] = 'module1' node += addnodes.pending_xref_condition('', 'Foo.bar', condition='resolved') node += addnodes.pending_xref_condition('', 'module1.Foo.bar', condition='*') rn = missing_reference(app, app.env, node, nodes.Text('dummy-cont-node')) assert rn.astext() == 'Foo.bar'
def resolve_intersphinx_aliases(app, env, node, contnode): reftarget_aliases = app.config.ref_aliases alias = node.get("reftarget", None) if alias is not None and alias in reftarget_aliases: real_ref, text_to_render = reftarget_aliases[alias] # this will resolve the ref node["reftarget"] = real_ref # this will rewrite the rendered text: # find the text node child text_node = next(iter(contnode.traverse(lambda n: n.tagname == "#text"))) # remove the old text node, add new text node with custom text text_node.parent.replace(text_node, Text(text_to_render, "")) # delegate all the rest of dull work to intersphinx return missing_reference(app, env, node, contnode)
def case(*, term, doc, py): def assert_(rn, expected): if expected is None: assert rn is None else: assert rn.astext() == expected kwargs = {} node, contnode = fake_node('std', 'term', 'a term', 'a term', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'a term' if term else None) node, contnode = fake_node('std', 'term', 'inv:a term', 'a term', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'a term') node, contnode = fake_node('std', 'doc', 'docname', 'docname', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'docname' if doc else None) node, contnode = fake_node('std', 'doc', 'inv:docname', 'docname', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'docname') # an arbitrary ref in another domain node, contnode = fake_node('py', 'func', 'module1.func', 'func()', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'func()' if py else None) node, contnode = fake_node('py', 'func', 'inv:module1.func', 'func()', **kwargs) rn = missing_reference(app, app.env, node, contnode) assert_(rn, 'func()')
def test_missing_reference(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, 'py3k': ('https://docs.python.org/py3k/', inv_file), 'py3krel': ('py3k', inv_file), # relative path 'py3krelparent': ('../../py3k', inv_file), # relative path, parent dir } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly normalize_intersphinx_mapping(app, app.config) load_mappings(app) inv = app.env.intersphinx_inventory assert inv['py:module']['module2'] == \ ('foo', '2.0', 'https://docs.python.org/foo.html#module-module2', '-') # check resolution when a target is found rn = reference_check(app, 'py', 'func', 'module1.func', 'foo') assert isinstance(rn, nodes.reference) assert rn['refuri'] == 'https://docs.python.org/sub/foo.html#module1.func' assert rn['reftitle'] == '(in foo v2.0)' assert rn[0].astext() == 'foo' # create unresolvable nodes and check None return value assert reference_check(app, 'py', 'foo', 'module1.func', 'foo') is None assert reference_check(app, 'py', 'func', 'foo', 'foo') is None assert reference_check(app, 'py', 'func', 'foo', 'foo') is None # check handling of prefixes # prefix given, target found: prefix is stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2') assert rn[0].astext() == 'module2' # prefix given, but not in title: nothing stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'module2') assert rn[0].astext() == 'module2' # prefix given, but explicit: nothing stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2', refexplicit=True) assert rn[0].astext() == 'py3k:module2' # prefix given, target not found and nonexplicit title: prefix is stripped node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=False) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'unknown' # prefix given, target not found and explicit title: nothing is changed node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=True) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'py3k:unknown' # check relative paths rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo') assert rn['refuri'] == 'py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo') assert rn['refuri'] == '../../py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo', refdoc='sub/dir/test') assert rn['refuri'] == '../../py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo', refdoc='sub/dir/test') assert rn['refuri'] == '../../../../py3k/foo.html#module-module1' # check refs of standard domain rn = reference_check(app, 'std', 'doc', 'docname', 'docname') assert rn['refuri'] == 'https://docs.python.org/docname.html'
def reference_check(app, *args, **kwds): node, contnode = fake_node(*args, **kwds) return missing_reference(app, app.env, node, contnode)
def test_missing_reference(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, 'py3k': ('https://docs.python.org/py3k/', inv_file), } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly load_mappings(app) inv = app.env.intersphinx_inventory assert inv['py:module']['module2'] == \ ('foo', '2.0', 'https://docs.python.org/foo.html#module-module2', '-') # create fake nodes and check referencing def fake_node(domain, type, target, content, **attrs): contnode = nodes.emphasis(content, content) node = addnodes.pending_xref('') node['reftarget'] = target node['reftype'] = type node['refdomain'] = domain node.attributes.update(attrs) node += contnode return node, contnode def reference_check(*args, **kwds): node, contnode = fake_node(*args, **kwds) return missing_reference(app, app.env, node, contnode) # check resolution when a target is found rn = reference_check('py', 'func', 'module1.func', 'foo') assert isinstance(rn, nodes.reference) assert rn['refuri'] == 'https://docs.python.org/sub/foo.html#module1.func' assert rn['reftitle'] == '(in foo v2.0)' assert rn[0].astext() == 'foo' # create unresolvable nodes and check None return value assert reference_check('py', 'foo', 'module1.func', 'foo') is None assert reference_check('py', 'func', 'foo', 'foo') is None assert reference_check('py', 'func', 'foo', 'foo') is None # check handling of prefixes # prefix given, target found: prefix is stripped rn = reference_check('py', 'mod', 'py3k:module2', 'py3k:module2') assert rn[0].astext() == 'module2' # prefix given, but not in title: nothing stripped rn = reference_check('py', 'mod', 'py3k:module2', 'module2') assert rn[0].astext() == 'module2' # prefix given, but explicit: nothing stripped rn = reference_check('py', 'mod', 'py3k:module2', 'py3k:module2', refexplicit=True) assert rn[0].astext() == 'py3k:module2' # prefix given, target not found and nonexplicit title: prefix is stripped node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=False) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'unknown' # prefix given, target not found and explicit title: nothing is changed node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=True) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'py3k:unknown'
def missing_reference(app, env, node, contnode): """Search the index for missing references. For example, resolve :class:`Event` to :class:`Event <gevent.event.Event>`""" # XXX methods and functions resolved by this function miss their () if intersphinx.missing_reference(app, env, node, contnode) is not None: # is there a better way to give intersphinx a bigger priority? return env = app.builder.env type = node['reftype'] target = node['reftarget'] modname = node.get('py:module') classname = node.get('py:class') if modname and classname: return def new_reference(refuri, reftitle): newnode = nodes.reference('', '') newnode['refuri'] = refuri newnode['reftitle'] = reftitle newnode['py:class'] = 'external-xref' newnode['classname'] = 'external-xref' newnode.append(contnode) msg = 'Resolved missing-reference: :%5s:`%s` -> %s' % (type, target, refuri) if noisy >= 1 or msg not in message_cache: print(msg) message_cache.add(msg) return newnode if noisy >= 1: print('Looking for %s' % [type, target, modname, classname]) print(node) for docname, items in env.indexentries.items(): if noisy >= 2: print(docname) for (i_type, i_string, i_target, i_aliasname) in items: if noisy >= 3: print('---', [i_type, i_string, i_target, i_aliasname]) if i_aliasname.endswith(target): stripped_aliasname = i_aliasname[len(docname):] if stripped_aliasname: assert stripped_aliasname[0] == '.', repr( stripped_aliasname) stripped_aliasname = stripped_aliasname[1:] if stripped_aliasname == target: if noisy >= 1: print('--- found %s %s in %s' % (type, target, i_aliasname)) return new_reference(docname + '.html#' + i_aliasname, i_aliasname) if type == 'mod': modules = [ x for x in env.indexentries.keys() if x.startswith('gevent.') ] target = 'gevent.' + target if target in modules: return new_reference(target + '.html', target)
def _on_missing_reference(app, env, node, contnode): """Handler for missing references. This will attempt to fix references to options and then attempt to apply default intersphinx prefixes (if needed) before resolving a reference using intersphinx. Args: app (sphinx.application.Sphinx): The Sphinx application processing the document. env (sphinx.environment.BuildEnvironment): The environment for this doc build. node (sphinx.addnodes.pending_xref): The pending reference to resolve. contnode (docutils.nodes.literal): The context for the reference. Returns: list: The list of any reference nodes, as created by intersphinx. """ orig_target = node['reftarget'] target = orig_target domain = node.get('refdomain') # See if we're referencing a std:option. Sphinx (as of 1.6.1) does not # properly link these. A pull request has been opened to fix this # (https://github.com/sphinx-doc/sphinx/pull/3769). Until we can make # use of that, we're including the workaround here. if domain == 'std' and node['reftype'] == 'option': # Options are stored in the inventory as "program-name.--option". # In order to look up the option, the target will need to be # converted to this format. # # Ideally, we'd be able to utilize the same logic as found in # StandardDomain._resolve_option_xref, but we don't have any # information on the progoptions data stored there. Instead, we # try to determine if the target already has a program name or # an intersphinx doc set and normalize the contents to match the # option reference name format. i = target.rfind(' ') if i != -1: # The option target contains a program name and an option # name. We can easily normalize this to be in # <progname>.<option> format. target = '%s.%s' % (target[:i], target[i + 1:]) target = target.replace(' ', '-') else: # Since a space was not found, and a program name is needed # to complete the reference, we'll see if a ".. program::" # has been set in this file. If so, we'll put that into the # target name (being careful to consider any intersphinx doc # set name that may be prefixed). progname = node.get('std:program') if progname: if ':' in target: setname, newtarget = target.split(':', 1) target = '%s:%s.%s' % (setname, progname, newtarget) else: target = '%s.%s' % (progname, target) if ':' not in target: prefixes = \ env.metadata[env.docname].get('default-intersphinx-prefixes') if prefixes: # Try all supported prefixes in order. These are the only allowed # to be inferred. for prefix in prefixes: old_content = contnode[0] node['reftarget'] = '%s:%s' % (prefix, target) result = intersphinx.missing_reference(app, env, node, contnode) if result: return result # Couldn't find it. Go back to the original target and try # again. node['reftarget'] = orig_target contnode[0] = old_content return None return intersphinx.missing_reference(app, env, node, contnode)
def reference_check(*args, **kwds): node, contnode = fake_node(*args, **kwds) return missing_reference(app, app.env, node, contnode)
def test_missing_reference(tempdir, app, status, warning): inv_file = tempdir / "inventory" inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { "https://docs.python.org/": inv_file, "py3k": ("https://docs.python.org/py3k/", inv_file), } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly load_mappings(app) inv = app.env.intersphinx_inventory assert inv["py:module"]["module2"] == ("foo", "2.0", "https://docs.python.org/foo.html#module-module2", "-") # create fake nodes and check referencing def fake_node(domain, type, target, content, **attrs): contnode = nodes.emphasis(content, content) node = addnodes.pending_xref("") node["reftarget"] = target node["reftype"] = type node["refdomain"] = domain node.attributes.update(attrs) node += contnode return node, contnode def reference_check(*args, **kwds): node, contnode = fake_node(*args, **kwds) return missing_reference(app, app.env, node, contnode) # check resolution when a target is found rn = reference_check("py", "func", "module1.func", "foo") assert isinstance(rn, nodes.reference) assert rn["refuri"] == "https://docs.python.org/sub/foo.html#module1.func" assert rn["reftitle"] == "(in foo v2.0)" assert rn[0].astext() == "foo" # create unresolvable nodes and check None return value assert reference_check("py", "foo", "module1.func", "foo") is None assert reference_check("py", "func", "foo", "foo") is None assert reference_check("py", "func", "foo", "foo") is None # check handling of prefixes # prefix given, target found: prefix is stripped rn = reference_check("py", "mod", "py3k:module2", "py3k:module2") assert rn[0].astext() == "module2" # prefix given, but not in title: nothing stripped rn = reference_check("py", "mod", "py3k:module2", "module2") assert rn[0].astext() == "module2" # prefix given, but explicit: nothing stripped rn = reference_check("py", "mod", "py3k:module2", "py3k:module2", refexplicit=True) assert rn[0].astext() == "py3k:module2" # prefix given, target not found and nonexplicit title: prefix is stripped node, contnode = fake_node("py", "mod", "py3k:unknown", "py3k:unknown", refexplicit=False) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == "unknown" # prefix given, target not found and explicit title: nothing is changed node, contnode = fake_node("py", "mod", "py3k:unknown", "py3k:unknown", refexplicit=True) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == "py3k:unknown"
def test_missing_reference(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) app.config.intersphinx_mapping = { 'https://docs.python.org/': inv_file, 'py3k': ('https://docs.python.org/py3k/', inv_file), 'py3krel': ('py3k', inv_file), # relative path 'py3krelparent': ('../../py3k', inv_file), # relative path, parent dir } app.config.intersphinx_cache_limit = 0 # load the inventory and check if it's done correctly load_mappings(app) inv = app.env.intersphinx_inventory assert inv['py:module']['module2'] == \ ('foo', '2.0', 'https://docs.python.org/foo.html#module-module2', '-') # check resolution when a target is found rn = reference_check(app, 'py', 'func', 'module1.func', 'foo') assert isinstance(rn, nodes.reference) assert rn['refuri'] == 'https://docs.python.org/sub/foo.html#module1.func' assert rn['reftitle'] == '(in foo v2.0)' assert rn[0].astext() == 'foo' # create unresolvable nodes and check None return value assert reference_check(app, 'py', 'foo', 'module1.func', 'foo') is None assert reference_check(app, 'py', 'func', 'foo', 'foo') is None assert reference_check(app, 'py', 'func', 'foo', 'foo') is None # check handling of prefixes # prefix given, target found: prefix is stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2') assert rn[0].astext() == 'module2' # prefix given, but not in title: nothing stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'module2') assert rn[0].astext() == 'module2' # prefix given, but explicit: nothing stripped rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2', refexplicit=True) assert rn[0].astext() == 'py3k:module2' # prefix given, target not found and nonexplicit title: prefix is stripped node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=False) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'unknown' # prefix given, target not found and explicit title: nothing is changed node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown', refexplicit=True) rn = missing_reference(app, app.env, node, contnode) assert rn is None assert contnode[0].astext() == 'py3k:unknown' # check relative paths rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo') assert rn['refuri'] == 'py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo') assert rn['refuri'] == '../../py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo', refdoc='sub/dir/test') assert rn['refuri'] == '../../py3k/foo.html#module-module1' rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo', refdoc='sub/dir/test') assert rn['refuri'] == '../../../../py3k/foo.html#module-module1' # check refs of standard domain rn = reference_check(app, 'std', 'doc', 'docname', 'docname') assert rn['refuri'] == 'https://docs.python.org/docname.html'