Commits

Anonymous committed a2afdae

Allow the config to act as an extension.

  • Participants
  • Parent commits d73831f

Comments (0)

Files changed (8)

 * sphinx.builder, sphinx.environment: Gracefully handle some exception
   cases.
 
+* sphinx.config: The config file itself can be an extension (if it
+  provides a setup() function).
+
 
 Release 0.1.61950 (Mar 26, 2008)
 ================================
 # All configuration values have a default value; values that are commented out
 # serve to show the default value.
 
-import sys, os
+import sys, os, re
 
 # If your extensions are in another directory, add it here.
-sys.path.append(os.path.dirname(__file__))
+#sys.path.append(os.path.dirname(__file__))
 
 # General configuration
 # ---------------------
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
-extensions = ['ext', 'sphinx.ext.autodoc', 'sphinx.ext.doctest']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 #latex_appendices = []
 
 automodule_skip_lines = 4
+
+
+# Extension interface
+# -------------------
+
+from sphinx import addnodes
+
+dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
+
+def parse_directive(env, sig, signode):
+    if not sig.startswith('.'):
+        dec_sig = '.. %s::' % sig
+        signode += addnodes.desc_name(dec_sig, dec_sig)
+        return sig
+    m = dir_sig_re.match(sig)
+    if not m:
+        signode += addnodes.desc_name(sig, sig)
+        return sig
+    name, args = m.groups()
+    dec_name = '.. %s::' % name
+    signode += addnodes.desc_name(dec_name, dec_name)
+    signode += addnodes.desc_classname(args, args)
+    return name
+
+
+def parse_role(env, sig, signode):
+    signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
+    return sig
+
+
+def setup(app):
+    app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
+    app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
+    app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')
    That way, you can load an extension called ``extname`` from the documentation
    root's subdirectory ``sphinxext``.
 
+   The configuration file itself can be an extension; for that, you only need to
+   provide a :func:`setup` function in it.
+
 .. confval:: templates_path
 
    A list of paths that contain extra templates (or templates that overwrite

doc/ext.py

-# -*- coding: utf-8 -*-
-"""
-    ext.py -- Sphinx extension for the Sphinx documentation
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    :copyright: 2008 by Georg Brandl.
-    :license: BSD.
-"""
-
-import re
-
-from sphinx import addnodes
-
-dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
-
-def parse_directive(env, sig, signode):
-    if not sig.startswith('.'):
-        dec_sig = '.. %s::' % sig
-        signode += addnodes.desc_name(dec_sig, dec_sig)
-        return sig
-    m = dir_sig_re.match(sig)
-    if not m:
-        signode += addnodes.desc_name(sig, sig)
-        return sig
-    name, args = m.groups()
-    dec_name = '.. %s::' % name
-    signode += addnodes.desc_name(dec_name, dec_name)
-    signode += addnodes.desc_classname(args, args)
-    return name
-
-
-def parse_role(env, sig, signode):
-    signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
-    return sig
-
-
-def setup(app):
-    app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
-    app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
-    app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')

doc/extensions.rst

 are so-called "hook points" at strategic places throughout the build process,
 where an extension can register a hook and run specialized code.
 
+The configuration file itself can be an extension, see the :confval:`extensions`
+configuration value docs.
+
 .. toctree::
 
    ext/appapi

sphinx/application.py

         # load all extension modules
         for extension in getattr(self.config, 'extensions', ()):
             self.setup_extension(extension)
+        # the config file itself can be an extension
+        if hasattr(self.config, 'setup'):
+            self.config.setup(self)
 
         # this must happen after loading extension modules, since they
         # can add custom config values
 """
 
 import os
-import types
 from os import path
 
 
             execfile(config['__file__'], config)
         finally:
             os.chdir(olddir)
-        # remove potentially pickling-problematic values
-        for key, val in config.items():
-            if key.startswith('_') or isinstance(val, types.ModuleType):
-                del config[key]
         self.__dict__.update(config)
 
     def init_defaults(self):
     def __getitem__(self, name):
         return getattr(self, name)
 
+    def __setitem__(self, name, value):
+        setattr(self, name, value)
+
+    def __delitem__(self, name):
+        delattr(self, name)
+
     def __contains__(self, name):
         return hasattr(self, name)

sphinx/environment.py

 import os
 import time
 import heapq
+import types
 import difflib
 import itertools
 import cPickle as pickle
         warnfunc = self._warnfunc
         self.set_warnfunc(None)
         picklefile = open(filename, 'wb')
+        # remove potentially pickling-problematic values from config
+        for key, val in vars(self.config).items():
+            if key.startswith('_') or \
+                   isinstance(val, types.ModuleType) or \
+                   isinstance(val, types.FunctionType):
+                del self.config[key]
         try:
             pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
         finally: