Author: adrian
Date: 2007-02-02 14:06:20 -0600 (Fri, 02 Feb 2007)
New Revision: 4457

Added:
   django/branches/newforms-admin/django/utils/simplejson/jsonfilter.py
Modified:
   django/branches/newforms-admin/django/utils/simplejson/LICENSE.txt
   django/branches/newforms-admin/django/utils/simplejson/__init__.py
   django/branches/newforms-admin/django/utils/simplejson/decoder.py
   django/branches/newforms-admin/django/utils/simplejson/encoder.py
   django/branches/newforms-admin/django/utils/simplejson/scanner.py
   django/branches/newforms-admin/tests/modeltests/test_client/views.py
Log:
newforms-admin: Merged to [4456]

Modified: django/branches/newforms-admin/django/utils/simplejson/LICENSE.txt
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/LICENSE.txt  
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/django/utils/simplejson/LICENSE.txt  
2007-02-02 20:06:20 UTC (rev 4457)
@@ -1,4 +1,4 @@
-simplejson 1.3
+simplejson 1.5
 Copyright (c) 2006 Bob Ippolito
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of

Modified: django/branches/newforms-admin/django/utils/simplejson/__init__.py
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/__init__.py  
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/django/utils/simplejson/__init__.py  
2007-02-02 20:06:20 UTC (rev 4457)
@@ -27,6 +27,21 @@
     >>> io.getvalue()
     '["streaming API"]'
 
+Compact encoding::
+
+    >>> import simplejson
+    >>> simplejson.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
+    '[1,2,3,{"4":5,"6":7}]'
+
+Pretty printing::
+
+    >>> import simplejson
+    >>> print simplejson.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
+    {
+        "4": 5, 
+        "6": 7
+    }
+
 Decoding JSON::
     
     >>> import simplejson
@@ -68,10 +83,10 @@
     ['[', '2.0', ', ', '1.0', ']']
     
 
-Note that the JSON produced by this module is a subset of YAML,
-so it may be used as a serializer for that as well.
+Note that the JSON produced by this module's default settings
+is a subset of YAML, so it may be used as a serializer for that as well.
 """
-__version__ = '1.3'
+__version__ = '1.5'
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONEncoder',
@@ -81,7 +96,7 @@
 from django.utils.simplejson.encoder import JSONEncoder
 
 def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
-        allow_nan=True, cls=None, **kw):
+        allow_nan=True, cls=None, indent=None, **kw):
     """
     Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
     ``.write()``-supporting file-like object).
@@ -105,6 +120,10 @@
     in strict compliance of the JSON specification, instead of using the
     JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
 
+    If ``indent`` is a non-negative integer, then JSON array elements and 
object
+    members will be pretty-printed with that indent level.  An indent level
+    of 0 will only insert newlines.  ``None`` is the most compact 
representation.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
     the ``cls`` kwarg.
@@ -112,7 +131,7 @@
     if cls is None:
         cls = JSONEncoder
     iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
-        check_circular=check_circular, allow_nan=allow_nan,
+        check_circular=check_circular, allow_nan=allow_nan, indent=indent,
         **kw).iterencode(obj)
     # could accelerate with writelines in some versions of Python, at
     # a debuggability cost
@@ -120,7 +139,7 @@
         fp.write(chunk)
 
 def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
-        allow_nan=True, cls=None, **kw):
+        allow_nan=True, cls=None, indent=None, separators=None, **kw):
     """
     Serialize ``obj`` to a JSON formatted ``str``.
 
@@ -141,14 +160,26 @@
     strict compliance of the JSON specification, instead of using the
     JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
 
+    If ``indent`` is a non-negative integer, then JSON array elements and
+    object members will be pretty-printed with that indent level.  An indent
+    level of 0 will only insert newlines.  ``None`` is the most compact
+    representation.
+
+    If ``separators`` is an ``(item_separator, dict_separator)`` tuple
+    then it will be used instead of the default ``(', ', ': ')`` separators.
+    ``(',', ':')`` is the most compact JSON representation.
+
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
     the ``cls`` kwarg.
     """
     if cls is None:
         cls = JSONEncoder
-    return cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
-        check_circular=check_circular, allow_nan=allow_nan, **kw).encode(obj)
+    return cls(
+        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+        check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+        separators=separators,
+        **kw).encode(obj)
 
 def load(fp, encoding=None, cls=None, object_hook=None, **kw):
     """

Modified: django/branches/newforms-admin/django/utils/simplejson/decoder.py
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/decoder.py   
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/django/utils/simplejson/decoder.py   
2007-02-02 20:06:20 UTC (rev 4457)
@@ -127,6 +127,7 @@
         raise ValueError(errmsg("Expecting property name", s, end))
     end += 1
     encoding = getattr(context, 'encoding', None)
+    iterscan = JSONScanner.iterscan
     while True:
         key, end = scanstring(s, end, encoding)
         end = _w(s, end).end()
@@ -134,7 +135,7 @@
             raise ValueError(errmsg("Expecting : delimiter", s, end))
         end = _w(s, end + 1).end()
         try:
-            value, end = JSONScanner.iterscan(s, idx=end).next()
+            value, end = iterscan(s, idx=end, context=context).next()
         except StopIteration:
             raise ValueError(errmsg("Expecting object", s, end))
         pairs[key] = value
@@ -164,9 +165,10 @@
     nextchar = s[end:end + 1]
     if nextchar == ']':
         return values, end + 1
+    iterscan = JSONScanner.iterscan
     while True:
         try:
-            value, end = JSONScanner.iterscan(s, idx=end).next()
+            value, end = iterscan(s, idx=end, context=context).next()
         except StopIteration:
             raise ValueError(errmsg("Expecting object", s, end))
         values.append(value)

Modified: django/branches/newforms-admin/django/utils/simplejson/encoder.py
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/encoder.py   
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/django/utils/simplejson/encoder.py   
2007-02-02 20:06:20 UTC (rev 4457)
@@ -3,11 +3,11 @@
 """
 import re
 
-# this should match any kind of infinity
-INFCHARS = re.compile(r'[infINF]')
 ESCAPE = re.compile(r'[\x00-\x19\\"\b\f\n\r\t]')
-ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
+ESCAPE_ASCII = re.compile(r'([\\"/]|[^\ -~])')
 ESCAPE_DCT = {
+    # escape all forward slashes to prevent </script> attack
+    '/': '\\/',
     '\\': '\\\\',
     '"': '\\"',
     '\b': '\\b',
@@ -16,32 +16,32 @@
     '\r': '\\r',
     '\t': '\\t',
 }
-for i in range(20):
+for i in range(0x20):
     ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
 
+# assume this produces an infinity on all machines (probably not guaranteed)
+INFINITY = float('1e66666')
+
 def floatstr(o, allow_nan=True):
-    s = str(o)
-    # If the first non-sign is a digit then it's not a special value
-    if (o < 0.0 and s[1].isdigit()) or s[0].isdigit():
-        return s
-    elif not allow_nan:
+    # Check for specials.  Note that this type of test is processor- and/or
+    # platform-specific, so do tests which don't depend on the internals.
+
+    if o != o:
+        text = 'NaN'
+    elif o == INFINITY:
+        text = 'Infinity'
+    elif o == -INFINITY:
+        text = '-Infinity'
+    else:
+        return str(o)
+
+    if not allow_nan:
         raise ValueError("Out of range float values are not JSON compliant: %r"
             % (o,))
-    # These are the string representations on the platforms I've tried
-    if s == 'nan':
-        return 'NaN'
-    if s == 'inf':
-        return 'Infinity'
-    if s == '-inf':
-        return '-Infinity'
-    # NaN should either be inequal to itself, or equal to everything
-    if o != o or o == 0.0:
-        return 'NaN'
-    # Last ditch effort, assume inf
-    if o < 0:
-        return '-Infinity'
-    return 'Infinity'
 
+    return text
+
+
 def encode_basestring(s):
     """
     Return a JSON representation of a Python string
@@ -90,8 +90,11 @@
     implementation (to raise ``TypeError``).
     """
     __all__ = ['__init__', 'default', 'encode', 'iterencode']
+    item_separator = ', '
+    key_separator = ': '
     def __init__(self, skipkeys=False, ensure_ascii=True,
-            check_circular=True, allow_nan=True, sort_keys=False):
+            check_circular=True, allow_nan=True, sort_keys=False,
+            indent=None, separators=None):
         """
         Constructor for JSONEncoder, with sensible defaults.
 
@@ -116,6 +119,15 @@
         If sort_keys is True, then the output of dictionaries will be
         sorted by key; this is useful for regression tests to ensure
         that JSON serializations can be compared on a day-to-day basis.
+
+        If indent is a non-negative integer, then JSON array
+        elements and object members will be pretty-printed with that
+        indent level.  An indent level of 0 will only insert newlines.
+        None is the most compact representation.
+
+        If specified, separators should be a (item_separator, key_separator)
+        tuple. The default is (', ', ': '). To get the most compact JSON
+        representation you should specify (',', ':') to eliminate whitespace.
         """
 
         self.skipkeys = skipkeys
@@ -123,7 +135,14 @@
         self.check_circular = check_circular
         self.allow_nan = allow_nan
         self.sort_keys = sort_keys
+        self.indent = indent
+        self.current_indent_level = 0
+        if separators is not None:
+            self.item_separator, self.key_separator = separators
 
+    def _newline_indent(self):
+        return '\n' + (' ' * (self.indent * self.current_indent_level))
+
     def _iterencode_list(self, lst, markers=None):
         if not lst:
             yield '[]'
@@ -134,14 +153,25 @@
                 raise ValueError("Circular reference detected")
             markers[markerid] = lst
         yield '['
+        if self.indent is not None:
+            self.current_indent_level += 1
+            newline_indent = self._newline_indent()
+            separator = self.item_separator + newline_indent
+            yield newline_indent
+        else:
+            newline_indent = None
+            separator = self.item_separator
         first = True
         for value in lst:
             if first:
                 first = False
             else:
-                yield ', '
+                yield separator
             for chunk in self._iterencode(value, markers):
                 yield chunk
+        if newline_indent is not None:
+            self.current_indent_level -= 1
+            yield self._newline_indent()
         yield ']'
         if markers is not None:
             del markers[markerid]
@@ -156,6 +186,15 @@
                 raise ValueError("Circular reference detected")
             markers[markerid] = dct
         yield '{'
+        key_separator = self.key_separator
+        if self.indent is not None:
+            self.current_indent_level += 1
+            newline_indent = self._newline_indent()
+            item_separator = self.item_separator + newline_indent
+            yield newline_indent
+        else:
+            newline_indent = None
+            item_separator = self.item_separator
         first = True
         if self.ensure_ascii:
             encoder = encode_basestring_ascii
@@ -165,7 +204,7 @@
         if self.sort_keys:
             keys = dct.keys()
             keys.sort()
-            items = [(k,dct[k]) for k in keys]
+            items = [(k, dct[k]) for k in keys]
         else:
             items = dct.iteritems()
         for key, value in items:
@@ -190,11 +229,14 @@
             if first:
                 first = False
             else:
-                yield ', '
+                yield item_separator
             yield encoder(key)
-            yield ': '
+            yield key_separator
             for chunk in self._iterencode(value, markers):
                 yield chunk
+        if newline_indent is not None:
+            self.current_indent_level -= 1
+            yield self._newline_indent()
         yield '}'
         if markers is not None:
             del markers[markerid]

Copied: django/branches/newforms-admin/django/utils/simplejson/jsonfilter.py 
(from rev 4456, django/trunk/django/utils/simplejson/jsonfilter.py)
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/jsonfilter.py        
                        (rev 0)
+++ django/branches/newforms-admin/django/utils/simplejson/jsonfilter.py        
2007-02-02 20:06:20 UTC (rev 4457)
@@ -0,0 +1,40 @@
+from django.utils import simplejson
+import cgi
+
+class JSONFilter(object):
+    def __init__(self, app, mime_type='text/x-json'):
+        self.app = app
+        self.mime_type = mime_type
+
+    def __call__(self, environ, start_response):
+        # Read JSON POST input to jsonfilter.json if matching mime type
+        response = {'status': '200 OK', 'headers': []}
+        def json_start_response(status, headers):
+            response['status'] = status
+            response['headers'].extend(headers)
+        environ['jsonfilter.mime_type'] = self.mime_type
+        if environ.get('REQUEST_METHOD', '') == 'POST':
+            if environ.get('CONTENT_TYPE', '') == self.mime_type:
+                args = [_ for _ in [environ.get('CONTENT_LENGTH')] if _]
+                data = environ['wsgi.input'].read(*map(int, args))
+                environ['jsonfilter.json'] = simplejson.loads(data)
+        res = simplejson.dumps(self.app(environ, json_start_response))
+        jsonp = cgi.parse_qs(environ.get('QUERY_STRING', '')).get('jsonp')
+        if jsonp:
+            content_type = 'text/javascript'
+            res = ''.join(jsonp + ['(', res, ')'])
+        elif 'Opera' in environ.get('HTTP_USER_AGENT', ''):
+            # Opera has bunk XMLHttpRequest support for most mime types
+            content_type = 'text/plain'
+        else:
+            content_type = self.mime_type
+        headers = [
+            ('Content-type', content_type),
+            ('Content-length', len(res)),
+        ]
+        headers.extend(response['headers'])
+        start_response(response['status'], headers)
+        return [res]
+
+def factory(app, global_conf, **kw):
+    return JSONFilter(app, **kw)

Modified: django/branches/newforms-admin/django/utils/simplejson/scanner.py
===================================================================
--- django/branches/newforms-admin/django/utils/simplejson/scanner.py   
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/django/utils/simplejson/scanner.py   
2007-02-02 20:06:20 UTC (rev 4457)
@@ -3,11 +3,12 @@
 """
 import sre_parse, sre_compile, sre_constants
 from sre_constants import BRANCH, SUBPATTERN
+from re import VERBOSE, MULTILINE, DOTALL
 import re
 
 __all__ = ['Scanner', 'pattern']
 
-FLAGS = (re.VERBOSE | re.MULTILINE | re.DOTALL)
+FLAGS = (VERBOSE | MULTILINE | DOTALL)
 class Scanner(object):
     def __init__(self, lexicon, flags=FLAGS):
         self.actions = [None]

Modified: django/branches/newforms-admin/tests/modeltests/test_client/views.py
===================================================================
--- django/branches/newforms-admin/tests/modeltests/test_client/views.py        
2007-02-02 17:35:55 UTC (rev 4456)
+++ django/branches/newforms-admin/tests/modeltests/test_client/views.py        
2007-02-02 20:06:20 UTC (rev 4457)
@@ -26,10 +26,10 @@
     "A view that redirects all requests to the GET view"
     return HttpResponseRedirect('/test_client/get_view/')
     
[EMAIL PROTECTED]
 def login_protected_view(request):
     "A simple view that is login protected."
     t = Template('This is a login protected test. Username is {{ user.username 
}}.', name='Login Template')
     c = Context({'user': request.user})
     
     return HttpResponse(t.render(c))
+login_protected_view = login_required(login_protected_view)
\ No newline at end of file


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to