[Python-checkins] r66585 - in doctools/trunk/sphinx: builder.py search.py util/jsdump.py util/json.py

georg.brandl python-checkins at python.org
Wed Sep 24 14:02:15 CEST 2008


Author: georg.brandl
Date: Wed Sep 24 14:01:16 2008
New Revision: 66585

Log:
Rename util.json to util.jsdump because it doesn't generate valid JSON anymore.
The JSON html builder still needs simplejson to work.


Added:
   doctools/trunk/sphinx/util/jsdump.py   (props changed)
      - copied unchanged from r66584, /doctools/trunk/sphinx/util/json.py
Removed:
   doctools/trunk/sphinx/util/json.py
Modified:
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/search.py

Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Wed Sep 24 14:01:16 2008
@@ -26,7 +26,7 @@
 from docutils.readers.doctree import Reader as DoctreeReader
 
 from sphinx import addnodes, locale, __version__
-from sphinx.util import ensuredir, relative_uri, SEP, os_path, json, texescape
+from sphinx.util import ensuredir, relative_uri, SEP, os_path, texescape
 from sphinx.htmlhelp import build_hhx
 from sphinx.htmlwriter import HTMLWriter, HTMLTranslator, SmartyPantsHTMLTranslator
 from sphinx.textwriter import TextWriter
@@ -36,6 +36,14 @@
 from sphinx.util.console import bold, purple, darkgreen
 from sphinx.search import js_index
 
+try:
+    import json
+except ImportError:
+    try:
+        import ssimplejson as json
+    except ImportError:
+        json = None
+
 # side effect: registers roles and directives
 from sphinx import roles
 from sphinx import directives
@@ -802,9 +810,6 @@
         self.init_translator_class()
         self.templates = None   # no template bridge necessary
 
-    indexer_format = property(lambda x: x.implementation, doc='''
-        Alias the indexer format to the serilization implementation''')
-
     def get_target_uri(self, docname, typ=None):
         if docname == 'index':
             return ''
@@ -866,6 +871,7 @@
     A Builder that dumps the generated HTML into pickle files.
     """
     implementation = pickle
+    indexer_format = pickle
     name = 'pickle'
     out_suffix = '.fpickle'
     globalcontext_filename = 'globalcontext.pickle'
@@ -877,11 +883,20 @@
     A builder that dumps the generated HTML into JSON files.
     """
     implementation = json
+    indexer_format = json
     name = 'json'
     out_suffix = '.fjson'
     globalcontext_filename = 'globalcontext.json'
     searchindex_filename = 'searchindex.json'
 
+    def init(self):
+        if json is None:
+            from sphinx.application import SphinxError
+            raise SphinxError('The module simplejson (or json in Python >= 2.6) '
+                              'is not available. The JSONHTMLBuilder builder '
+                              'will not work.')
+        SerializingHTMLBuilder.init(self)
+
 
 class HTMLHelpBuilder(StandaloneHTMLBuilder):
     """

Modified: doctools/trunk/sphinx/search.py
==============================================================================
--- doctools/trunk/sphinx/search.py	(original)
+++ doctools/trunk/sphinx/search.py	Wed Sep 24 14:01:16 2008
@@ -15,7 +15,7 @@
 from docutils.nodes import Text, NodeVisitor
 
 from sphinx.util.stemmer import PorterStemmer
-from sphinx.util import json, rpartition
+from sphinx.util import jsdump, rpartition
 
 
 word_re = re.compile(r'\w+(?u)')
@@ -37,22 +37,20 @@
     """
     The search index as javascript file that calls a function
     on the documentation search object to register the index.
-    This serializing system does not support chaining because
-    simplejson (which it depends on) doesn't support it either.
     """
 
     PREFIX = 'Search.setIndex('
     SUFFIX = ')'
 
     def dumps(self, data):
-        return self.PREFIX + json.dumps(data) + self.SUFFIX
+        return self.PREFIX + jsdump.dumps(data) + self.SUFFIX
 
     def loads(self, s):
         data = s[len(self.PREFIX):-len(self.SUFFIX)]
         if not data or not s.startswith(self.PREFIX) or not \
            s.endswith(self.SUFFIX):
             raise ValueError('invalid data')
-        return json.loads(data)
+        return jsdump.loads(data)
 
     def dump(self, data, f):
         f.write(self.dumps(data))
@@ -95,7 +93,7 @@
     passed to the `feed` method.
     """
     formats = {
-        'json':     json,
+        'jsdump':   jsdump,
         'pickle':   pickle
     }
 

Deleted: doctools/trunk/sphinx/util/json.py
==============================================================================
--- doctools/trunk/sphinx/util/json.py	Wed Sep 24 14:01:16 2008
+++ (empty file)
@@ -1,195 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    sphinx.util.json
-    ~~~~~~~~~~~~~~~~
-
-    This module implements a simple JSON serializer if simplejson is
-    unavailable.
-
-    This is not fully JSON compliant but enough for the searchindex.
-    And the generated files are smaller than the simplejson ones.
-
-    Uses the basestring encode function from simplejson.
-
-    :copyright: 2008 by Armin Ronacher, Bob Ippolito, Georg Brandl.
-    :license: BSD.
-"""
-
-import re
-
-_str_re  = re.compile(r'"(\\\\|\\"|[^"])*"')
-_int_re  = re.compile(r'\d+')
-_name_re = re.compile(r'[a-zA-Z]\w*')
-_nameonly_re = re.compile(r'[a-zA-Z]\w*$')
-
-# escape \, ", control characters and everything outside ASCII
-ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
-ESCAPE_DICT = {
-    '\\': '\\\\',
-    '"': '\\"',
-    '\b': '\\b',
-    '\f': '\\f',
-    '\n': '\\n',
-    '\r': '\\r',
-    '\t': '\\t',
-}
-
-ESCAPED = re.compile(r'\\u.{4}|\\.')
-
-
-def encode_string(s):
-    def replace(match):
-        s = match.group(0)
-        try:
-            return ESCAPE_DICT[s]
-        except KeyError:
-            n = ord(s)
-            if n < 0x10000:
-                return '\\u%04x' % (n,)
-            else:
-                # surrogate pair
-                n -= 0x10000
-                s1 = 0xd800 | ((n >> 10) & 0x3ff)
-                s2 = 0xdc00 | (n & 0x3ff)
-                return '\\u%04x\\u%04x' % (s1, s2)
-    return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
-
-def decode_string(s):
-    return ESCAPED.sub(lambda m: eval('u"'+m.group()+'"'), s)
-
-
-reswords = set("""\
-abstract   else   instanceof   switch
-boolean   enum   int   synchronized
-break   export   interface   this
-byte   extends   long   throw
-case   false   native   throws
-catch   final   new   transient
-char   finally   null   true
-class   float   package   try
-const   for   private   typeof
-continue   function   protected   var
-debugger   goto   public   void
-default   if   return   volatile
-delete   implements   short   while
-do   import   static   with
-double   in   super""".split())
-
-def dumps(obj, key=False):
-    if key:
-        if not isinstance(obj, basestring):
-            obj = str(obj)
-        if _nameonly_re.match(obj) and obj not in reswords:
-            return obj  # return it as a bare word
-        else:
-            return encode_string(obj)
-    if obj is None:
-        return 'null'
-    elif obj is True or obj is False:
-        return obj and 'true' or 'false'
-    elif isinstance(obj, (int, long, float)):
-        return str(obj)
-    elif isinstance(obj, dict):
-        return '{%s}' % ','.join('%s:%s' % (
-            dumps(key, True),
-            dumps(value)
-        ) for key, value in obj.iteritems())
-    elif isinstance(obj, (tuple, list, set)):
-        return '[%s]' % ','.join(dumps(x) for x in obj)
-    elif isinstance(obj, basestring):
-        return encode_string(obj)
-    raise TypeError(type(obj))
-
-def dump(obj, f):
-    f.write(dumps(obj))
-
-
-def loads(x):
-    """Loader that can read the JS subset the indexer produces."""
-    nothing = object()
-    i = 0
-    n = len(x)
-    stack = []
-    obj = nothing
-    key = False
-    keys = []
-    while i < n:
-        c = x[i]
-        if c == '{':
-            obj = {}
-            stack.append(obj)
-            key = True
-            keys.append(nothing)
-            i += 1
-        elif c == '[':
-            obj = []
-            stack.append(obj)
-            key = False
-            keys.append(nothing)
-            i += 1
-        elif c in '}]':
-            if key:
-                raise ValueError("unfinished dict")
-            oldobj = stack.pop()
-            keys.pop()
-            if stack:
-                obj = stack[-1]
-                if isinstance(obj, dict):
-                    if keys[-1] is nothing:
-                        raise ValueError("invalid key object", oldobj)
-                    obj[keys[-1]] = oldobj
-                else:
-                    obj.append(oldobj)
-            else:
-                break
-            i += 1
-        elif c == ',':
-            if key:
-                raise ValueError("multiple keys")
-            if isinstance(obj, dict):
-                key = True
-            i += 1
-        elif c == ':':
-            if not isinstance(obj, dict):
-                raise ValueError("colon in list")
-            i += 1
-            if not key:
-                raise ValueError("multiple values")
-            key = False
-        else:
-            m = _str_re.match(x, i)
-            if m:
-                y = decode_string(m.group()[1:-1])
-            else:
-                m = _int_re.match(x, i)
-                if m:
-                    y = int(m.group())
-                else:
-                    m = _name_re.match(x, i)
-                    if m:
-                        y = m.group()
-                        if y == 'true':
-                            y = True
-                        elif y == 'false':
-                            y = False
-                        elif y == 'null':
-                            y = None
-                        elif not key:
-                            raise ValueError("bareword as value")
-                    else:
-                        raise ValueError("read error at pos %d" % i)
-            i = m.end()
-            if isinstance(obj, dict):
-                if key:
-                    keys[-1] = y
-                else:
-                    obj[keys[-1]] = y
-                    key = False
-            else:
-                obj.append(y)
-    if obj is nothing:
-        raise ValueError("nothing loaded from string")
-    return obj
-
-def load(f):
-    return loads(f.read())


More information about the Python-checkins mailing list