Commits

Georg Brandl  committed 368101c

With a few disabled features (see XXX), the test suite runs again.

  • Participants
  • Parent commits e2283da

Comments (0)

Files changed (9)

File sphinx/application.py

 import sys
 import types
 import posixpath
+from os import path
 from cStringIO import StringIO
 
 from docutils import nodes

File sphinx/builders/html.py

         rellinks = []
         if self.config.html_use_index:
             rellinks.append(('genindex', _('General Index'), 'I', _('index')))
-        if self.config.html_use_modindex and self.env.modules:
+        # XXX generalization of modindex?
+        if self.config.html_use_modindex and \
+                self.env.domains['py'].data['modules']:
             rellinks.append(('modindex', _('Global Module Index'),
                              'M', _('modules')))
 
 
         # the global module index
 
-        if self.config.html_use_modindex and self.env.modules:
+        moduleindex = self.env.domains['py'].data['modules']
+        if self.config.html_use_modindex and moduleindex:
             # the sorted list of all modules, for the global module index
             modules = sorted(((mn, (self.get_relative_uri('modindex', fn) +
                                     '#module-' + mn, sy, pl, dep))
                               for (mn, (fn, sy, pl, dep)) in
-                              self.env.modules.iteritems()),
+                              moduleindex.iteritems()),
                              key=lambda x: x[0].lower())
             # collect all platforms
             platforms = set()
         self.info(bold('dumping object inventory... '), nonl=True)
         f = open(path.join(self.outdir, INVENTORY_FILENAME), 'w')
         try:
+            # XXX inventory version 2
             f.write('# Sphinx inventory version 1\n')
             f.write('# Project: %s\n' % self.config.project.encode('utf-8'))
             f.write('# Version: %s\n' % self.config.version)
-            for modname, info in self.env.modules.iteritems():
-                f.write('%s mod %s\n' % (modname, self.get_target_uri(info[0])))
-            for refname, (docname, desctype) in self.env.descrefs.iteritems():
-                f.write('%s %s %s\n' % (refname, desctype,
-                                        self.get_target_uri(docname)))
+            #for modname, info in self.env.modules.iteritems():
+            #    f.write('%s mod %s\n' % (modname, self.get_target_uri(info[0])))
+            #for refname, (docname, desctype) in self.env.descrefs.iteritems():
+            #    f.write('%s %s %s\n' % (refname, desctype,
+            #                            self.get_target_uri(docname)))
         finally:
             f.close()
         self.info('done')

File sphinx/directives/desc.py

         pass
 
     def run(self):
-        self.desctype = self.name
+        if ':' in self.name:
+            self.domain, self.desctype = self.name.split(':', 1)
+        else:
+            self.domain, self.desctype = '', self.name
         self.env = self.state.document.settings.env
         self.indexnode = addnodes.index(entries=[])
 
     def run(self):
         env = self.state.document.settings.env
         domain_name = arguments[0]
-        # XXX won't work
         env.default_domain = env.domains.get(domain_name)
 
 

File sphinx/directives/other.py

         return ret
 
 
-class Module(Directive):
-    """
-    Directive to mark description of a new module.
-    """
-
-    has_content = False
-    required_arguments = 1
-    optional_arguments = 0
-    final_argument_whitespace = False
-    option_spec = {
-        'platform': lambda x: x,
-        'synopsis': lambda x: x,
-        'noindex': directives.flag,
-        'deprecated': directives.flag,
-    }
-
-    def run(self):
-        env = self.state.document.settings.env
-        modname = self.arguments[0].strip()
-        noindex = 'noindex' in self.options
-        env.currmodule = modname
-        env.note_module(modname, self.options.get('synopsis', ''),
-                        self.options.get('platform', ''),
-                        'deprecated' in self.options)
-        modulenode = addnodes.module()
-        modulenode['modname'] = modname
-        modulenode['synopsis'] = self.options.get('synopsis', '')
-        targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
-        self.state.document.note_explicit_target(targetnode)
-        ret = [modulenode, targetnode]
-        if 'platform' in self.options:
-            platform = self.options['platform']
-            modulenode['platform'] = platform
-            node = nodes.paragraph()
-            node += nodes.emphasis('', _('Platforms: '))
-            node += nodes.Text(platform, platform)
-            ret.append(node)
-        # the synopsis isn't printed; in fact, it is only used in the
-        # modindex currently
-        if not noindex:
-            indextext = _('%s (module)') % modname
-            inode = addnodes.index(entries=[('single', indextext,
-                                             'module-' + modname, modname)])
-            ret.insert(0, inode)
-        return ret
-
-
-class CurrentModule(Directive):
-    """
-    This directive is just to tell Sphinx that we're documenting
-    stuff in module foo, but links to module foo won't lead here.
-    """
-
-    has_content = False
-    required_arguments = 1
-    optional_arguments = 0
-    final_argument_whitespace = False
-    option_spec = {}
-
-    def run(self):
-        env = self.state.document.settings.env
-        modname = self.arguments[0].strip()
-        if modname == 'None':
-            env.currmodule = None
-        else:
-            env.currmodule = modname
-        return []
-
-
 class Author(Directive):
     """
     Directive to give the name of the author of the current document
 
 
 directives.register_directive('toctree', directive_dwim(TocTree))
-directives.register_directive('module', directive_dwim(Module))
-directives.register_directive('currentmodule', directive_dwim(CurrentModule))
 directives.register_directive('sectionauthor', directive_dwim(Author))
 directives.register_directive('moduleauthor', directive_dwim(Author))
 directives.register_directive('program', directive_dwim(Program))

File sphinx/domains.py

 import string
 
 from docutils import nodes
+from docutils.parsers.rst import directives
 
 from sphinx import addnodes
 from sphinx.roles import XRefRole
 from sphinx.directives import DescDirective
 from sphinx.util import make_refnode
+from sphinx.util.compat import Directive
 
 
 class Domain(object):
     label = ''
 
     # data value for a fresh environment
-    initial_data = {
-        
-    }
+    initial_data = {}
     # data version
     data_version = 0
 
     def __init__(self, env):
         self.env = env
-        self.data = env.domaindata.get(self.name, self.initial_data)
-        if 'version' in self.data and self.data['version'] < self.data_version:
-            raise IOError('data of %r domain out of date' % self.label)
+        if self.name not in env.domaindata:
+            new_data = self.initial_data.copy()
+            new_data['version'] = self.data_version
+            self.data = env.domaindata[self.name] = new_data
+        else:
+            self.data = env.domaindata[self.name]
+            if self.data['version'] < self.data_version:
+                raise IOError('data of %r domain out of date' % self.label)
         self._role_cache = {}
         self._directive_cache = {}
 
-    def __getstate__(self):
-        # can't pickle the adapter caches
-        state = self.__dict__.copy()
-        state['_role_cache'] = {}
-        state['_directive_cache'] = {}
-        return state
-
-    #def clear_doc
+    def clear_doc(self, docname):
+        """
+        Remove traces of a document in the domain-specific inventories.
+        """
+        pass
 
     def role(self, name):
         """
             signode['ids'].append(fullname)
             signode['first'] = (not self.names)
             self.state.document.note_explicit_target(signode)
-            self.env.note_descref(fullname, self.desctype, self.lineno)
+            objects = self.env.domains['py'].data['objects']
+            if fullname in objects:
+                self.env.warn(
+                    self.env.docname,
+                    'duplicate object description of %s, ' % fullname +
+                    'other instance in ' +
+                    self.env.doc2path(objects[fullname][0]),
+                    self.lineno)
+            objects[fullname] = (self.env.docname, self.desctype)
 
         indextext = self.get_index_text(modname, name_cls)
         if indextext:
             self.clsname_set = True
 
 
+class PyModule(Directive):
+    """
+    Directive to mark description of a new module.
+    """
+
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {
+        'platform': lambda x: x,
+        'synopsis': lambda x: x,
+        'noindex': directives.flag,
+        'deprecated': directives.flag,
+    }
+
+    def run(self):
+        env = self.state.document.settings.env
+        modname = self.arguments[0].strip()
+        noindex = 'noindex' in self.options
+        env.currmodule = modname
+        env.domains['py'].data['modules'][modname] = \
+            (env.docname, self.options.get('synopsis', ''),
+             self.options.get('platform', ''), 'deprecated' in self.options)
+        modulenode = addnodes.module()
+        modulenode['modname'] = modname
+        modulenode['synopsis'] = self.options.get('synopsis', '')
+        targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
+        self.state.document.note_explicit_target(targetnode)
+        ret = [modulenode, targetnode]
+        if 'platform' in self.options:
+            platform = self.options['platform']
+            modulenode['platform'] = platform
+            node = nodes.paragraph()
+            node += nodes.emphasis('', _('Platforms: '))
+            node += nodes.Text(platform, platform)
+            ret.append(node)
+        # the synopsis isn't printed; in fact, it is only used in the
+        # modindex currently
+        if not noindex:
+            indextext = _('%s (module)') % modname
+            inode = addnodes.index(entries=[('single', indextext,
+                                             'module-' + modname, modname)])
+            ret.insert(0, inode)
+        return ret
+
+
+class PyCurrentModule(Directive):
+    """
+    This directive is just to tell Sphinx that we're documenting
+    stuff in module foo, but links to module foo won't lead here.
+    """
+
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def run(self):
+        env = self.state.document.settings.env
+        modname = self.arguments[0].strip()
+        if modname == 'None':
+            env.currmodule = None
+        else:
+            env.currmodule = modname
+        return []
+
+
 class PyXRefRole(XRefRole):
     def process_link(self, env, pnode, has_explicit_title, title, target):
         pnode['modname'] = env.currmodule
         'classmethod': ClassmemberDesc,
         'staticmethod': ClassmemberDesc,
         'attribute': ClassmemberDesc,
+        'module': PyModule,
+        'currentmodule': PyCurrentModule,
     }
     roles = {
         'data': PyXRefRole(),
         'mod': PyXRefRole(),
         'obj': PyXRefRole(),
     }
+    initial_data = {
+        'objects': {},  # fullname -> docname, desctype
+        'modules': {},  # modname -> docname, synopsis, platform, deprecated
+    }
+
+    def clear_doc(self, docname):
+        for fullname, (fn, _) in self.data['objects'].items():
+            if fn == docname:
+                del self.data['objects'][fullname]
+        for modname, (fn, _, _, _) in self.data['modules'].items():
+            if fn == docname:
+                del self.data['modules'][modname]
 
     def find_desc(self, env, modname, classname, name, type, searchorder=0):
         """
         if not name:
             return None, None
 
+        objects = self.data['objects']
+
         newname = None
         if searchorder == 1:
             if modname and classname and \
-                   modname + '.' + classname + '.' + name in env.descrefs:
+                   modname + '.' + classname + '.' + name in objects:
                 newname = modname + '.' + classname + '.' + name
-            elif modname and modname + '.' + name in env.descrefs:
+            elif modname and modname + '.' + name in objects:
                 newname = modname + '.' + name
-            elif name in env.descrefs:
+            elif name in objects:
                 newname = name
         else:
-            if name in env.descrefs:
+            if name in objects:
                 newname = name
-            elif modname and modname + '.' + name in env.descrefs:
+            elif modname and modname + '.' + name in objects:
                 newname = modname + '.' + name
             elif modname and classname and \
-                     modname + '.' + classname + '.' + name in env.descrefs:
+                     modname + '.' + classname + '.' + name in objects:
                 newname = modname + '.' + classname + '.' + name
             # special case: builtin exceptions have module "exceptions" set
             elif type == 'exc' and '.' not in name and \
-                 'exceptions.' + name in env.descrefs:
+                 'exceptions.' + name in objects:
                 newname = 'exceptions.' + name
             # special case: object methods
             elif type in ('func', 'meth') and '.' not in name and \
-                 'object.' + name in env.descrefs:
+                 'object.' + name in objects:
                 newname = 'object.' + name
         if newname is None:
             return None, None
-        return newname, env.descrefs[newname]
+        return newname, objects[newname]
 
     def resolve_xref(self, env, fromdocname, builder,
                      typ, target, node, contnode):
         if (typ == 'mod' or
-            typ == 'obj' and target in env.modules):
+            typ == 'obj' and target in self.data['modules']):
             docname, synopsis, platform, deprecated = \
-                env.modules.get(target, ('','','', ''))
+                self.data['modules'].get(target, ('','','', ''))
             if not docname:
                 return None
             elif docname == fromdocname:
                 return make_refnode(builder, fromdocname, docname,
                                     'module-' + target, contnode, title)
         else:
-            # "descrefs"
             modname = node['modname']
             clsname = node['classname']
             searchorder = node.hasattr('refspecific') and 1 or 0
             signode['ids'].append(name)
             signode['first'] = (not self.names)
             self.state.document.note_explicit_target(signode)
-            self.env.note_descref(name, self.desctype, self.lineno)
+            inv = self.env.domains['c'].data['objects']
+            if name in inv:
+                self.env.warn(
+                    self.env.docname,
+                    'duplicate C object description of %s, ' % name +
+                    'other instance in ' + self.env.doc2path(inv[name][0]),
+                    self.lineno)
+            inv[name] = (self.env.docname, self.desctype)
 
         indextext = self.get_index_text(name)
         if indextext:
         'data': XRefRole(),
         'type': XRefRole(),
     }
+    initial_data = {
+        'objects': {},  # fullname -> docname, desctype
+    }
+
+    def clear_doc(self, docname):
+        for fullname, (fn, _) in self.data['objects'].items():
+            if fn == docname:
+                del self.data['objects'][fullname]
 
     def resolve_xref(self, env, fromdocname, builder,
                      typ, target, node, contnode):
         # strip pointer asterisk
         target = target.rstrip(' *')
-        # XXX descrefs
-        if target not in env.descrefs:
+        if target not in self.data:
             return None
-        desc = env.descrefs[target]
+        desc = self.data[target]
         return make_refnode(builder, fromdocname, desc[0], contnode, target)
 
 

File sphinx/environment.py

         self.glob_toctrees = set()  # docnames that have :glob: toctrees
         self.numbered_toctrees = set() # docnames that have :numbered: toctrees
 
-        # domain-specific inventories
-        self.domaindata = {}        # domainname -> object
+        # domain-specific inventories, here to be pickled
+        self.domaindata = {}        # domainname -> domain-specific object
 
         # X-ref target inventory
-        self.descrefs = {}          # fullname -> docname, desctype
-        self.modules = {}           # modname -> docname, synopsis,
-                                    #            platform, deprecated
         self.labels = {}            # labelname -> docname, labelid, sectionname
         self.anonlabels = {}        # labelname -> docname, labelid
         self.progoptions = {}       # (program, name) -> docname, labelid
                 fnset.discard(docname)
                 if not fnset:
                     del self.files_to_rebuild[subfn]
-            for fullname, (fn, _) in self.descrefs.items():
-                if fn == docname:
-                    del self.descrefs[fullname]
-            for modname, (fn, _, _, _) in self.modules.items():
-                if fn == docname:
-                    del self.modules[modname]
             for labelname, (fn, _, _) in self.labels.items():
                 if fn == docname:
                     del self.labels[labelname]
                 new = [change for change in changes if change[1] != docname]
                 changes[:] = new
 
+        # XXX why does this not work inside the if?
+        for domain in self.domains.values():
+            domain.clear_doc(docname)
+
     def doc2path(self, docname, base=True, suffix=None):
         """
         Return the filename for the document name.
     # -------
     # these are called from docutils directives and therefore use self.docname
     #
-    def note_descref(self, fullname, desctype, line):
-        if fullname in self.descrefs:
-            self.warn(self.docname,
-                      'duplicate canonical description name %s, ' % fullname +
-                      'other instance in ' +
-                      self.doc2path(self.descrefs[fullname][0]),
-                      line)
-        self.descrefs[fullname] = (self.docname, desctype)
-
-    def note_module(self, modname, synopsis, platform, deprecated):
-        self.modules[modname] = (self.docname, synopsis, platform, deprecated)
-
     def note_progoption(self, optname, labelid):
         self.progoptions[self.currprogram, optname] = (self.docname, labelid)
 

File sphinx/ext/coverage.py

 
     def build_c_coverage(self):
         # Fetch all the info from the header files
+        c_objects = self.env.domains['c'].data['objects']
         for filename in self.c_sourcefiles:
             undoc = []
             f = open(filename, 'r')
                         match = regex.match(line)
                         if match:
                             name = match.groups()[0]
-                            if name not in self.env.descrefs:
+                            if name not in c_objects:
                                 for exp in self.c_ignorexps.get(key, ()):
                                     if exp.match(name):
                                         break
             op.close()
 
     def build_py_coverage(self):
-        for mod_name in self.env.modules:
+        objects = self.env.domains['py'].data['objects']
+        modules = self.env.domains['py'].data['modules']
+        
+        for mod_name in modules:
             ignore = False
             for exp in self.mod_ignorexps:
                 if exp.match(mod_name):
                 full_name = '%s.%s' % (mod_name, name)
 
                 if inspect.isfunction(obj):
-                    if full_name not in self.env.descrefs:
+                    if full_name not in objects:
                         for exp in self.fun_ignorexps:
                             if exp.match(name):
                                 break
                         if exp.match(name):
                             break
                     else:
-                        if full_name not in self.env.descrefs:
+                        if full_name not in objects:
                             # not documented at all
                             classes[name] = []
                             continue
                                 continue
 
                             full_attr_name = '%s.%s' % (full_name, attr_name)
-                            if full_attr_name not in self.env.descrefs:
+                            if full_attr_name not in objects:
                                 attrs.append(attr_name)
 
                         if attrs:

File sphinx/search.py

 
     def get_modules(self, fn2index):
         rv = {}
+        # XXX implement search capability
+        return rv
         for name, (doc, _, _, _) in self.env.modules.iteritems():
             if doc in fn2index:
                 rv[name] = fn2index[doc]
     def get_descrefs(self, fn2index):
         rv = {}
         dt = self._desctypes
+        # XXX implement search capability
+        return rv
         for fullname, (doc, desctype) in self.env.descrefs.iteritems():
             if doc not in fn2index:
                 continue

File tests/test_env.py

 
 def setup_module():
     global app, env
-    app = TestApp(srcdir='(temp)')
+    app = TestApp(srcdir='(temp)', freshenv=True)
     env = app.env
-    #env = BuildEnvironment(app.srcdir, app.doctreedir, app.config)
     env.set_warnfunc(lambda *args: warnings.append(args))
 
 def teardown_module():
     assert 'autodoc' not in env.found_docs
 
 def test_object_inventory():
-    refs = env.descrefs
+    refs = env.domains['py'].data['objects']
 
     assert 'func_without_module' in refs
     assert refs['func_without_module'] == ('desc', 'function')
     assert 'func_in_module' not in refs
     assert 'func_noindex' not in refs
 
-    assert 'mod' in env.modules
-    assert env.modules['mod'] == ('desc', 'Module synopsis.', 'UNIX', False)
+    assert env.domains['py'].data['modules']['mod'] == \
+        ('desc', 'Module synopsis.', 'UNIX', False)