mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Allow a leading dot in x-reference roles, marking reversed search order for targets.
This commit is contained in:
@@ -116,7 +116,7 @@ py_paramlist_re = re.compile(r'([\[\],])') # split at '[', ']' and ','
|
|||||||
def parse_py_signature(signode, sig, desctype, env):
|
def parse_py_signature(signode, sig, desctype, env):
|
||||||
"""
|
"""
|
||||||
Transform a python signature into RST nodes.
|
Transform a python signature into RST nodes.
|
||||||
Return the fully qualified name of the thing.
|
Return (fully qualified name of the thing, classname if any).
|
||||||
|
|
||||||
If inside a class, the current class name is handled intelligently:
|
If inside a class, the current class name is handled intelligently:
|
||||||
* it is stripped from the displayed name if present
|
* it is stripped from the displayed name if present
|
||||||
@@ -153,7 +153,7 @@ def parse_py_signature(signode, sig, desctype, env):
|
|||||||
if desctype in ('function', 'method'):
|
if desctype in ('function', 'method'):
|
||||||
# for callables, add an empty parameter list
|
# for callables, add an empty parameter list
|
||||||
signode += addnodes.desc_parameterlist()
|
signode += addnodes.desc_parameterlist()
|
||||||
return fullname
|
return fullname, classname
|
||||||
signode += addnodes.desc_parameterlist()
|
signode += addnodes.desc_parameterlist()
|
||||||
|
|
||||||
stack = [signode[-1]]
|
stack = [signode[-1]]
|
||||||
@@ -171,7 +171,7 @@ def parse_py_signature(signode, sig, desctype, env):
|
|||||||
token = token.strip()
|
token = token.strip()
|
||||||
stack[-1] += addnodes.desc_parameter(token, token)
|
stack[-1] += addnodes.desc_parameter(token, token)
|
||||||
if len(stack) != 1: raise ValueError
|
if len(stack) != 1: raise ValueError
|
||||||
return fullname
|
return fullname, classname
|
||||||
|
|
||||||
|
|
||||||
c_sig_re = re.compile(
|
c_sig_re = re.compile(
|
||||||
@@ -280,6 +280,7 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
|||||||
noindex = ('noindex' in options)
|
noindex = ('noindex' in options)
|
||||||
signatures = map(lambda s: s.strip(), arguments[0].split('\n'))
|
signatures = map(lambda s: s.strip(), arguments[0].split('\n'))
|
||||||
names = []
|
names = []
|
||||||
|
clsname = None
|
||||||
for i, sig in enumerate(signatures):
|
for i, sig in enumerate(signatures):
|
||||||
# add a signature node for each signature in the current unit
|
# add a signature node for each signature in the current unit
|
||||||
# and add a reference target for it
|
# and add a reference target for it
|
||||||
@@ -290,7 +291,7 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
|||||||
try:
|
try:
|
||||||
if desctype in ('function', 'data', 'class', 'exception',
|
if desctype in ('function', 'data', 'class', 'exception',
|
||||||
'method', 'attribute'):
|
'method', 'attribute'):
|
||||||
name = parse_py_signature(signode, sig, desctype, env)
|
name, clsname = parse_py_signature(signode, sig, desctype, env)
|
||||||
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
|
elif desctype in ('cfunction', 'cmember', 'cmacro', 'ctype', 'cvar'):
|
||||||
name = parse_c_signature(signode, sig, desctype)
|
name = parse_c_signature(signode, sig, desctype)
|
||||||
elif desctype == 'opcode':
|
elif desctype == 'opcode':
|
||||||
@@ -323,13 +324,18 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
|||||||
if desctype == 'cfunction':
|
if desctype == 'cfunction':
|
||||||
add_refcount_annotation(env, subnode, name)
|
add_refcount_annotation(env, subnode, name)
|
||||||
# needed for automatic qualification of members
|
# needed for automatic qualification of members
|
||||||
|
clsname_set = False
|
||||||
if desctype == 'class' and names:
|
if desctype == 'class' and names:
|
||||||
env.currclass = names[0]
|
env.currclass = names[0]
|
||||||
|
clsname_set = True
|
||||||
|
elif desctype in ('method', 'attribute') and clsname and not env.currclass:
|
||||||
|
env.currclass = clsname.strip('.')
|
||||||
|
clsname_set = True
|
||||||
# needed for association of version{added,changed} directives
|
# needed for association of version{added,changed} directives
|
||||||
if names:
|
if names:
|
||||||
env.currdesc = names[0]
|
env.currdesc = names[0]
|
||||||
state.nested_parse(content, content_offset, subnode)
|
state.nested_parse(content, content_offset, subnode)
|
||||||
if desctype == 'class':
|
if clsname_set:
|
||||||
env.currclass = None
|
env.currclass = None
|
||||||
env.currdesc = None
|
env.currdesc = None
|
||||||
node.append(subnode)
|
node.append(subnode)
|
||||||
|
|||||||
@@ -621,7 +621,8 @@ class BuildEnvironment:
|
|||||||
builder.get_relative_uri(docfilename, filename) + anchor)
|
builder.get_relative_uri(docfilename, filename) + anchor)
|
||||||
newnode.append(contnode)
|
newnode.append(contnode)
|
||||||
else:
|
else:
|
||||||
name, desc = self.find_desc(modname, clsname, target, typ)
|
searchorder = 1 if node.hasattr('refspecific') else 0
|
||||||
|
name, desc = self.find_desc(modname, clsname, target, typ, searchorder)
|
||||||
if not desc:
|
if not desc:
|
||||||
newnode = contnode
|
newnode = contnode
|
||||||
else:
|
else:
|
||||||
@@ -742,13 +743,16 @@ class BuildEnvironment:
|
|||||||
|
|
||||||
# --------- QUERYING -------------------------------------------------------
|
# --------- QUERYING -------------------------------------------------------
|
||||||
|
|
||||||
def find_desc(self, modname, classname, name, type):
|
def find_desc(self, modname, classname, name, type, searchorder=0):
|
||||||
"""Find a description node matching "name", perhaps using
|
"""Find a description node matching "name", perhaps using
|
||||||
the given module and/or classname."""
|
the given module and/or classname."""
|
||||||
# skip parens
|
# skip parens
|
||||||
if name[-2:] == '()':
|
if name[-2:] == '()':
|
||||||
name = name[:-2]
|
name = name[:-2]
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
return None, None
|
||||||
|
|
||||||
# don't add module and class names for C things
|
# don't add module and class names for C things
|
||||||
if type[0] == 'c' and type not in ('class', 'const'):
|
if type[0] == 'c' and type not in ('class', 'const'):
|
||||||
# skip trailing star and whitespace
|
# skip trailing star and whitespace
|
||||||
@@ -757,22 +761,32 @@ class BuildEnvironment:
|
|||||||
return name, self.descrefs[name]
|
return name, self.descrefs[name]
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
if name in self.descrefs:
|
newname = None
|
||||||
newname = name
|
if searchorder == 1:
|
||||||
elif modname and modname + '.' + name in self.descrefs:
|
if modname and classname and \
|
||||||
newname = modname + '.' + name
|
modname + '.' + classname + '.' + name in self.descrefs:
|
||||||
elif modname and classname and \
|
newname = modname + '.' + classname + '.' + name
|
||||||
modname + '.' + classname + '.' + name in self.descrefs:
|
elif modname and modname + '.' + name in self.descrefs:
|
||||||
newname = modname + '.' + classname + '.' + name
|
newname = modname + '.' + name
|
||||||
# special case: builtin exceptions have module "exceptions" set
|
elif name in self.descrefs:
|
||||||
elif type == 'exc' and '.' not in name and \
|
newname = name
|
||||||
'exceptions.' + name in self.descrefs:
|
|
||||||
newname = 'exceptions.' + name
|
|
||||||
# special case: object methods
|
|
||||||
elif type in ('func', 'meth') and '.' not in name and \
|
|
||||||
'object.' + name in self.descrefs:
|
|
||||||
newname = 'object.' + name
|
|
||||||
else:
|
else:
|
||||||
|
if name in self.descrefs:
|
||||||
|
newname = name
|
||||||
|
elif modname and modname + '.' + name in self.descrefs:
|
||||||
|
newname = modname + '.' + name
|
||||||
|
elif modname and classname and \
|
||||||
|
modname + '.' + classname + '.' + name in self.descrefs:
|
||||||
|
newname = modname + '.' + classname + '.' + name
|
||||||
|
# special case: builtin exceptions have module "exceptions" set
|
||||||
|
elif type == 'exc' and '.' not in name and \
|
||||||
|
'exceptions.' + name in self.descrefs:
|
||||||
|
newname = 'exceptions.' + name
|
||||||
|
# special case: object methods
|
||||||
|
elif type in ('func', 'meth') and '.' not in name and \
|
||||||
|
'object.' + name in self.descrefs:
|
||||||
|
newname = 'object.' + name
|
||||||
|
if newname is None:
|
||||||
return None, None
|
return None, None
|
||||||
return newname, self.descrefs[newname]
|
return newname, self.descrefs[newname]
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,12 @@ def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
|||||||
text += '()'
|
text += '()'
|
||||||
pnode = addnodes.pending_xref(rawtext)
|
pnode = addnodes.pending_xref(rawtext)
|
||||||
pnode['reftype'] = typ
|
pnode['reftype'] = typ
|
||||||
|
# if the first character is a dot, search more specific namespaces first
|
||||||
|
# else search builtins first
|
||||||
|
if text[0:1] == '.' and \
|
||||||
|
typ in ('data', 'exc', 'func', 'class', 'const', 'attr', 'meth'):
|
||||||
|
text = text[1:]
|
||||||
|
pnode['refspecific'] = True
|
||||||
pnode['reftarget'] = ws_re.sub('', text)
|
pnode['reftarget'] = ws_re.sub('', text)
|
||||||
pnode['modname'] = env.currmodule
|
pnode['modname'] = env.currmodule
|
||||||
pnode['classname'] = env.currclass
|
pnode['classname'] = env.currclass
|
||||||
|
|||||||
Reference in New Issue
Block a user