Move env.temp_data content that might be used to resolve references to a new env.ref_context dictionary.

This commit is contained in:
Georg Brandl 2014-09-20 19:15:41 +02:00
parent ca4e62e47b
commit 2c396601bf
10 changed files with 60 additions and 55 deletions

View File

@ -130,7 +130,7 @@ class CObject(ObjectDescription):
if m: if m:
name = m.group(1) name = m.group(1)
typename = self.env.temp_data.get('c:type') typename = self.env.ref_context.get('c:type')
if self.name == 'c:member' and typename: if self.name == 'c:member' and typename:
fullname = typename + '.' + name fullname = typename + '.' + name
else: else:
@ -212,12 +212,12 @@ class CObject(ObjectDescription):
self.typename_set = False self.typename_set = False
if self.name == 'c:type': if self.name == 'c:type':
if self.names: if self.names:
self.env.temp_data['c:type'] = self.names[0] self.env.ref_context['c:type'] = self.names[0]
self.typename_set = True self.typename_set = True
def after_content(self): def after_content(self):
if self.typename_set: if self.typename_set:
self.env.temp_data['c:type'] = None self.env.ref_context.pop('c:type', None)
class CXRefRole(XRefRole): class CXRefRole(XRefRole):

View File

@ -434,7 +434,7 @@ class ASTNestedNameElement(ASTBase):
'', refdomain='cpp', reftype='type', '', refdomain='cpp', reftype='type',
reftarget=targetText, modname=None, classname=None) reftarget=targetText, modname=None, classname=None)
if env: # during testing we don't have an env, do we? if env: # during testing we don't have an env, do we?
pnode['cpp:parent'] = env.temp_data.get('cpp:parent') pnode['cpp:parent'] = env.ref_context.get('cpp:parent')
pnode += nodes.Text(text_type(self.identifier)) pnode += nodes.Text(text_type(self.identifier))
signode += pnode signode += pnode
elif mode == 'lastIsName': elif mode == 'lastIsName':
@ -1666,7 +1666,7 @@ class CPPObject(ObjectDescription):
signode['names'].append(uninstantiated) signode['names'].append(uninstantiated)
objects.setdefault(uninstantiated, ( objects.setdefault(uninstantiated, (
self.env.docname, ast.objectType, theid)) self.env.docname, ast.objectType, theid))
self.env.temp_data['cpp:lastname'] = ast.prefixedName self.env.ref_context['cpp:lastname'] = ast.prefixedName
indextext = self.get_index_text(name) indextext = self.get_index_text(name)
if not re.compile(r'^[a-zA-Z0-9_]*$').match(theid): if not re.compile(r'^[a-zA-Z0-9_]*$').match(theid):
@ -1693,7 +1693,7 @@ class CPPObject(ObjectDescription):
raise ValueError raise ValueError
self.describe_signature(signode, ast) self.describe_signature(signode, ast)
parent = self.env.temp_data.get('cpp:parent') parent = self.env.ref_context.get('cpp:parent')
if parent and len(parent) > 0: if parent and len(parent) > 0:
ast = ast.clone() ast = ast.clone()
ast.prefixedName = ast.name.prefix_nested_name(parent[-1]) ast.prefixedName = ast.name.prefix_nested_name(parent[-1])
@ -1741,15 +1741,15 @@ class CPPClassObject(CPPObject):
return _('%s (C++ class)') % name return _('%s (C++ class)') % name
def before_content(self): def before_content(self):
lastname = self.env.temp_data['cpp:lastname'] lastname = self.env.ref_context['cpp:lastname']
assert lastname assert lastname
if 'cpp:parent' in self.env.temp_data: if 'cpp:parent' in self.env.ref_context:
self.env.temp_data['cpp:parent'].append(lastname) self.env.ref_context['cpp:parent'].append(lastname)
else: else:
self.env.temp_data['cpp:parent'] = [lastname] self.env.ref_context['cpp:parent'] = [lastname]
def after_content(self): def after_content(self):
self.env.temp_data['cpp:parent'].pop() self.env.ref_context['cpp:parent'].pop()
def parse_definition(self, parser): def parse_definition(self, parser):
return parser.parse_class_object() return parser.parse_class_object()
@ -1774,7 +1774,7 @@ class CPPNamespaceObject(Directive):
def run(self): def run(self):
env = self.state.document.settings.env env = self.state.document.settings.env
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
env.temp_data['cpp:parent'] = [] env.ref_context['cpp:parent'] = []
else: else:
parser = DefinitionParser(self.arguments[0]) parser = DefinitionParser(self.arguments[0])
try: try:
@ -1784,13 +1784,13 @@ class CPPNamespaceObject(Directive):
self.state_machine.reporter.warning(e.description, self.state_machine.reporter.warning(e.description,
line=self.lineno) line=self.lineno)
else: else:
env.temp_data['cpp:parent'] = [prefix] env.ref_context['cpp:parent'] = [prefix]
return [] return []
class CPPXRefRole(XRefRole): class CPPXRefRole(XRefRole):
def process_link(self, env, refnode, has_explicit_title, title, target): def process_link(self, env, refnode, has_explicit_title, title, target):
parent = env.temp_data.get('cpp:parent') parent = env.ref_context.get('cpp:parent')
if parent: if parent:
refnode['cpp:parent'] = parent[:] refnode['cpp:parent'] = parent[:]
if not has_explicit_title: if not has_explicit_title:

View File

@ -45,7 +45,7 @@ class JSObject(ObjectDescription):
nameprefix = None nameprefix = None
name = prefix name = prefix
objectname = self.env.temp_data.get('js:object') objectname = self.env.ref_context.get('js:object')
if nameprefix: if nameprefix:
if objectname: if objectname:
# someone documenting the method of an attribute of the current # someone documenting the method of an attribute of the current
@ -77,7 +77,7 @@ class JSObject(ObjectDescription):
def add_target_and_index(self, name_obj, sig, signode): def add_target_and_index(self, name_obj, sig, signode):
objectname = self.options.get( objectname = self.options.get(
'object', self.env.temp_data.get('js:object')) 'object', self.env.ref_context.get('js:object'))
fullname = name_obj[0] fullname = name_obj[0]
if fullname not in self.state.document.ids: if fullname not in self.state.document.ids:
signode['names'].append(fullname) signode['names'].append(fullname)
@ -140,7 +140,7 @@ class JSConstructor(JSCallable):
class JSXRefRole(XRefRole): class JSXRefRole(XRefRole):
def process_link(self, env, refnode, has_explicit_title, title, target): def process_link(self, env, refnode, has_explicit_title, title, target):
# basically what sphinx.domains.python.PyXRefRole does # basically what sphinx.domains.python.PyXRefRole does
refnode['js:object'] = env.temp_data.get('js:object') refnode['js:object'] = env.ref_context.get('js:object')
if not has_explicit_title: if not has_explicit_title:
title = title.lstrip('.') title = title.lstrip('.')
target = target.lstrip('~') target = target.lstrip('~')
@ -216,7 +216,7 @@ class JavaScriptDomain(Domain):
def resolve_any_xref(self, env, fromdocname, builder, target, node, def resolve_any_xref(self, env, fromdocname, builder, target, node,
contnode): contnode):
objectname = node.get('js:object') # not likely objectname = node.get('js:object')
name, obj = self.find_obj(env, objectname, target, None, 1) name, obj = self.find_obj(env, objectname, target, None, 1)
if not obj: if not obj:
return [] return []

View File

@ -156,8 +156,8 @@ class PyObject(ObjectDescription):
# determine module and class name (if applicable), as well as full name # determine module and class name (if applicable), as well as full name
modname = self.options.get( modname = self.options.get(
'module', self.env.temp_data.get('py:module')) 'module', self.env.ref_context.get('py:module'))
classname = self.env.temp_data.get('py:class') classname = self.env.ref_context.get('py:class')
if classname: if classname:
add_module = False add_module = False
if name_prefix and name_prefix.startswith(classname): if name_prefix and name_prefix.startswith(classname):
@ -194,7 +194,7 @@ class PyObject(ObjectDescription):
# 'exceptions' module. # 'exceptions' module.
elif add_module and self.env.config.add_module_names: elif add_module and self.env.config.add_module_names:
modname = self.options.get( modname = self.options.get(
'module', self.env.temp_data.get('py:module')) 'module', self.env.ref_context.get('py:module'))
if modname and modname != 'exceptions': if modname and modname != 'exceptions':
nodetext = modname + '.' nodetext = modname + '.'
signode += addnodes.desc_addname(nodetext, nodetext) signode += addnodes.desc_addname(nodetext, nodetext)
@ -225,7 +225,7 @@ class PyObject(ObjectDescription):
def add_target_and_index(self, name_cls, sig, signode): def add_target_and_index(self, name_cls, sig, signode):
modname = self.options.get( modname = self.options.get(
'module', self.env.temp_data.get('py:module')) 'module', self.env.ref_context.get('py:module'))
fullname = (modname and modname + '.' or '') + name_cls[0] fullname = (modname and modname + '.' or '') + name_cls[0]
# note target # note target
if fullname not in self.state.document.ids: if fullname not in self.state.document.ids:
@ -254,7 +254,7 @@ class PyObject(ObjectDescription):
def after_content(self): def after_content(self):
if self.clsname_set: if self.clsname_set:
self.env.temp_data['py:class'] = None self.env.ref_context.pop('py:class', None)
class PyModulelevel(PyObject): class PyModulelevel(PyObject):
@ -299,7 +299,7 @@ class PyClasslike(PyObject):
def before_content(self): def before_content(self):
PyObject.before_content(self) PyObject.before_content(self)
if self.names: if self.names:
self.env.temp_data['py:class'] = self.names[0][0] self.env.ref_context['py:class'] = self.names[0][0]
self.clsname_set = True self.clsname_set = True
@ -377,8 +377,8 @@ class PyClassmember(PyObject):
def before_content(self): def before_content(self):
PyObject.before_content(self) PyObject.before_content(self)
lastname = self.names and self.names[-1][1] lastname = self.names and self.names[-1][1]
if lastname and not self.env.temp_data.get('py:class'): if lastname and not self.env.ref_context.get('py:class'):
self.env.temp_data['py:class'] = lastname.strip('.') self.env.ref_context['py:class'] = lastname.strip('.')
self.clsname_set = True self.clsname_set = True
@ -434,7 +434,7 @@ class PyModule(Directive):
env = self.state.document.settings.env env = self.state.document.settings.env
modname = self.arguments[0].strip() modname = self.arguments[0].strip()
noindex = 'noindex' in self.options noindex = 'noindex' in self.options
env.temp_data['py:module'] = modname env.ref_context['py:module'] = modname
ret = [] ret = []
if not noindex: if not noindex:
env.domaindata['py']['modules'][modname] = \ env.domaindata['py']['modules'][modname] = \
@ -472,16 +472,16 @@ class PyCurrentModule(Directive):
env = self.state.document.settings.env env = self.state.document.settings.env
modname = self.arguments[0].strip() modname = self.arguments[0].strip()
if modname == 'None': if modname == 'None':
env.temp_data['py:module'] = None env.ref_context.pop('py:module', None)
else: else:
env.temp_data['py:module'] = modname env.ref_context['py:module'] = modname
return [] return []
class PyXRefRole(XRefRole): class PyXRefRole(XRefRole):
def process_link(self, env, refnode, has_explicit_title, title, target): def process_link(self, env, refnode, has_explicit_title, title, target):
refnode['py:module'] = env.temp_data.get('py:module') refnode['py:module'] = env.ref_context.get('py:module')
refnode['py:class'] = env.temp_data.get('py:class') refnode['py:class'] = env.ref_context.get('py:class')
if not has_explicit_title: if not has_explicit_title:
title = title.lstrip('.') # only has a meaning for the target title = title.lstrip('.') # only has a meaning for the target
target = target.lstrip('~') # only has a meaning for the title target = target.lstrip('~') # only has a meaning for the title

View File

@ -163,7 +163,7 @@ class Cmdoption(ObjectDescription):
return firstname return firstname
def add_target_and_index(self, firstname, sig, signode): def add_target_and_index(self, firstname, sig, signode):
currprogram = self.env.temp_data.get('std:program') currprogram = self.env.ref_context.get('std:program')
for optname in signode.get('allnames', []): for optname in signode.get('allnames', []):
targetname = optname.replace('/', '-') targetname = optname.replace('/', '-')
if not targetname.startswith('-'): if not targetname.startswith('-'):
@ -198,9 +198,9 @@ class Program(Directive):
env = self.state.document.settings.env env = self.state.document.settings.env
program = ws_re.sub('-', self.arguments[0].strip()) program = ws_re.sub('-', self.arguments[0].strip())
if program == 'None': if program == 'None':
env.temp_data['std:program'] = None env.ref_context.pop('std:program', None)
else: else:
env.temp_data['std:program'] = program env.ref_context['std:program'] = program
return [] return []
@ -219,7 +219,7 @@ class OptionXRefRole(XRefRole):
innernodeclass = addnodes.literal_emphasis innernodeclass = addnodes.literal_emphasis
def process_link(self, env, refnode, has_explicit_title, title, target): def process_link(self, env, refnode, has_explicit_title, title, target):
program = env.temp_data.get('std:program') program = env.ref_context.get('std:program')
if not has_explicit_title: if not has_explicit_title:
if ' ' in title and not (title.startswith('/') or if ' ' in title and not (title.startswith('/') or
title.startswith('-')): title.startswith('-')):

View File

@ -225,6 +225,10 @@ class BuildEnvironment:
# temporary data storage while reading a document # temporary data storage while reading a document
self.temp_data = {} self.temp_data = {}
# context for cross-references (e.g. current module or class)
# this is similar to temp_data, but will for example be copied to
# attributes of "any" cross references
self.ref_context = {}
def set_warnfunc(self, func): def set_warnfunc(self, func):
self._warnfunc = func self._warnfunc = func
@ -681,6 +685,7 @@ class BuildEnvironment:
# cleanup # cleanup
self.temp_data.clear() self.temp_data.clear()
self.ref_context.clear()
roles._roles.pop('', None) # if a document has set a local default role roles._roles.pop('', None) # if a document has set a local default role
if save_parsed: if save_parsed:
@ -747,7 +752,7 @@ class BuildEnvironment:
def note_versionchange(self, type, version, node, lineno): def note_versionchange(self, type, version, node, lineno):
self.versionchanges.setdefault(version, []).append( self.versionchanges.setdefault(version, []).append(
(type, self.temp_data['docname'], lineno, (type, self.temp_data['docname'], lineno,
self.temp_data.get('py:module'), self.ref_context.get('py:module'),
self.temp_data.get('object'), node.astext())) self.temp_data.get('object'), node.astext()))
# post-processing of read doctrees # post-processing of read doctrees

View File

@ -891,7 +891,7 @@ class ModuleLevelDocumenter(Documenter):
modname = self.env.temp_data.get('autodoc:module') modname = self.env.temp_data.get('autodoc:module')
# ... or in the scope of a module directive # ... or in the scope of a module directive
if not modname: if not modname:
modname = self.env.temp_data.get('py:module') modname = self.env.ref_context.get('py:module')
# ... else, it stays None, which means invalid # ... else, it stays None, which means invalid
return modname, parents + [base] return modname, parents + [base]
@ -913,7 +913,7 @@ class ClassLevelDocumenter(Documenter):
mod_cls = self.env.temp_data.get('autodoc:class') mod_cls = self.env.temp_data.get('autodoc:class')
# ... or from a class directive # ... or from a class directive
if mod_cls is None: if mod_cls is None:
mod_cls = self.env.temp_data.get('py:class') mod_cls = self.env.ref_context.get('py:class')
# ... if still None, there's no way to know # ... if still None, there's no way to know
if mod_cls is None: if mod_cls is None:
return None, [] return None, []
@ -923,7 +923,7 @@ class ClassLevelDocumenter(Documenter):
if not modname: if not modname:
modname = self.env.temp_data.get('autodoc:module') modname = self.env.temp_data.get('autodoc:module')
if not modname: if not modname:
modname = self.env.temp_data.get('py:module') modname = self.env.ref_context.get('py:module')
# ... else, it stays None, which means invalid # ... else, it stays None, which means invalid
return modname, parents + [base] return modname, parents + [base]

View File

@ -432,11 +432,11 @@ def get_import_prefixes_from_env(env):
""" """
prefixes = [None] prefixes = [None]
currmodule = env.temp_data.get('py:module') currmodule = env.ref_context.get('py:module')
if currmodule: if currmodule:
prefixes.insert(0, currmodule) prefixes.insert(0, currmodule)
currclass = env.temp_data.get('py:class') currclass = env.ref_context.get('py:class')
if currclass: if currclass:
if currmodule: if currmodule:
prefixes.insert(0, currmodule + "." + currclass) prefixes.insert(0, currmodule + "." + currclass)

View File

@ -310,7 +310,7 @@ class InheritanceDiagram(Directive):
# Create a graph starting with the list of classes # Create a graph starting with the list of classes
try: try:
graph = InheritanceGraph( graph = InheritanceGraph(
class_names, env.temp_data.get('py:module'), class_names, env.ref_context.get('py:module'),
parts=node['parts'], parts=node['parts'],
private_bases='private-bases' in self.options) private_bases='private-bases' in self.options)
except InheritanceException as err: except InheritanceException as err:

View File

@ -123,24 +123,24 @@ def test_parse_name():
directive.env.temp_data['autodoc:module'] = 'util' directive.env.temp_data['autodoc:module'] = 'util'
verify('function', 'raises', ('util', ['raises'], None, None)) verify('function', 'raises', ('util', ['raises'], None, None))
del directive.env.temp_data['autodoc:module'] del directive.env.temp_data['autodoc:module']
directive.env.temp_data['py:module'] = 'util' directive.env.ref_context['py:module'] = 'util'
verify('function', 'raises', ('util', ['raises'], None, None)) verify('function', 'raises', ('util', ['raises'], None, None))
verify('class', 'TestApp', ('util', ['TestApp'], None, None)) verify('class', 'TestApp', ('util', ['TestApp'], None, None))
# for members # for members
directive.env.temp_data['py:module'] = 'foo' directive.env.ref_context['py:module'] = 'foo'
verify('method', 'util.TestApp.cleanup', verify('method', 'util.TestApp.cleanup',
('util', ['TestApp', 'cleanup'], None, None)) ('util', ['TestApp', 'cleanup'], None, None))
directive.env.temp_data['py:module'] = 'util' directive.env.ref_context['py:module'] = 'util'
directive.env.temp_data['py:class'] = 'Foo' directive.env.ref_context['py:class'] = 'Foo'
directive.env.temp_data['autodoc:class'] = 'TestApp' directive.env.temp_data['autodoc:class'] = 'TestApp'
verify('method', 'cleanup', ('util', ['TestApp', 'cleanup'], None, None)) verify('method', 'cleanup', ('util', ['TestApp', 'cleanup'], None, None))
verify('method', 'TestApp.cleanup', verify('method', 'TestApp.cleanup',
('util', ['TestApp', 'cleanup'], None, None)) ('util', ['TestApp', 'cleanup'], None, None))
# and clean up # and clean up
del directive.env.temp_data['py:module'] del directive.env.ref_context['py:module']
del directive.env.temp_data['py:class'] del directive.env.ref_context['py:class']
del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:class']
@ -584,7 +584,7 @@ def test_generate():
'method', 'test_autodoc.Class.foobar', more_content=None) 'method', 'test_autodoc.Class.foobar', more_content=None)
# test auto and given content mixing # test auto and given content mixing
directive.env.temp_data['py:module'] = 'test_autodoc' directive.env.ref_context['py:module'] = 'test_autodoc'
assert_result_contains(' Function.', 'method', 'Class.meth') assert_result_contains(' Function.', 'method', 'Class.meth')
add_content = ViewList() add_content = ViewList()
add_content.append('Content.', '', 0) add_content.append('Content.', '', 0)
@ -682,12 +682,12 @@ def test_generate():
'attribute', 'test_autodoc.Class.descr') 'attribute', 'test_autodoc.Class.descr')
# test generation for C modules (which have no source file) # test generation for C modules (which have no source file)
directive.env.temp_data['py:module'] = 'time' directive.env.ref_context['py:module'] = 'time'
assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime')
assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime')
# test autodoc_member_order == 'source' # test autodoc_member_order == 'source'
directive.env.temp_data['py:module'] = 'test_autodoc' directive.env.ref_context['py:module'] = 'test_autodoc'
assert_order(['.. py:class:: Class(arg)', assert_order(['.. py:class:: Class(arg)',
' .. py:attribute:: Class.descr', ' .. py:attribute:: Class.descr',
' .. py:method:: Class.meth()', ' .. py:method:: Class.meth()',
@ -704,7 +704,7 @@ def test_generate():
' .. py:method:: Class.inheritedmeth()', ' .. py:method:: Class.inheritedmeth()',
], ],
'class', 'Class', member_order='bysource', all_members=True) 'class', 'Class', member_order='bysource', all_members=True)
del directive.env.temp_data['py:module'] del directive.env.ref_context['py:module']
# test attribute initialized to class instance from other module # test attribute initialized to class instance from other module
directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class' directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class'
@ -729,7 +729,7 @@ def test_generate():
'test_autodoc.Class.moore') 'test_autodoc.Class.moore')
# test new attribute documenter behavior # test new attribute documenter behavior
directive.env.temp_data['py:module'] = 'test_autodoc' directive.env.ref_context['py:module'] = 'test_autodoc'
options.undoc_members = True options.undoc_members = True
assert_processes([('class', 'test_autodoc.AttCls'), assert_processes([('class', 'test_autodoc.AttCls'),
('attribute', 'test_autodoc.AttCls.a1'), ('attribute', 'test_autodoc.AttCls.a1'),
@ -743,7 +743,7 @@ def test_generate():
# test explicit members with instance attributes # test explicit members with instance attributes
del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:class']
del directive.env.temp_data['autodoc:module'] del directive.env.temp_data['autodoc:module']
directive.env.temp_data['py:module'] = 'test_autodoc' directive.env.ref_context['py:module'] = 'test_autodoc'
options.inherited_members = False options.inherited_members = False
options.undoc_members = False options.undoc_members = False
options.members = ALL options.members = ALL
@ -765,7 +765,7 @@ def test_generate():
], 'class', 'InstAttCls') ], 'class', 'InstAttCls')
del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:class']
del directive.env.temp_data['autodoc:module'] del directive.env.temp_data['autodoc:module']
del directive.env.temp_data['py:module'] del directive.env.ref_context['py:module']
# test descriptor class documentation # test descriptor class documentation
options.members = ['CustomDataDescriptor'] options.members = ['CustomDataDescriptor']