Initial import from tarball
This commit is contained in:
commit
49048a26cb
|
@ -0,0 +1,66 @@
|
|||
0.1:
|
||||
|
||||
* Initial release
|
||||
|
||||
0.1.1
|
||||
|
||||
* Added benchmarking script
|
||||
* Added support for more serializer modules
|
||||
|
||||
0.2
|
||||
|
||||
* Added exception handling so that all supported modules will result in the
|
||||
same exceptions being thrown. The exceptions are the same that are used
|
||||
by the JSON module from python 2.7, TypeError for serialize and
|
||||
ValueError for deserialize.
|
||||
* '''NOTE''' API changed. the implementation property is now an object, not
|
||||
a string
|
||||
* Rewrote module loading code, so it's now easier to add and rearrange
|
||||
JSON modules
|
||||
|
||||
0.2.1
|
||||
|
||||
* Fixed bug that rendered the lib uninstalleable with easy_install if there
|
||||
was no supported json module allready installed
|
||||
|
||||
0.2.2
|
||||
|
||||
* Fixed bug #2. Installation failed if there were noe compatible json
|
||||
implementations installed, because the module was loaeded, and threw import
|
||||
exception during the install process.
|
||||
|
||||
0.2.3
|
||||
|
||||
* Fixed bug #3
|
||||
* Fixed bug in benchmarking script
|
||||
|
||||
0.2.4
|
||||
|
||||
* Added support for py-yajl (Thanks Benjamin Anderson)
|
||||
* Improved benchmark script to test serialization performance and
|
||||
to use real life data for tests.
|
||||
|
||||
0.2.5
|
||||
|
||||
* Added loads and dumps methods so anyjson can be used interchangably
|
||||
with the stdlib json module. Note: The original methods are still
|
||||
in place. Nothing from the 0.2.4 API is changed, removed or deprecated
|
||||
in this release.
|
||||
|
||||
0.3
|
||||
|
||||
* Added support for python3
|
||||
|
||||
0.3.1
|
||||
|
||||
* Added deprecation warning for cjson and made it the least preferred
|
||||
implementation. See: http://pypi.python.org/pypi/python-cjson/1.0.5
|
||||
|
||||
0.3.2
|
||||
|
||||
* Added support for buffer objects
|
||||
|
||||
0.3.3
|
||||
|
||||
* Fixed bug in buffer object support related to differences between
|
||||
stringIO and cStringIO
|
|
@ -0,0 +1,29 @@
|
|||
This software is licensed under the ``New BSD License``:
|
||||
|
||||
Copyright (c) 2009, by the authors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the authors nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,4 @@
|
|||
include CHANGELOG
|
||||
include README
|
||||
include LICENSE
|
||||
graft tests
|
|
@ -0,0 +1,85 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: anyjson
|
||||
Version: 0.3.3
|
||||
Summary: Wraps the best available JSON implementation available in a common interface
|
||||
Home-page: http://bitbucket.org/runeh/anyjson/
|
||||
Author: Rune Halvorsen
|
||||
Author-email: runefh@gmail.com
|
||||
License: BSD
|
||||
Description: ##############################
|
||||
anyjson - JSON library wrapper
|
||||
##############################
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Anyjson loads whichever is the fastest JSON module installed and provides
|
||||
a uniform API regardless of which JSON implementation is used.
|
||||
|
||||
Originally part of carrot (http://github.com/ask/carrot/)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To serialize a python object to a JSON string, call the `serialize` function:
|
||||
|
||||
>>> import anyjson
|
||||
>>> anyjson.serialize(["test", 1, {"foo": 3.141592}, "bar"])
|
||||
'["test", 1, {"foo": 3.141592}, "bar"]'
|
||||
|
||||
Conversion the other way is done with the `deserialize` call.
|
||||
|
||||
>>> anyjson.deserialize("""["test", 1, {"foo": 3.141592}, "bar"]""")
|
||||
['test', 1, {'foo': 3.1415920000000002}, 'bar']
|
||||
|
||||
Regardless of the JSON implementation used, the exceptions will be the same.
|
||||
This means that trying to serialize something not compatible with JSON
|
||||
raises a TypeError:
|
||||
|
||||
>>> anyjson.serialize([object()])
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
TypeError: object is not JSON encodable
|
||||
|
||||
And deserializing a JSON string with invalid JSON raises a ValueError:
|
||||
|
||||
>>> anyjson.deserialize("""['missing square brace!""")
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
ValueError: cannot parse JSON description
|
||||
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
The module is maintaned by Rune F. Halvorsen <runefh@gmail.com>.
|
||||
The project resides at http://bitbucket.org/runeh/anyjson . Bugs and feature
|
||||
requests can be submitted there. Patches are also very welcome.
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
See CHANGELOG file
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
see the LICENSE file
|
||||
|
||||
Keywords: json
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.4
|
||||
Classifier: Programming Language :: Python :: 2.5
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.1
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Programming Language :: Python :: Implementation :: Jython
|
|
@ -0,0 +1,59 @@
|
|||
##############################
|
||||
anyjson - JSON library wrapper
|
||||
##############################
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Anyjson loads whichever is the fastest JSON module installed and provides
|
||||
a uniform API regardless of which JSON implementation is used.
|
||||
|
||||
Originally part of carrot (http://github.com/ask/carrot/)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To serialize a python object to a JSON string, call the `serialize` function:
|
||||
|
||||
>>> import anyjson
|
||||
>>> anyjson.serialize(["test", 1, {"foo": 3.141592}, "bar"])
|
||||
'["test", 1, {"foo": 3.141592}, "bar"]'
|
||||
|
||||
Conversion the other way is done with the `deserialize` call.
|
||||
|
||||
>>> anyjson.deserialize("""["test", 1, {"foo": 3.141592}, "bar"]""")
|
||||
['test', 1, {'foo': 3.1415920000000002}, 'bar']
|
||||
|
||||
Regardless of the JSON implementation used, the exceptions will be the same.
|
||||
This means that trying to serialize something not compatible with JSON
|
||||
raises a TypeError:
|
||||
|
||||
>>> anyjson.serialize([object()])
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
TypeError: object is not JSON encodable
|
||||
|
||||
And deserializing a JSON string with invalid JSON raises a ValueError:
|
||||
|
||||
>>> anyjson.deserialize("""['missing square brace!""")
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
ValueError: cannot parse JSON description
|
||||
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
The module is maintaned by Rune F. Halvorsen <runefh@gmail.com>.
|
||||
The project resides at http://bitbucket.org/runeh/anyjson . Bugs and feature
|
||||
requests can be submitted there. Patches are also very welcome.
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
See CHANGELOG file
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
see the LICENSE file
|
|
@ -0,0 +1,85 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: anyjson
|
||||
Version: 0.3.3
|
||||
Summary: Wraps the best available JSON implementation available in a common interface
|
||||
Home-page: http://bitbucket.org/runeh/anyjson/
|
||||
Author: Rune Halvorsen
|
||||
Author-email: runefh@gmail.com
|
||||
License: BSD
|
||||
Description: ##############################
|
||||
anyjson - JSON library wrapper
|
||||
##############################
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Anyjson loads whichever is the fastest JSON module installed and provides
|
||||
a uniform API regardless of which JSON implementation is used.
|
||||
|
||||
Originally part of carrot (http://github.com/ask/carrot/)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To serialize a python object to a JSON string, call the `serialize` function:
|
||||
|
||||
>>> import anyjson
|
||||
>>> anyjson.serialize(["test", 1, {"foo": 3.141592}, "bar"])
|
||||
'["test", 1, {"foo": 3.141592}, "bar"]'
|
||||
|
||||
Conversion the other way is done with the `deserialize` call.
|
||||
|
||||
>>> anyjson.deserialize("""["test", 1, {"foo": 3.141592}, "bar"]""")
|
||||
['test', 1, {'foo': 3.1415920000000002}, 'bar']
|
||||
|
||||
Regardless of the JSON implementation used, the exceptions will be the same.
|
||||
This means that trying to serialize something not compatible with JSON
|
||||
raises a TypeError:
|
||||
|
||||
>>> anyjson.serialize([object()])
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
TypeError: object is not JSON encodable
|
||||
|
||||
And deserializing a JSON string with invalid JSON raises a ValueError:
|
||||
|
||||
>>> anyjson.deserialize("""['missing square brace!""")
|
||||
Traceback (most recent call last):
|
||||
<snipped traceback>
|
||||
ValueError: cannot parse JSON description
|
||||
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
The module is maintaned by Rune F. Halvorsen <runefh@gmail.com>.
|
||||
The project resides at http://bitbucket.org/runeh/anyjson . Bugs and feature
|
||||
requests can be submitted there. Patches are also very welcome.
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
See CHANGELOG file
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
see the LICENSE file
|
||||
|
||||
Keywords: json
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.4
|
||||
Classifier: Programming Language :: Python :: 2.5
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.1
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Programming Language :: Python :: Implementation :: Jython
|
|
@ -0,0 +1,14 @@
|
|||
CHANGELOG
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README
|
||||
setup.py
|
||||
anyjson/__init__.py
|
||||
anyjson.egg-info/PKG-INFO
|
||||
anyjson.egg-info/SOURCES.txt
|
||||
anyjson.egg-info/dependency_links.txt
|
||||
anyjson.egg-info/not-zip-safe
|
||||
anyjson.egg-info/top_level.txt
|
||||
tests/benchmark.py
|
||||
tests/test_implementations.py
|
||||
tests/test_implementations.pyc
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
anyjson
|
|
@ -0,0 +1,142 @@
|
|||
"""Wraps the best available JSON implementation available in a common
|
||||
interface"""
|
||||
|
||||
import sys
|
||||
|
||||
VERSION = (0, 3, 3)
|
||||
__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
|
||||
__author__ = "Rune Halvorsen"
|
||||
__contact__ = "runefh@gmail.com"
|
||||
__homepage__ = "http://bitbucket.org/runeh/anyjson/"
|
||||
__docformat__ = "restructuredtext"
|
||||
|
||||
# -eof meta-
|
||||
|
||||
#: The json implementation object. This is probably not useful to you,
|
||||
#: except to get the name of the implementation in use. The name is
|
||||
#: available through ``implementation.name``.
|
||||
implementation = None
|
||||
|
||||
# json.loads does not support buffer() objects,
|
||||
# so we load() and StringIO instead, and it won't copy.
|
||||
if sys.version_info[0] == 3:
|
||||
from io import StringIO
|
||||
else:
|
||||
try:
|
||||
from cStringIO import StringIO # noqa
|
||||
except ImportError:
|
||||
from StringIO import StringIO # noqa
|
||||
|
||||
#: List of known json modules, and the names of their loads/dumps
|
||||
#: methods, as well as the exceptions they throw. Exception can be either
|
||||
#: an exception class or a string.
|
||||
_modules = [("yajl", "dumps", TypeError, "loads", ValueError, "load"),
|
||||
("jsonlib2", "write", "WriteError", "read", "ReadError", None),
|
||||
("jsonlib", "write", "WriteError", "read", "ReadError", None),
|
||||
("simplejson", "dumps", TypeError, "loads", ValueError, "load"),
|
||||
("json", "dumps", TypeError, "loads", ValueError, "load"),
|
||||
("django.utils.simplejson", "dumps", TypeError, "loads", ValueError, "load"),
|
||||
("cjson", "encode", "EncodeError", "decode", "DecodeError", None)
|
||||
]
|
||||
|
||||
_fields = ("modname", "encoder", "encerror",
|
||||
"decoder", "decerror", "filedecoder")
|
||||
|
||||
|
||||
class _JsonImplementation(object):
|
||||
"""Incapsulates a JSON implementation"""
|
||||
|
||||
def __init__(self, modspec):
|
||||
modinfo = dict(zip(_fields, modspec))
|
||||
|
||||
if modinfo["modname"] == "cjson":
|
||||
import warnings
|
||||
warnings.warn("cjson is deprecated! See http://pypi.python.org/pypi/python-cjson/1.0.5", DeprecationWarning)
|
||||
|
||||
# No try block. We want importerror to end up at caller
|
||||
module = self._attempt_load(modinfo["modname"])
|
||||
|
||||
self.implementation = modinfo["modname"]
|
||||
self._encode = getattr(module, modinfo["encoder"])
|
||||
self._decode = getattr(module, modinfo["decoder"])
|
||||
fdec = modinfo["filedecoder"]
|
||||
self._filedecode = fdec and getattr(module, fdec)
|
||||
self._encode_error = modinfo["encerror"]
|
||||
self._decode_error = modinfo["decerror"]
|
||||
|
||||
if isinstance(modinfo["encerror"], basestring):
|
||||
self._encode_error = getattr(module, modinfo["encerror"])
|
||||
if isinstance(modinfo["decerror"], basestring):
|
||||
self._decode_error = getattr(module, modinfo["decerror"])
|
||||
|
||||
self.name = modinfo["modname"]
|
||||
|
||||
def __repr__(self):
|
||||
return "<_JsonImplementation instance using %s>" % self.name
|
||||
|
||||
def _attempt_load(self, modname):
|
||||
"""Attempt to load module name modname, returning it on success,
|
||||
throwing ImportError if module couldn't be imported"""
|
||||
__import__(modname)
|
||||
return sys.modules[modname]
|
||||
|
||||
def dumps(self, data):
|
||||
"""Serialize the datastructure to json. Returns a string. Raises
|
||||
TypeError if the object could not be serialized."""
|
||||
try:
|
||||
return self._encode(data)
|
||||
except self._encode_error, exc:
|
||||
raise TypeError, TypeError(*exc.args), sys.exc_info()[2]
|
||||
serialize = dumps
|
||||
|
||||
def loads(self, s):
|
||||
"""deserialize the string to python data types. Raises
|
||||
ValueError if the string could not be parsed."""
|
||||
# uses StringIO to support buffer objects.
|
||||
try:
|
||||
if self._filedecode and not isinstance(s, basestring):
|
||||
return self._filedecode(StringIO(s))
|
||||
return self._decode(s)
|
||||
except self._decode_error, exc:
|
||||
raise ValueError, ValueError(*exc.args), sys.exc_info()[2]
|
||||
deserialize = loads
|
||||
|
||||
|
||||
def force_implementation(modname):
|
||||
"""Forces anyjson to use a specific json module if it's available"""
|
||||
global implementation
|
||||
for name, spec in [(e[0], e) for e in _modules]:
|
||||
if name == modname:
|
||||
implementation = _JsonImplementation(spec)
|
||||
return
|
||||
raise ImportError("No module named: %s" % modname)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# If run as a script, we do nothing but print an error message.
|
||||
# We do NOT try to load a compatible module because that may throw an
|
||||
# exception, which renders the package uninstallable with easy_install
|
||||
# (It trys to execfile the script when installing, to make sure it works)
|
||||
print "Running anyjson as a stand alone script is not supported"
|
||||
sys.exit(1)
|
||||
else:
|
||||
for modspec in _modules:
|
||||
try:
|
||||
implementation = _JsonImplementation(modspec)
|
||||
break
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
raise ImportError("No supported JSON module found")
|
||||
|
||||
|
||||
def loads(value):
|
||||
"""Serialize the object to JSON."""
|
||||
return implementation.loads(value)
|
||||
deserialize = loads # compat
|
||||
|
||||
|
||||
def dumps(value):
|
||||
"""Deserialize JSON-encoded object to a Python object."""
|
||||
return implementation.dumps(value)
|
||||
serialize = dumps
|
|
@ -0,0 +1,5 @@
|
|||
[egg_info]
|
||||
tag_build =
|
||||
tag_date = 0
|
||||
tag_svn_revision = 0
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
extra = {}
|
||||
if sys.version_info >= (3, 0):
|
||||
extra.update(use_2to3=True)
|
||||
|
||||
try:
|
||||
from setuptools import setup, find_packages
|
||||
except ImportError:
|
||||
from distutils.core import setup, find_packages
|
||||
|
||||
# -*- Distribution Meta -*-
|
||||
import re
|
||||
re_meta = re.compile(r'__(\w+?)__\s*=\s*(.*)')
|
||||
re_vers = re.compile(r'VERSION\s*=\s*\((.*?)\)')
|
||||
re_doc = re.compile(r'^"""(.+?)"""', re.M|re.S)
|
||||
rq = lambda s: s.strip("\"'")
|
||||
|
||||
def add_default(m):
|
||||
attr_name, attr_value = m.groups()
|
||||
return ((attr_name, rq(attr_value)), )
|
||||
|
||||
|
||||
def add_version(m):
|
||||
v = list(map(rq, m.groups()[0].split(", ")))
|
||||
return (("VERSION", ".".join(v[0:3]) + "".join(v[3:])), )
|
||||
|
||||
|
||||
def add_doc(m):
|
||||
return (("doc", m.groups()[0].replace("\n", " ")), )
|
||||
|
||||
pats = {re_meta: add_default,
|
||||
re_vers: add_version}
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
meta_fh = open(os.path.join(here, "anyjson/__init__.py"))
|
||||
try:
|
||||
meta = {}
|
||||
acc = []
|
||||
for line in meta_fh:
|
||||
if line.strip() == '# -eof meta-':
|
||||
break
|
||||
acc.append(line)
|
||||
for pattern, handler in pats.items():
|
||||
m = pattern.match(line.strip())
|
||||
if m:
|
||||
meta.update(handler(m))
|
||||
m = re_doc.match("".join(acc).strip())
|
||||
if m:
|
||||
meta.update(add_doc(m))
|
||||
finally:
|
||||
meta_fh.close()
|
||||
|
||||
|
||||
supported = ["yajl", "jsonlib2", "jsonlib", "simplejson",
|
||||
"json", "django.utils.simplejson", "cjson"]
|
||||
install_requires = []
|
||||
for module in supported:
|
||||
try:
|
||||
__import__(module)
|
||||
break
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
install_requires.append("simplejson")
|
||||
|
||||
|
||||
setup(name='anyjson',
|
||||
version=meta["VERSION"],
|
||||
description=meta["doc"],
|
||||
author=meta["author"],
|
||||
author_email=meta["contact"],
|
||||
url=meta["homepage"],
|
||||
license='BSD',
|
||||
long_description=open("README").read(),
|
||||
install_requires=install_requires,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Intended Audience :: Developers',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.4',
|
||||
'Programming Language :: Python :: 2.5',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.1',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Programming Language :: Python :: Implementation :: Jython',
|
||||
],
|
||||
keywords='json',
|
||||
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
|
||||
zip_safe=False,
|
||||
platforms=["any"],
|
||||
test_suite = 'nose.collector',
|
||||
**extra
|
||||
)
|
|
@ -0,0 +1,143 @@
|
|||
"""
|
||||
Simple benchmark script to do some basic speed tests of json libs
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
|
||||
_small = """
|
||||
{
|
||||
"name": "benchmark test",
|
||||
"foo": "bar",
|
||||
"age": 32,
|
||||
"weight": 100,
|
||||
"Height": 154.12,
|
||||
"married": false,
|
||||
"siblings": [],
|
||||
"bar": null
|
||||
}
|
||||
"""
|
||||
|
||||
_deep = """
|
||||
{
|
||||
"foo": "bar",
|
||||
"nest": {
|
||||
"foo": %(_small)s,
|
||||
"nest": {
|
||||
"foo": %(_small)s,
|
||||
"nest": {
|
||||
"foo": %(_small)s,
|
||||
"nest": {
|
||||
"foo": %(_small)s,
|
||||
"nest": {
|
||||
"foo": %(_small)s,
|
||||
"nest": %(_small)s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""" % locals()
|
||||
|
||||
_big = """
|
||||
{
|
||||
"biglist": [%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_deep)s, %(_small)s, %(_deep)s, %(_small)s, %(_deep)s,
|
||||
%(_small)s, %(_small)s, %(_small)s, %(_small)s, %(_small)s],
|
||||
"entry1": %(_small)s,
|
||||
"entry2": %(_deep)s,
|
||||
"entry3": %(_small)s,
|
||||
"entry4": %(_deep)s,
|
||||
"entry5": %(_small)s,
|
||||
"entry6": %(_deep)s
|
||||
}
|
||||
""" % locals()
|
||||
|
||||
# The following two will contain real world json from twitter and reddit if
|
||||
# script is run with the --download flag
|
||||
_reddit = "[]"
|
||||
_twitter = "[]"
|
||||
|
||||
def load_external_json():
|
||||
global _reddit, _twitter
|
||||
_reddit = urllib.urlopen("http://reddit.com/.json").read()
|
||||
_twitter = urllib.urlopen("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=twitterapi&count=200").read()
|
||||
|
||||
|
||||
def do_benchmark(impspec, json, runs=10):
|
||||
modulename, parsename, emitname = impspec
|
||||
|
||||
try:
|
||||
__import__(modulename)
|
||||
mod = sys.modules[modulename]
|
||||
reads = getattr(mod, parsename)
|
||||
dumps = getattr(mod, emitname)
|
||||
except:
|
||||
return None
|
||||
|
||||
start = time.time()
|
||||
for n in xrange(runs):
|
||||
data = reads(json)
|
||||
|
||||
readtime = time.time() - start
|
||||
|
||||
start = time.time()
|
||||
for n in xrange(runs):
|
||||
devnull = dumps(data)
|
||||
|
||||
return readtime, time.time() - start # tuple (readtime, writetime)
|
||||
|
||||
|
||||
modules = [("json", "loads", "dumps"),
|
||||
("simplejson", "loads", "dumps"),
|
||||
("yajl", "loads", "dumps"),
|
||||
("cjson", "decode", "encode"),
|
||||
("django.utils.simplejson", "loads", "dumps"),
|
||||
("jsonpickle", "decode", "encode"),
|
||||
("jsonlib", "read", "write"),
|
||||
("jsonlib2", "read", "write"),
|
||||
#("demjson", "decode"), terribly slow. wont include it
|
||||
]
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "--download":
|
||||
load_external_json()
|
||||
|
||||
res = []
|
||||
runs = 100
|
||||
for e in modules:
|
||||
res.append((e[0], do_benchmark(e, _small, runs),
|
||||
do_benchmark(e, _deep , runs),
|
||||
do_benchmark(e, _big, runs),
|
||||
do_benchmark(e, _reddit, runs),
|
||||
do_benchmark(e, _twitter, runs),
|
||||
))
|
||||
|
||||
no_res = set([e for e in res if e[1] is None])
|
||||
res = list(set(res) - no_res)
|
||||
res = [(e[0], sum(map(lambda x:x[0], e[1:])), sum(map(lambda x:x[1], e[1:]))) for e in res]
|
||||
|
||||
res.sort(lambda a,b: cmp((a[1]+a[2]), b[1]+b[2]))
|
||||
|
||||
print "Total Read Write Implementation"
|
||||
print "-----------------------------------"
|
||||
for e in res:
|
||||
print "%.3f %.3f %.3f %s" % (e[1]+e[2], e[1], e[2], e[0])
|
||||
for e in no_res:
|
||||
print "Not installed:", e[0]
|
|
@ -0,0 +1,57 @@
|
|||
from nose.tools import assert_raises
|
||||
import anyjson
|
||||
|
||||
modnames = [e[0] for e in anyjson._modules]
|
||||
|
||||
def test_default_serialization():
|
||||
assert anyjson.dumps([1,2,3]).replace(" ", "") == "[1,2,3]"
|
||||
assert anyjson.serialize([1,2,3]).replace(" ", "") == "[1,2,3]"
|
||||
|
||||
|
||||
def test_default_deserialization():
|
||||
assert anyjson.loads("[1,2,3]") == [1,2,3]
|
||||
assert anyjson.deserialize("[1,2,3]") == [1,2,3]
|
||||
|
||||
|
||||
def test_forced_serialization():
|
||||
for name in modnames:
|
||||
try:
|
||||
anyjson.force_implementation(name)
|
||||
except ImportError:
|
||||
continue # module can't be tested, try next
|
||||
|
||||
assert anyjson.dumps([1,2,3]).replace(" ", "") == "[1,2,3]"
|
||||
assert anyjson.serialize([1,2,3]).replace(" ", "") == "[1,2,3]"
|
||||
|
||||
|
||||
def test_forced_deserialization():
|
||||
for name in modnames:
|
||||
try:
|
||||
anyjson.force_implementation(name)
|
||||
except ImportError:
|
||||
continue # module can't be tested, try next
|
||||
|
||||
assert anyjson.loads("[1,2,3]") == [1,2,3]
|
||||
assert anyjson.deserialize("[1,2,3]") == [1,2,3]
|
||||
|
||||
|
||||
def test_exceptions():
|
||||
for name in modnames:
|
||||
try:
|
||||
anyjson.force_implementation(name)
|
||||
except ImportError:
|
||||
continue # module can't be tested, try next
|
||||
|
||||
assert_raises(TypeError, anyjson.dumps, [object()])
|
||||
assert_raises(TypeError, anyjson.serialize, [object()])
|
||||
assert_raises(ValueError, anyjson.loads, "[")
|
||||
assert_raises(ValueError, anyjson.deserialize, "[")
|
||||
|
||||
|
||||
def test_json_loads_unicode():
|
||||
try:
|
||||
anyjson.force_implementation("json")
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
assert "foo" in anyjson.loads(u'{"foo": "bar"}')
|
Loading…
Reference in New Issue