Skip to content
Browse files

Merge pull request #48 from Komnomnomnom/pandas-changes

Fixes and enhancements from the pandas project
  • Loading branch information...
2 parents fd13812 + fd3e969 commit 640f6dae2eed597ee21abde1cbb27e9bec7dd789 @jskorpan jskorpan committed
Showing with 3,895 additions and 3,752 deletions.
  1. +295 −298 lib/ultrajson.h
  2. +835 −827 lib/ultrajsondec.c
  3. +890 −857 lib/ultrajsonenc.c
  4. +182 −182 python/JSONtoObj.c
  5. +842 −827 python/objToJSON.c
  6. +15 −0 python/py_defines.h
  7. +73 −41 python/ujson.c
  8. +29 −17 setup.py
  9. +734 −703 tests/tests.py
View
593 lib/ultrajson.h
@@ -1,298 +1,295 @@
-/*
-Copyright (c) 2011, Jonas Tarnstrom and ESN Social Software AB
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. 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.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by ESN Social Software AB (www.esn.me).
-4. Neither the name of the ESN Social Software AB 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 ESN SOCIAL SOFTWARE AB ''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 ESN SOCIAL SOFTWARE AB 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.
-
-Portions of code from:
-MODP_ASCII - Ascii transformations (upper/lower, etc)
-http://code.google.com/p/stringencoders/
-Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
-
-*/
-
-/*
-Ultra fast JSON encoder and decoder
-Developed by Jonas Tarnstrom (jonas@esn.me).
-
-Encoder notes:
-------------------
-
-:: Cyclic references ::
-Cyclic referenced objects are not detected.
-Set JSONObjectEncoder.recursionMax to suitable value or make sure input object
-tree doesn't have cyclic references.
-
-*/
-
-#ifndef __ULTRAJSON_H__
-#define __ULTRAJSON_H__
-
-#include <stdio.h>
-#include <wchar.h>
-
-//#define JSON_DECODE_NUMERIC_AS_DOUBLE
-
-// Don't output any extra whitespaces when encoding
-#define JSON_NO_EXTRA_WHITESPACE
-
-// Max decimals to encode double floating point numbers with
-#ifndef JSON_DOUBLE_MAX_DECIMALS
-#define JSON_DOUBLE_MAX_DECIMALS 9
-#endif
-
-// Max recursion depth, default for encoder
-#ifndef JSON_MAX_RECURSION_DEPTH
-#define JSON_MAX_RECURSION_DEPTH 1024
-#endif
-
-/*
-Dictates and limits how much stack space for buffers UltraJSON will use before resorting to provided heap functions */
-#ifndef JSON_MAX_STACK_BUFFER_SIZE
-#define JSON_MAX_STACK_BUFFER_SIZE 131072
-#endif
-
-#ifdef _WIN32
-
-typedef __int64 JSINT64;
-typedef unsigned __int64 JSUINT64;
-
-typedef unsigned __int32 uint32_t;
-typedef __int32 JSINT32;
-typedef uint32_t JSUINT32;
-typedef unsigned __int8 JSUINT8;
-typedef unsigned __int16 JSUTF16;
-typedef unsigned __int32 JSUTF32;
-typedef __int64 JSLONG;
-
-#define EXPORTFUNCTION __declspec(dllexport)
-
-#define FASTCALL_MSVC __fastcall
-#define FASTCALL_ATTR
-#define INLINE_PREFIX __inline
-
-#else
-
-#include <sys/types.h>
-typedef int64_t JSINT64;
-typedef u_int64_t JSUINT64;
-
-typedef int32_t JSINT32;
-typedef u_int32_t JSUINT32;
-
-#define FASTCALL_MSVC
-#define FASTCALL_ATTR __attribute__((fastcall))
-#define INLINE_PREFIX inline
-
-typedef u_int32_t uint32_t;
-
-typedef u_int8_t JSUINT8;
-typedef u_int16_t JSUTF16;
-typedef u_int32_t JSUTF32;
-
-typedef int64_t JSLONG;
-
-#define EXPORTFUNCTION
-#endif
-
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define __LITTLE_ENDIAN__
-#else
-
-#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define __BIG_ENDIAN__
-#endif
-
-#endif
-
-#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
-#error "Endianess not supported"
-#endif
-
-enum JSTYPES
-{
- JT_NULL, // NULL
- JT_TRUE, //boolean true
- JT_FALSE, //boolean false
- JT_INT, //(JSINT32 (signed 32-bit))
- JT_LONG, //(JSINT64 (signed 64-bit))
- JT_DOUBLE, //(double)
- JT_UTF8, //(char 8-bit)
- JT_ARRAY, // Array structure
- JT_OBJECT, // Key/Value structure
- JT_INVALID, // Internal, do not return nor expect
-};
-
-typedef void * JSOBJ;
-typedef void * JSITER;
-
-typedef struct __JSONTypeContext
-{
- int type;
- void *prv[32];
-} JSONTypeContext;
-
-/*
-Function pointer declarations, suitable for implementing UltraJSON */
-typedef void (*JSPFN_ITERBEGIN)(JSOBJ obj, JSONTypeContext *tc);
-typedef int (*JSPFN_ITERNEXT)(JSOBJ obj, JSONTypeContext *tc);
-typedef void (*JSPFN_ITEREND)(JSOBJ obj, JSONTypeContext *tc);
-typedef JSOBJ (*JSPFN_ITERGETVALUE)(JSOBJ obj, JSONTypeContext *tc);
-typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, size_t *outLen);
-typedef void *(*JSPFN_MALLOC)(size_t size);
-typedef void (*JSPFN_FREE)(void *pptr);
-typedef void *(*JSPFN_REALLOC)(void *base, size_t size);
-
-typedef struct __JSONObjectEncoder
-{
- void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc);
- void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc);
- const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen);
- JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
- JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc);
- double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc);
-
- /*
- Begin iteration of an iteratable object (JS_ARRAY or JS_OBJECT)
- Implementor should setup iteration state in ti->prv
- */
- JSPFN_ITERBEGIN iterBegin;
-
- /*
- Retrieve next object in an iteration. Should return 0 to indicate iteration has reached end or 1 if there are more items.
- Implementor is responsible for keeping state of the iteration. Use ti->prv fields for this
- */
- JSPFN_ITERNEXT iterNext;
-
- /*
- Ends the iteration of an iteratable object.
- Any iteration state stored in ti->prv can be freed here
- */
- JSPFN_ITEREND iterEnd;
-
- /*
- Returns a reference to the value object of an iterator
- The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
- */
- JSPFN_ITERGETVALUE iterGetValue;
-
- /*
- Return name of iterator.
- The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
- */
- JSPFN_ITERGETNAME iterGetName;
-
- /*
- Release a value as indicated by setting ti->release = 1 in the previous getValue call.
- The ti->prv array should contain the necessary context to release the value
- */
- void (*releaseObject)(JSOBJ obj);
-
- /* Library functions
- Set to NULL to use STDLIB malloc,realloc,free */
- JSPFN_MALLOC malloc;
- JSPFN_REALLOC realloc;
- JSPFN_FREE free;
-
- /*
- Configuration for max recursion, set to 0 to use default (see JSON_MAX_RECURSION_DEPTH)*/
- int recursionMax;
-
- /*
- Configuration for max decimals of double floating poiunt numbers to encode (0-9) */
- int doublePrecision;
-
- /*
- If true output will be ASCII with all characters above 127 encoded as \uXXXX. If false output will be UTF-8 or what ever charset strings are brought as */
- int forceASCII;
-
-
- /*
- Set to an error message if error occured */
- const char *errorMsg;
- JSOBJ errorObj;
-
- /* Buffer stuff */
- char *start;
- char *offset;
- char *end;
- int heap;
- int level;
-
-} JSONObjectEncoder;
-
-
-/*
-Encode an object structure into JSON.
-
-Arguments:
-obj - An anonymous type representing the object
-enc - Function definitions for querying JSOBJ type
-buffer - Preallocated buffer to store result in. If NULL function allocates own buffer
-cbBuffer - Length of buffer (ignored if buffer is NULL)
-
-Returns:
-Encoded JSON object as a null terminated char string.
-
-NOTE:
-If the supplied buffer wasn't enough to hold the result the function will allocate a new buffer.
-Life cycle of the provided buffer must still be handled by caller.
-
-If the return value doesn't equal the specified buffer caller must release the memory using
-JSONObjectEncoder.free or free() as specified when calling this function.
-*/
-EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *buffer, size_t cbBuffer);
-
-
-
-typedef struct __JSONObjectDecoder
-{
- JSOBJ (*newString)(wchar_t *start, wchar_t *end);
- void (*objectAddKey)(JSOBJ obj, JSOBJ name, JSOBJ value);
- void (*arrayAddItem)(JSOBJ obj, JSOBJ value);
- JSOBJ (*newTrue)(void);
- JSOBJ (*newFalse)(void);
- JSOBJ (*newNull)(void);
- JSOBJ (*newObject)(void);
- JSOBJ (*newArray)(void);
- JSOBJ (*newInt)(JSINT32 value);
- JSOBJ (*newLong)(JSINT64 value);
- JSOBJ (*newDouble)(double value);
- void (*releaseObject)(JSOBJ obj);
- JSPFN_MALLOC malloc;
- JSPFN_FREE free;
- JSPFN_REALLOC realloc;
-
- char *errorStr;
- char *errorOffset;
-
-
-
-} JSONObjectDecoder;
-
-EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer);
-
-#endif
+/*
+Copyright (c) 2011, Jonas Tarnstrom and ESN Social Software AB
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. 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.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by ESN Social Software AB (www.esn.me).
+4. Neither the name of the ESN Social Software AB 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 ESN SOCIAL SOFTWARE AB ''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 ESN SOCIAL SOFTWARE AB 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.
+
+Portions of code from:
+MODP_ASCII - Ascii transformations (upper/lower, etc)
+http://code.google.com/p/stringencoders/
+Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
+
+*/
+
+/*
+Ultra fast JSON encoder and decoder
+Developed by Jonas Tarnstrom (jonas@esn.me).
+
+Encoder notes:
+------------------
+
+:: Cyclic references ::
+Cyclic referenced objects are not detected.
+Set JSONObjectEncoder.recursionMax to suitable value or make sure input object
+tree doesn't have cyclic references.
+
+*/
+
+#ifndef __ULTRAJSON_H__
+#define __ULTRAJSON_H__
+
+#include <stdio.h>
+#include <wchar.h>
+
+//#define JSON_DECODE_NUMERIC_AS_DOUBLE
+
+// Don't output any extra whitespaces when encoding
+#define JSON_NO_EXTRA_WHITESPACE
+
+// Max decimals to encode double floating point numbers with
+#ifndef JSON_DOUBLE_MAX_DECIMALS
+#define JSON_DOUBLE_MAX_DECIMALS 15
+#endif
+
+// Max recursion depth, default for encoder
+#ifndef JSON_MAX_RECURSION_DEPTH
+#define JSON_MAX_RECURSION_DEPTH 1024
+#endif
+
+/*
+Dictates and limits how much stack space for buffers UltraJSON will use before resorting to provided heap functions */
+#ifndef JSON_MAX_STACK_BUFFER_SIZE
+#define JSON_MAX_STACK_BUFFER_SIZE 131072
+#endif
+
+#ifdef _WIN32
+
+typedef __int64 JSINT64;
+typedef unsigned __int64 JSUINT64;
+
+typedef __int32 JSINT32;
+typedef unsigned __int32 JSUINT32;
+typedef unsigned __int8 JSUINT8;
+typedef unsigned __int16 JSUTF16;
+typedef unsigned __int32 JSUTF32;
+typedef __int64 JSLONG;
+
+#define EXPORTFUNCTION __declspec(dllexport)
+
+#define FASTCALL_MSVC __fastcall
+#define FASTCALL_ATTR
+#define INLINE_PREFIX __inline
+
+#else
+
+#include <sys/types.h>
+typedef int64_t JSINT64;
+typedef u_int64_t JSUINT64;
+
+typedef int32_t JSINT32;
+typedef u_int32_t JSUINT32;
+
+#define FASTCALL_MSVC
+#define FASTCALL_ATTR __attribute__((fastcall))
+#define INLINE_PREFIX inline
+
+typedef u_int8_t JSUINT8;
+typedef u_int16_t JSUTF16;
+typedef u_int32_t JSUTF32;
+
+typedef int64_t JSLONG;
+
+#define EXPORTFUNCTION
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define __LITTLE_ENDIAN__
+#else
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define __BIG_ENDIAN__
+#endif
+
+#endif
+
+#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+#error "Endianess not supported"
+#endif
+
+enum JSTYPES
+{
+ JT_NULL, // NULL
+ JT_TRUE, //boolean true
+ JT_FALSE, //boolean false
+ JT_INT, //(JSINT32 (signed 32-bit))
+ JT_LONG, //(JSINT64 (signed 64-bit))
+ JT_DOUBLE, //(double)
+ JT_UTF8, //(char 8-bit)
+ JT_ARRAY, // Array structure
+ JT_OBJECT, // Key/Value structure
+ JT_INVALID, // Internal, do not return nor expect
+};
+
+typedef void * JSOBJ;
+typedef void * JSITER;
+
+typedef struct __JSONTypeContext
+{
+ int type;
+ void *prv;
+} JSONTypeContext;
+
+/*
+Function pointer declarations, suitable for implementing UltraJSON */
+typedef void (*JSPFN_ITERBEGIN)(JSOBJ obj, JSONTypeContext *tc);
+typedef int (*JSPFN_ITERNEXT)(JSOBJ obj, JSONTypeContext *tc);
+typedef void (*JSPFN_ITEREND)(JSOBJ obj, JSONTypeContext *tc);
+typedef JSOBJ (*JSPFN_ITERGETVALUE)(JSOBJ obj, JSONTypeContext *tc);
+typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, size_t *outLen);
+typedef void *(*JSPFN_MALLOC)(size_t size);
+typedef void (*JSPFN_FREE)(void *pptr);
+typedef void *(*JSPFN_REALLOC)(void *base, size_t size);
+
+typedef struct __JSONObjectEncoder
+{
+ void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc);
+ void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc);
+ const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen);
+ JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
+ JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc);
+ double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc);
+
+ /*
+ Begin iteration of an iteratable object (JS_ARRAY or JS_OBJECT)
+ Implementor should setup iteration state in ti->prv
+ */
+ JSPFN_ITERBEGIN iterBegin;
+
+ /*
+ Retrieve next object in an iteration. Should return 0 to indicate iteration has reached end or 1 if there are more items.
+ Implementor is responsible for keeping state of the iteration. Use ti->prv fields for this
+ */
+ JSPFN_ITERNEXT iterNext;
+
+ /*
+ Ends the iteration of an iteratable object.
+ Any iteration state stored in ti->prv can be freed here
+ */
+ JSPFN_ITEREND iterEnd;
+
+ /*
+ Returns a reference to the value object of an iterator
+ The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
+ */
+ JSPFN_ITERGETVALUE iterGetValue;
+
+ /*
+ Return name of iterator.
+ The is responsible for the life-cycle of the returned string. Use iterNext/iterEnd and ti->prv to keep track of current object
+ */
+ JSPFN_ITERGETNAME iterGetName;
+
+ /*
+ Release a value as indicated by setting ti->release = 1 in the previous getValue call.
+ The ti->prv array should contain the necessary context to release the value
+ */
+ void (*releaseObject)(JSOBJ obj);
+
+ /* Library functions
+ Set to NULL to use STDLIB malloc,realloc,free */
+ JSPFN_MALLOC malloc;
+ JSPFN_REALLOC realloc;
+ JSPFN_FREE free;
+
+ /*
+ Configuration for max recursion, set to 0 to use default (see JSON_MAX_RECURSION_DEPTH)*/
+ int recursionMax;
+
+ /*
+ Configuration for max decimals of double floating poiunt numbers to encode (0-9) */
+ int doublePrecision;
+
+ /*
+ If true output will be ASCII with all characters above 127 encoded as \uXXXX. If false output will be UTF-8 or what ever charset strings are brought as */
+ int forceASCII;
+
+
+ /*
+ Set to an error message if error occured */
+ const char *errorMsg;
+ JSOBJ errorObj;
+
+ /* Buffer stuff */
+ char *start;
+ char *offset;
+ char *end;
+ int heap;
+ int level;
+
+} JSONObjectEncoder;
+
+
+/*
+Encode an object structure into JSON.
+
+Arguments:
+obj - An anonymous type representing the object
+enc - Function definitions for querying JSOBJ type
+buffer - Preallocated buffer to store result in. If NULL function allocates own buffer
+cbBuffer - Length of buffer (ignored if buffer is NULL)
+
+Returns:
+Encoded JSON object as a null terminated char string.
+
+NOTE:
+If the supplied buffer wasn't enough to hold the result the function will allocate a new buffer.
+Life cycle of the provided buffer must still be handled by caller.
+
+If the return value doesn't equal the specified buffer caller must release the memory using
+JSONObjectEncoder.free or free() as specified when calling this function.
+*/
+EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *buffer, size_t cbBuffer);
+
+
+
+typedef struct __JSONObjectDecoder
+{
+ JSOBJ (*newString)(wchar_t *start, wchar_t *end);
+ void (*objectAddKey)(JSOBJ obj, JSOBJ name, JSOBJ value);
+ void (*arrayAddItem)(JSOBJ obj, JSOBJ value);
+ JSOBJ (*newTrue)(void);
+ JSOBJ (*newFalse)(void);
+ JSOBJ (*newNull)(void);
+ JSOBJ (*newObject)(void);
+ JSOBJ (*newArray)(void);
+ JSOBJ (*newInt)(JSINT32 value);
+ JSOBJ (*newLong)(JSINT64 value);
+ JSOBJ (*newDouble)(double value);
+ void (*releaseObject)(JSOBJ obj);
+ JSPFN_MALLOC malloc;
+ JSPFN_FREE free;
+ JSPFN_REALLOC realloc;
+
+ char *errorStr;
+ char *errorOffset;
+
+
+
+} JSONObjectDecoder;
+
+EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer);
+
+#endif
View
1,662 lib/ultrajsondec.c
835 additions, 827 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
1,747 lib/ultrajsonenc.c
890 additions, 857 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
364 python/JSONtoObj.c
@@ -1,182 +1,182 @@
-#include <Python.h>
-#include <ultrajson.h>
-
-
-
-
-void Object_objectAddKey(JSOBJ obj, JSOBJ name, JSOBJ value)
-{
- PyDict_SetItem (obj, name, value);
- Py_DECREF( (PyObject *) name);
- Py_DECREF( (PyObject *) value);
- return;
-}
-
-void Object_arrayAddItem(JSOBJ obj, JSOBJ value)
-{
- PyList_Append(obj, value);
- Py_DECREF( (PyObject *) value);
- return;
-}
-
-JSOBJ Object_newString(wchar_t *start, wchar_t *end)
-{
- return PyUnicode_FromWideChar (start, (end - start));
-}
-
-JSOBJ Object_newTrue(void)
-{
- Py_RETURN_TRUE;
-}
-
-JSOBJ Object_newFalse(void)
-{
- Py_RETURN_FALSE;
-}
-
-JSOBJ Object_newNull(void)
-{
- Py_RETURN_NONE;
-}
-
-JSOBJ Object_newObject(void)
-{
- return PyDict_New();
-}
-
-JSOBJ Object_newArray(void)
-{
- return PyList_New(0);
-}
-
-JSOBJ Object_newInteger(JSINT32 value)
-{
- return PyInt_FromLong( (long) value);
-}
-
-JSOBJ Object_newLong(JSINT64 value)
-{
- return PyLong_FromLongLong (value);
-}
-
-JSOBJ Object_newDouble(double value)
-{
- return PyFloat_FromDouble(value);
-}
-
-static void Object_releaseObject(JSOBJ obj)
-{
- Py_DECREF( ((PyObject *)obj));
-}
-
-
-
-PyObject* JSONToObj(PyObject* self, PyObject *arg)
-{
- PyObject *ret;
- PyObject *sarg;
- JSONObjectDecoder decoder =
- {
- Object_newString,
- Object_objectAddKey,
- Object_arrayAddItem,
- Object_newTrue,
- Object_newFalse,
- Object_newNull,
- Object_newObject,
- Object_newArray,
- Object_newInteger,
- Object_newLong,
- Object_newDouble,
- Object_releaseObject,
- PyObject_Malloc,
- PyObject_Free,
- PyObject_Realloc
- };
-
- if (PyString_Check(arg))
- {
- sarg = arg;
- }
- else
- if (PyUnicode_Check(arg))
- {
- sarg = PyUnicode_AsUTF8String(arg);
- if (sarg == NULL)
- {
- //Exception raised above us by codec according to docs
- return NULL;
- }
- }
- else
- {
- PyErr_Format(PyExc_TypeError, "Expected String or Unicode");
- return NULL;
- }
-
- decoder.errorStr = NULL;
- decoder.errorOffset = NULL;
-
- ret = JSON_DecodeObject(&decoder, PyString_AS_STRING(sarg), PyString_GET_SIZE(sarg));
-
- if (sarg != arg)
- {
- Py_DECREF(sarg);
- }
-
- if (decoder.errorStr)
- {
- /*
- FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/
-
- PyErr_Format (PyExc_ValueError, "%s", decoder.errorStr);
-
- if (ret)
- {
- Py_DECREF( (PyObject *) ret);
- }
-
- return NULL;
- }
-
- return ret;
-}
-
-PyObject* JSONFileToObj(PyObject* self, PyObject *file)
-{
- PyObject *read;
- PyObject *string;
- PyObject *result;
-
- if (!PyObject_HasAttrString (file, "read"))
- {
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- read = PyObject_GetAttrString (file, "read");
-
- if (!PyCallable_Check (read)) {
- Py_XDECREF(read);
- PyErr_Format (PyExc_TypeError, "expected file");
- return NULL;
- }
-
- string = PyObject_CallObject (read, NULL);
- Py_XDECREF(read);
-
- if (string == NULL)
- {
- return NULL;
- }
-
- result = JSONToObj (self, string);
- Py_XDECREF(string);
-
- if (result == NULL) {
- return NULL;
- }
-
- return result;
-}
-
+#include "py_defines.h"
+#include <ultrajson.h>
+
+
+
+
+void Object_objectAddKey(JSOBJ obj, JSOBJ name, JSOBJ value)
+{
+ PyDict_SetItem (obj, name, value);
+ Py_DECREF( (PyObject *) name);
+ Py_DECREF( (PyObject *) value);
+ return;
+}
+
+void Object_arrayAddItem(JSOBJ obj, JSOBJ value)
+{
+ PyList_Append(obj, value);
+ Py_DECREF( (PyObject *) value);
+ return;
+}
+
+JSOBJ Object_newString(wchar_t *start, wchar_t *end)
+{
+ return PyUnicode_FromWideChar (start, (end - start));
+}
+
+JSOBJ Object_newTrue(void)
+{
+ Py_RETURN_TRUE;
+}
+
+JSOBJ Object_newFalse(void)
+{
+ Py_RETURN_FALSE;
+}
+
+JSOBJ Object_newNull(void)
+{
+ Py_RETURN_NONE;
+}
+
+JSOBJ Object_newObject(void)
+{
+ return PyDict_New();
+}
+
+JSOBJ Object_newArray(void)
+{
+ return PyList_New(0);
+}
+
+JSOBJ Object_newInteger(JSINT32 value)
+{
+ return PyInt_FromLong( (long) value);
+}
+
+JSOBJ Object_newLong(JSINT64 value)
+{
+ return PyLong_FromLongLong (value);
+}
+
+JSOBJ Object_newDouble(double value)
+{
+ return PyFloat_FromDouble(value);
+}
+
+static void Object_releaseObject(JSOBJ obj)
+{
+ Py_DECREF( ((PyObject *)obj));
+}
+
+
+
+PyObject* JSONToObj(PyObject* self, PyObject *arg)
+{
+ PyObject *ret;
+ PyObject *sarg;
+ JSONObjectDecoder decoder =
+ {
+ Object_newString,
+ Object_objectAddKey,
+ Object_arrayAddItem,
+ Object_newTrue,
+ Object_newFalse,
+ Object_newNull,
+ Object_newObject,
+ Object_newArray,
+ Object_newInteger,
+ Object_newLong,
+ Object_newDouble,
+ Object_releaseObject,
+ PyObject_Malloc,
+ PyObject_Free,
+ PyObject_Realloc
+ };
+
+ if (PyString_Check(arg))
+ {
+ sarg = arg;
+ }
+ else
+ if (PyUnicode_Check(arg))
+ {
+ sarg = PyUnicode_AsUTF8String(arg);
+ if (sarg == NULL)
+ {
+ //Exception raised above us by codec according to docs
+ return NULL;
+ }
+ }
+ else
+ {
+ PyErr_Format(PyExc_TypeError, "Expected String or Unicode");
+ return NULL;
+ }
+
+ decoder.errorStr = NULL;
+ decoder.errorOffset = NULL;
+
+ ret = JSON_DecodeObject(&decoder, PyString_AS_STRING(sarg), PyString_GET_SIZE(sarg));
+
+ if (sarg != arg)
+ {
+ Py_DECREF(sarg);
+ }
+
+ if (decoder.errorStr)
+ {
+ /*
+ FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/
+
+ PyErr_Format (PyExc_ValueError, "%s", decoder.errorStr);
+
+ if (ret)
+ {
+ Py_DECREF( (PyObject *) ret);
+ }
+
+ return NULL;
+ }
+
+ return ret;
+}
+
+PyObject* JSONFileToObj(PyObject* self, PyObject *file)
+{
+ PyObject *read;
+ PyObject *string;
+ PyObject *result;
+
+ if (!PyObject_HasAttrString (file, "read"))
+ {
+ PyErr_Format (PyExc_TypeError, "expected file");
+ return NULL;
+ }
+
+ read = PyObject_GetAttrString (file, "read");
+
+ if (!PyCallable_Check (read)) {
+ Py_XDECREF(read);
+ PyErr_Format (PyExc_TypeError, "expected file");
+ return NULL;
+ }
+
+ string = PyObject_CallObject (read, NULL);
+ Py_XDECREF(read);
+
+ if (string == NULL)
+ {
+ return NULL;
+ }
+
+ result = JSONToObj (self, string);
+ Py_XDECREF(string);
+
+ if (result == NULL) {
+ return NULL;
+ }
+
+ return result;
+}
+
View
1,669 python/objToJSON.c
842 additions, 827 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
15 python/py_defines.h
@@ -0,0 +1,15 @@
+#include <Python.h>
+
+#if PY_MAJOR_VERSION >= 3
+
+#define PyInt_Check PyLong_Check
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_FromLong PyLong_FromLong
+
+#define PyString_Check PyBytes_Check
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_AS_STRING PyBytes_AS_STRING
+
+#define PyString_FromString PyUnicode_FromString
+
+#endif
View
114 python/ujson.c
@@ -1,41 +1,73 @@
-#include <Python.h>
-#include "version.h"
-
-/* objToJSON */
-PyObject* objToJSON(PyObject* self, PyObject *arg);
-void initObjToJSON();
-
-/* JSONToObj */
-PyObject* JSONToObj(PyObject* self, PyObject *arg);
-
-/* objToJSONFile */
-PyObject* objToJSONFile(PyObject* self, PyObject *args);
-
-/* JSONFileToObj */
-PyObject* JSONFileToObj(PyObject* self, PyObject *file);
-
-
-static PyMethodDef ujsonMethods[] = {
- {"encode", objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8. Pass in double_precision to alter the maximum digit precision with doubles"},
- {"decode", JSONToObj, METH_O, "Converts JSON as string to dict object structure"},
- {"dumps", objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8"},
- {"loads", JSONToObj, METH_O, "Converts JSON as string to dict object structure"},
- {"dump", objToJSONFile, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON file. Use ensure_ascii=false to output UTF-8"},
- {"load", JSONFileToObj, METH_O, "Converts JSON as file to dict object structure"},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-
-
-PyMODINIT_FUNC
-initujson(void)
-{
- PyObject *module;
- PyObject *version_string;
-
- initObjToJSON();
- module = Py_InitModule("ujson", ujsonMethods);
-
- version_string = PyString_FromString (UJSON_VERSION);
- PyModule_AddObject (module, "__version__", version_string);
-}
+#include "py_defines.h"
+#include "version.h"
+
+/* objToJSON */
+PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs);
+void initObjToJSON(void);
+
+/* JSONToObj */
+PyObject* JSONToObj(PyObject* self, PyObject *arg);
+
+/* objToJSONFile */
+PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs);
+
+/* JSONFileToObj */
+PyObject* JSONFileToObj(PyObject* self, PyObject *file);
+
+
+static PyMethodDef ujsonMethods[] = {
+ {"encode", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8. Pass in double_precision to alter the maximum digit precision with doubles"},
+ {"decode", (PyCFunction) JSONToObj, METH_O, "Converts JSON as string to dict object structure"},
+ {"dumps", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8"},
+ {"loads", (PyCFunction) JSONToObj, METH_O, "Converts JSON as string to dict object structure"},
+ {"dump", (PyCFunction) objToJSONFile, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON file. Use ensure_ascii=false to output UTF-8"},
+ {"load", (PyCFunction) JSONFileToObj, METH_O, "Converts JSON as file to dict object structure"},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "ujson",
+ 0, /* m_doc */
+ -1, /* m_size */
+ ujsonMethods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+
+#define PYMODINITFUNC PyObject *PyInit_ujson(void)
+#define PYMODULE_CREATE() PyModule_Create(&moduledef)
+#define MODINITERROR return NULL
+
+#else
+
+#define PYMODINITFUNC PyMODINIT_FUNC initujson(void)
+#define PYMODULE_CREATE() Py_InitModule("ujson", ujsonMethods)
+#define MODINITERROR return
+
+#endif
+
+PYMODINITFUNC
+{
+ PyObject *module;
+ PyObject *version_string;
+
+ initObjToJSON();
+ module = PYMODULE_CREATE();
+
+ if (module == NULL)
+ {
+ MODINITERROR;
+ }
+
+ version_string = PyString_FromString (UJSON_VERSION);
+ PyModule_AddObject (module, "__version__", version_string);
+
+#if PY_MAJOR_VERSION >= 3
+ return module;
+#endif
+}
View
46 setup.py
@@ -3,6 +3,7 @@
import shutil
import os.path
import re
+import sys
CLASSIFIERS = filter(None, map(str.strip,
"""
@@ -17,26 +18,30 @@
""".splitlines()))
try:
- shutil.rmtree("./build")
+ shutil.rmtree("./build")
except(OSError):
- pass
+ pass
module1 = Extension('ujson',
- sources = ['./python/ujson.c', './python/objToJSON.c', './python/JSONtoObj.c', './lib/ultrajsonenc.c', './lib/ultrajsondec.c'],
+ sources = ['./python/ujson.c',
+ './python/objToJSON.c',
+ './python/JSONtoObj.c',
+ './lib/ultrajsonenc.c',
+ './lib/ultrajsondec.c'],
include_dirs = ['./python', './lib'])
def get_version():
- filename = os.path.join(os.path.dirname(__file__), './python/version.h')
- file = None
- try:
- file = open(filename)
- header = file.read()
- finally:
- if file:
- file.close()
- m = re.search(r'#define\s+UJSON_VERSION\s+"(\d+\.\d+(?:\.\d+)?)"', header)
- assert m, "version.h must contain UJSON_VERSION macro"
- return m.group(1)
+ filename = os.path.join(os.path.dirname(__file__), './python/version.h')
+ file = None
+ try:
+ file = open(filename)
+ header = file.read()
+ finally:
+ if file:
+ file.close()
+ m = re.search(r'#define\s+UJSON_VERSION\s+"(\d+\.\d+(?:\.\d+)?)"', header)
+ assert m, "version.h must contain UJSON_VERSION macro"
+ return m.group(1)
setup (name = 'ujson',
version = get_version(),
@@ -46,7 +51,14 @@ def get_version():
author_email="jonas.tarnstrom@esn.me",
download_url="http://github.com/esnme/ultrajson",
license="BSD License",
- platforms=['any'],
- url="http://www.esn.me",
+ platforms=['any'],
+ url="http://www.esn.me",
classifiers=CLASSIFIERS,
- )
+ )
+
+if sys.version_info[0] >= 3:
+ print( "*" * 100)
+ print("If you want to run the tests be sure to run 2to3 on them first, "
+ "e.g. `2to3 -w tests/tests.py`.")
+ print("*" * 100)
+
View
1,437 tests/tests.py
@@ -1,708 +1,739 @@
-
-import unittest
-from unittest import TestCase
-
-import ujson
-try:
- import json
-except ImportError:
- import simplejson as json
-import math
-import time
-import datetime
-import calendar
-import StringIO
-import re
-
-class UltraJSONTests(TestCase):
- def test_encodeDictWithUnicodeKeys(self):
- input = { u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1" }
- output = ujson.encode(input)
-
- input = { u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1" }
- output = ujson.encode(input)
-
- pass
-
- def test_encodeDoubleConversion(self):
- input = math.pi
- output = ujson.encode(input)
- self.assertEquals(round(input, 5), round(json.loads(output), 5))
- self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
-
- def test_encodeWithDecimal(self):
- input = 1.0
- output = ujson.encode(input)
- self.assertEquals(output, "1.0")
-
- def test_encodeDoubleNegConversion(self):
- input = -math.pi
- output = ujson.encode(input)
- self.assertEquals(round(input, 5), round(json.loads(output), 5))
- self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
-
- def test_encodeArrayOfNestedArrays(self):
- input = [[[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]] ]
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- #self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
-
- def test_encodeArrayOfDoubles(self):
- input = [ 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337 ]
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- #self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
-
- def test_doublePrecisionTest(self):
- input = 30.012345678
- output = ujson.encode(input, double_precision = 9)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(input, ujson.decode(output))
-
- output = ujson.encode(input, double_precision = 3)
- self.assertEquals(round(input, 3), json.loads(output))
- self.assertEquals(round(input, 3), ujson.decode(output))
-
- output = ujson.encode(input)
- self.assertEquals(round(input, 5), json.loads(output))
- self.assertEquals(round(input, 5), ujson.decode(output))
-
- def test_invalidDoublePrecision(self):
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+from unittest import TestCase
+
+import ujson
+try:
+ import json
+except ImportError:
+ import simplejson as json
+import math
+import platform
+import sys
+import time
+import datetime
+import calendar
+import StringIO
+import re
+from functools import partial
+
+PY3 = (sys.version_info[0] >= 3)
+
+def _python_ver(skip_major, skip_minor=None):
+ major, minor = sys.version_info[:2]
+ return major == skip_major and (skip_minor is None or minor == skip_minor)
+
+json_unicode = (json.dumps if sys.version_info[0] >= 3
+ else partial(json.dumps, encoding="utf-8"))
+
+class UltraJSONTests(TestCase):
+ def test_encodeDictWithUnicodeKeys(self):
+ input = { u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1", u"key1": u"value1" }
+ output = ujson.encode(input)
+
+ input = { u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1", u"بن": u"value1" }
+ output = ujson.encode(input)
+
+ pass
+
+ def test_encodeDoubleConversion(self):
+ input = math.pi
+ output = ujson.encode(input)
+ self.assertEquals(round(input, 5), round(json.loads(output), 5))
+ self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
+
+ def test_encodeWithDecimal(self):
+ input = 1.0
+ output = ujson.encode(input)
+ self.assertEquals(output, "1.0")
+
+ def test_encodeDoubleNegConversion(self):
+ input = -math.pi
+ output = ujson.encode(input)
+ self.assertEquals(round(input, 5), round(json.loads(output), 5))
+ self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
+
+ def test_encodeArrayOfNestedArrays(self):
+ input = [[[[]]]] * 20
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ #self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+
+ def test_encodeArrayOfDoubles(self):
+ input = [ 31337.31337, 31337.31337, 31337.31337, 31337.31337] * 10
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ #self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+
+ def test_doublePrecisionTest(self):
+ input = 30.012345678901234
+ output = ujson.encode(input, double_precision = 15)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(input, ujson.decode(output))
+
+ output = ujson.encode(input, double_precision = 9)
+ self.assertEquals(round(input, 9), json.loads(output))
+ self.assertEquals(round(input, 9), ujson.decode(output))
+
+ output = ujson.encode(input, double_precision = 3)
+ self.assertEquals(round(input, 3), json.loads(output))
+ self.assertEquals(round(input, 3), ujson.decode(output))
+
+ output = ujson.encode(input)
+ self.assertEquals(round(input, 5), json.loads(output))
+ self.assertEquals(round(input, 5), ujson.decode(output))
+
+ def test_invalidDoublePrecision(self):
input = 30.12345678901234567890
- output = ujson.encode(input, double_precision = 20)
- # should snap to the max, which is 9
- self.assertEquals(round(input, 9), json.loads(output))
- self.assertEquals(round(input, 9), ujson.decode(output))
+ output = ujson.encode(input, double_precision = 20)
+ # should snap to the max, which is 15
+ self.assertEquals(round(input, 15), json.loads(output))
+ self.assertEquals(round(input, 15), ujson.decode(output))
- output = ujson.encode(input, double_precision = -1)
- # also should snap to the max, which is 9
- self.assertEquals(round(input, 9), json.loads(output))
- self.assertEquals(round(input, 9), ujson.decode(output))
+ output = ujson.encode(input, double_precision = -1)
+ # also should snap to the max, which is 15
+ self.assertEquals(round(input, 15), json.loads(output))
+ self.assertEquals(round(input, 15), ujson.decode(output))
# will throw typeError
- self.assertRaises(TypeError, ujson.encode, input, double_precision = '9')
+ self.assertRaises(TypeError, ujson.encode, input, double_precision = '9')
# will throw typeError
- self.assertRaises(TypeError, ujson.encode, input, double_precision = None)
-
-
- def test_encodeStringConversion(self):
- input = "A string \\ / \b \f \n \r \t"
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, '"A string \\\\ \\/ \\b \\f \\n \\r \\t"')
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_decodeUnicodeConversion(self):
- pass
-
- def test_encodeUnicodeConversion1(self):
- input = "Räksmörgås اسامة بن محمد بن عوض بن لادن"
- enc = ujson.encode(input)
- dec = ujson.decode(enc)
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
- self.assertEquals(dec, json.loads(enc))
-
- def test_encodeControlEscaping(self):
- input = "\x19"
- enc = ujson.encode(input)
- dec = ujson.decode(enc)
- self.assertEquals(input, dec)
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
-
-
- def test_encodeUnicodeConversion2(self):
- input = "\xe6\x97\xa5\xd1\x88"
- enc = ujson.encode(input)
- dec = ujson.decode(enc)
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
- self.assertEquals(dec, json.loads(enc))
-
- def test_encodeUnicodeSurrogatePair(self):
- input = "\xf0\x90\x8d\x86"
- enc = ujson.encode(input)
- dec = ujson.decode(enc)
-
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
- self.assertEquals(dec, json.loads(enc))
-
- def test_encodeUnicode4BytesUTF8(self):
- input = "\xf0\x91\x80\xb0TRAILINGNORMAL"
- enc = ujson.encode(input)
- dec = ujson.decode(enc)
-
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
- self.assertEquals(dec, json.loads(enc))
-
- def test_encodeUnicode4BytesUTF8Highest(self):
- input = "\xf3\xbf\xbf\xbfTRAILINGNORMAL"
- enc = ujson.encode(input)
-
- dec = ujson.decode(enc)
-
- self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
- self.assertEquals(dec, json.loads(enc))
-
-
- def test_encodeArrayInArray(self):
- input = [[[[]]]]
- output = ujson.encode(input)
-
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeIntConversion(self):
- input = 31337
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeIntNegConversion(self):
- input = -31337
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
-
- def test_encodeLongNegConversion(self):
- input = -9223372036854775808
- output = ujson.encode(input)
-
- outputjson = json.loads(output)
- outputujson = ujson.decode(output)
-
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeListConversion(self):
- input = [ 1, 2, 3, 4 ]
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeDictConversion(self):
- input = { "k1": 1, "k2": 2, "k3": 3, "k4": 4 }
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(input, ujson.decode(output))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeNoneConversion(self):
- input = None
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeTrueConversion(self):
- input = True
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeFalseConversion(self):
- input = False
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeDatetimeConversion(self):
- ts = time.time()
- input = datetime.datetime.fromtimestamp(ts)
- output = ujson.encode(input)
- expected = calendar.timegm(input.utctimetuple())
- self.assertEquals(int(expected), json.loads(output))
- self.assertEquals(int(expected), ujson.decode(output))
- pass
-
- def test_encodeDateConversion(self):
- ts = time.time()
- input = datetime.date.fromtimestamp(ts)
-
- output = ujson.encode(input)
- tup = ( input.year, input.month, input.day, 0, 0, 0 )
-
- expected = calendar.timegm(tup)
- self.assertEquals(int(expected), json.loads(output))
- self.assertEquals(int(expected), ujson.decode(output))
- pass
-
- def test_encodeToUTF8(self):
- input = "\xe6\x97\xa5\xd1\x88"
- enc = ujson.encode(input, ensure_ascii=False)
- dec = ujson.decode(enc)
- self.assertEquals(enc, json.dumps(input, encoding="utf-8", ensure_ascii=False))
- self.assertEquals(dec, json.loads(enc))
-
- def test_decodeFromUnicode(self):
- input = u"{\"obj\": 31337}"
- dec1 = ujson.decode(input)
- dec2 = ujson.decode(str(input))
- self.assertEquals(dec1, dec2)
-
- def test_encodeRecursionMax(self):
- # 8 is the max recursion depth
-
- class O2:
- member = 0
- pass
-
- class O1:
- member = 0
- pass
-
- input = O1()
- input.member = O2()
- input.member.member = input
-
- try:
- output = ujson.encode(input)
- assert False, "Expected overflow exception"
- except(OverflowError):
- pass
-
- def test_encodeDoubleNan(self):
- input = float('nan')
- try:
- ujson.encode(input)
- assert False, "Expected exception!"
- except(OverflowError):
- return
- assert False, "Wrong exception"
-
- def test_encodeDoubleInf(self):
- input = float('inf')
- try:
- ujson.encode(input)
- assert False, "Expected exception!"
- except(OverflowError):
- return
- assert False, "Wrong exception"
-
- def test_encodeDoubleNegInf(self):
- input = -float('inf')
- try:
- ujson.encode(input)
- assert False, "Expected exception!"
- except(OverflowError):
- return
- assert False, "Wrong exception"
-
-
- def test_decodeJibberish(self):
- input = "fdsa sda v9sa fdsa"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeBrokenArrayStart(self):
- input = "["
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeBrokenObjectStart(self):
- input = "{"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeBrokenArrayEnd(self):
- input = "]"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeBrokenObjectEnd(self):
- input = "}"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeStringUnterminated(self):
- input = "\"TESTING"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeStringUntermEscapeSequence(self):
- input = "\"TESTING\\\""
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeStringBadEscape(self):
- input = "\"TESTING\\\""
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeTrueBroken(self):
- input = "tru"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeFalseBroken(self):
- input = "fa"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
- def test_decodeNullBroken(self):
- input = "n"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
- assert False, "Wrong exception"
-
-
- def test_decodeBrokenDictKeyTypeLeakTest(self):
- input = '{{1337:""}}'
- for x in xrange(1000):
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError),e:
- continue
-
- assert False, "Wrong exception"
-
- def test_decodeBrokenDictLeakTest(self):
- input = '{{"key":"}'
- for x in xrange(1000):
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- continue
-
- assert False, "Wrong exception"
-
- def test_decodeBrokenListLeakTest(self):
- input = '[[[true'
- for x in xrange(1000):
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- continue
-
- assert False, "Wrong exception"
-
- def test_decodeDictWithNoKey(self):
- input = "{{{{31337}}}}"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
-
- assert False, "Wrong exception"
-
- def test_decodeDictWithNoColonOrValue(self):
- input = "{{{{\"key\"}}}}"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
-
- assert False, "Wrong exception"
-
- def test_decodeDictWithNoValue(self):
- input = "{{{{\"key\":}}}}"
- try:
- ujson.decode(input)
- assert False, "Expected exception!"
- except(ValueError):
- return
-
- assert False, "Wrong exception"
-
- def test_decodeNumericIntPos(self):
- input = "31337"
- self.assertEquals (31337, ujson.decode(input))
-
- def test_decodeNumericIntNeg(self):
- input = "-31337"
- self.assertEquals (-31337, ujson.decode(input))
-
- def test_encodeUnicode4BytesUTF8Fail(self):
- input = "\xfd\xbf\xbf\xbf\xbf\xbf"
- try:
- enc = ujson.encode(input)
- assert False, "Expected exception"
- except OverflowError:
- pass
-
- def test_encodeNullCharacter(self):
- input = "31337 \x00 1337"
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
-
- input = "\x00"
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
-
- self.assertEquals('" \\u0000\\r\\n "', ujson.dumps(u" \u0000\r\n "))
- pass
-
- def test_decodeNullCharacter(self):
- input = "\"31337 \\u0000 31337\""
- self.assertEquals(ujson.decode(input), json.loads(input))
-
-
- def test_encodeListLongConversion(self):
- input = [9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807 ]
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_encodeLongConversion(self):
- input = 9223372036854775807
- output = ujson.encode(input)
- self.assertEquals(input, json.loads(output))
- self.assertEquals(output, json.dumps(input))
- self.assertEquals(input, ujson.decode(output))
- pass
-
- def test_numericIntExp(self):
- input = "1337E40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_numericIntFrcExp(self):
- input = "1.337E40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpEPLUS(self):
- input = "1337E+40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpePLUS(self):
- input = "1.337e+40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpE(self):
- input = "1337E40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpe(self):
- input = "1337e40"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpEMinus(self):
- input = "1.337E-4"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_decodeNumericIntExpeMinus(self):
- input = "1.337e-4"
- output = ujson.decode(input)
- self.assertEquals(output, json.loads(input))
-
- def test_dumpToFile(self):
- f = StringIO.StringIO()
- ujson.dump([1, 2, 3], f)
- self.assertEquals("[1,2,3]", f.getvalue())
-
- def test_dumpToFileLikeObject(self):
- class filelike:
- def __init__(self):
- self.bytes = ''
- def write(self, bytes):
- self.bytes += bytes
- f = filelike()
- ujson.dump([1, 2, 3], f)
- self.assertEquals("[1,2,3]", f.bytes)
-
- def test_dumpFileArgsError(self):
- try:
- ujson.dump([], '')
- except TypeError:
- pass
- else:
- assert False, 'expected TypeError'
-
- def test_loadFile(self):
- f = StringIO.StringIO("[1,2,3,4]")
- self.assertEquals([1, 2, 3, 4], ujson.load(f))
-
- def test_loadFileLikeObject(self):
- class filelike:
- def read(self):
- try:
- self.end
- except AttributeError:
- self.end = True
- return "[1,2,3,4]"
- f = filelike()
- self.assertEquals([1, 2, 3, 4], ujson.load(f))
-
- def test_loadFileArgsError(self):
- try:
- ujson.load("[]")
- except TypeError:
- pass
- else:
- assert False, "expected TypeError"
-
- def test_version(self):
- assert re.match(r'^\d+\.\d+(\.\d+)?$', ujson.__version__), \
- "ujson.__version__ must be a string like '1.4.0'"
-
- def test_encodeNumericOverflow(self):
- try:
- ujson.encode(12839128391289382193812939)
- except OverflowError:
- pass
- else:
- assert False, "expected OverflowError"
-
- def test_encodeNumericOverflowNested(self):
- for n in xrange(0, 100):
- class Nested:
- x = 12839128391289382193812939
-
- nested = Nested()
-
- try:
- ujson.encode(nested)
- except OverflowError:
- pass
- else:
- assert False, "expected OverflowError"
-
- def test_decodeNumberWith32bitSignBit(self):
- #Test that numbers that fit within 32 bits but would have the
- # sign bit set (2**31 <= x < 2**32) are decoded properly.
- boundary1 = 2**31
- boundary2 = 2**32
- docs = (
- '{"id": 3590016419}',
- '{"id": %s}' % 2**31,
- '{"id": %s}' % 2**32,
- '{"id": %s}' % ((2**32)-1),
- )
- results = (3590016419, 2**31, 2**32, 2**32-1)
- for doc,result in zip(docs, results):
- self.assertEqual(ujson.decode(doc)['id'], result)
-
- def test_encodeBigEscape(self):
- for x in xrange(10):
- input = "\xc3\xa5" * 1024 * 1024 * 10
- output = ujson.encode(input)
-
- def test_decodeBigEscape(self):
- for x in xrange(10):
- input = "\"" + ("\xc3\xa5" * 1024 * 1024 * 10) + "\""
- output = ujson.decode(input)
-
- def test_toDict(self):
- d = {u"key": 31337}
-
- class DictTest:
- def toDict(self):
- return d
-
- o = DictTest()
- output = ujson.encode(o)
- dec = ujson.decode(output)
- self.assertEquals(dec, d)
-
-"""
-def test_decodeNumericIntFrcOverflow(self):
-input = "X.Y"
-raise NotImplementedError("Implement this test!")
-
-
-def test_decodeStringUnicodeEscape(self):
-input = "\u3131"
-raise NotImplementedError("Implement this test!")
-
-def test_decodeStringUnicodeBrokenEscape(self):
-input = "\u3131"
-raise NotImplementedError("Implement this test!")
-
-def test_decodeStringUnicodeInvalidEscape(self):
-input = "\u3131"
-raise NotImplementedError("Implement this test!")
-
-def test_decodeStringUTF8(self):
-input = "someutfcharacters"
-raise NotImplementedError("Implement this test!")
-
-
-
-"""
-if __name__ == "__main__":
- unittest.main()
-
-if __name__ == '__main__':
- from guppy import hpy
- hp = hpy()
- hp.setrelheap()
- while True:
- unittest.main()
- heap = hp.heapu()
- print heap
+ self.assertRaises(TypeError, ujson.encode, input, double_precision = None)
+
+
+ def test_encodeStringConversion(self):
+ input = "A string \\ / \b \f \n \r \t"
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, '"A string \\\\ \\/ \\b \\f \\n \\r \\t"')
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_decodeUnicodeConversion(self):
+ pass
+
+ def test_encodeUnicodeConversion1(self):
+ input = "Räksmörgås اسامة بن محمد بن عوض بن لادن"
+ enc = ujson.encode(input)
+ dec = ujson.decode(enc)
+ self.assertEquals(enc, json_unicode(input))
+ self.assertEquals(dec, json.loads(enc))
+
+ def test_encodeControlEscaping(self):
+ input = "\x19"
+ enc = ujson.encode(input)
+ dec = ujson.decode(enc)
+ self.assertEquals(input, dec)
+ self.assertEquals(enc, json_unicode(input))
+
+
+ def test_encodeUnicodeConversion2(self):
+ input = "\xe6\x97\xa5\xd1\x88"
+ enc = ujson.encode(input)
+ dec = ujson.decode(enc)
+ self.assertEquals(enc, json_unicode(input))
+ self.assertEquals(dec, json.loads(enc))
+
+ def test_encodeUnicodeSurrogatePair(self):
+ input = "\xf0\x90\x8d\x86"
+ enc = ujson.encode(input)
+ dec = ujson.decode(enc)
+
+ self.assertEquals(enc, json_unicode(input))
+ self.assertEquals(dec, json.loads(enc))
+
+ def test_encodeUnicode4BytesUTF8(self):
+ input = "\xf0\x91\x80\xb0TRAILINGNORMAL"
+ enc = ujson.encode(input)
+ dec = ujson.decode(enc)
+
+ self.assertEquals(enc, json_unicode(input))
+ self.assertEquals(dec, json.loads(enc))
+
+ def test_encodeUnicode4BytesUTF8Highest(self):
+ input = "\xf3\xbf\xbf\xbfTRAILINGNORMAL"
+ enc = ujson.encode(input)
+
+ dec = ujson.decode(enc)
+
+ self.assertEquals(enc, json_unicode(input))
+ self.assertEquals(dec, json.loads(enc))
+
+
+ def test_encodeArrayInArray(self):
+ input = [[[[]]]]
+ output = ujson.encode(input)
+
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeIntConversion(self):
+ input = 31337
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeIntNegConversion(self):
+ input = -31337
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+
+ def test_encodeLongNegConversion(self):
+ input = -9223372036854775808
+ output = ujson.encode(input)
+
+ outputjson = json.loads(output)
+ outputujson = ujson.decode(output)
+
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeListConversion(self):
+ input = [ 1, 2, 3, 4 ]
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeDictConversion(self):
+ input = { "k1": 1, "k2": 2, "k3": 3, "k4": 4 }
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(input, ujson.decode(output))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeNoneConversion(self):
+ input = None
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeTrueConversion(self):
+ input = True
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeFalseConversion(self):
+ input = False
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeDatetimeConversion(self):
+ ts = time.time()
+ input = datetime.datetime.fromtimestamp(ts)
+ output = ujson.encode(input)
+ expected = calendar.timegm(input.utctimetuple())
+ self.assertEquals(int(expected), json.loads(output))
+ self.assertEquals(int(expected), ujson.decode(output))
+ pass
+
+ def test_encodeDateConversion(self):
+ ts = time.time()
+ input = datetime.date.fromtimestamp(ts)
+
+ output = ujson.encode(input)
+ tup = ( input.year, input.month, input.day, 0, 0, 0 )
+
+ expected = calendar.timegm(tup)
+ self.assertEquals(int(expected), json.loads(output))
+ self.assertEquals(int(expected), ujson.decode(output))
+ pass
+
+ def test_encodeToUTF8(self):
+ input = "\xe6\x97\xa5\xd1\x88"
+ enc = ujson.encode(input, ensure_ascii=False)
+ dec = ujson.decode(enc)
+ self.assertEquals(enc, json_unicode(input, ensure_ascii=False))
+ self.assertEquals(dec, json.loads(enc))
+
+ def test_decodeFromUnicode(self):
+ input = u"{\"obj\": 31337}"
+ dec1 = ujson.decode(input)
+ dec2 = ujson.decode(str(input))
+ self.assertEquals(dec1, dec2)
+
+ def test_encodeRecursionMax(self):
+ # 8 is the max recursion depth
+
+ class O2:
+ member = 0
+ pass
+
+ class O1:
+ member = 0
+ pass
+
+ input = O1()
+ input.member = O2()
+ input.member.member = input
+
+ try:
+ output = ujson.encode(input)
+ assert False, "Expected overflow exception"
+ except(OverflowError):
+ pass
+
+ def test_encodeDoubleNan(self):
+ input = float('nan')
+ try:
+ ujson.encode(input)
+ assert False, "Expected exception!"
+ except(OverflowError):
+ return
+ assert False, "Wrong exception"
+
+ def test_encodeDoubleInf(self):
+ input = float('inf')
+ try:
+ ujson.encode(input)
+ assert False, "Expected exception!"
+ except(OverflowError):
+ return
+ assert False, "Wrong exception"
+
+ def test_encodeDoubleNegInf(self):
+ input = -float('inf')
+ try:
+ ujson.encode(input)
+ assert False, "Expected exception!"
+ except(OverflowError):
+ return
+ assert False, "Wrong exception"
+
+
+ def test_decodeJibberish(self):
+ input = "fdsa sda v9sa fdsa"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenArrayStart(self):
+ input = "["
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenObjectStart(self):
+ input = "{"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenArrayEnd(self):
+ input = "]"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenObjectEnd(self):
+ input = "}"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeStringUnterminated(self):
+ input = "\"TESTING"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeStringUntermEscapeSequence(self):
+ input = "\"TESTING\\\""
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeStringBadEscape(self):
+ input = "\"TESTING\\\""
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeTrueBroken(self):
+ input = "tru"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeFalseBroken(self):
+ input = "fa"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+ def test_decodeNullBroken(self):
+ input = "n"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+ assert False, "Wrong exception"
+
+
+ def test_decodeBrokenDictKeyTypeLeakTest(self):
+ input = '{{1337:""}}'
+ for x in xrange(1000):
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError),e:
+ continue
+
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenDictLeakTest(self):
+ input = '{{"key":"}'
+ for x in xrange(1000):
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ continue
+
+ assert False, "Wrong exception"
+
+ def test_decodeBrokenListLeakTest(self):
+ input = '[[[true'
+ for x in xrange(1000):
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ continue
+
+ assert False, "Wrong exception"
+
+ def test_decodeDictWithNoKey(self):
+ input = "{{{{31337}}}}"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+
+ assert False, "Wrong exception"
+
+ def test_decodeDictWithNoColonOrValue(self):
+ input = "{{{{\"key\"}}}}"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+
+ assert False, "Wrong exception"
+
+ def test_decodeDictWithNoValue(self):
+ input = "{{{{\"key\":}}}}"
+ try:
+ ujson.decode(input)
+ assert False, "Expected exception!"
+ except(ValueError):
+ return
+
+ assert False, "Wrong exception"
+
+ def test_decodeNumericIntPos(self):
+ input = "31337"
+ self.assertEquals (31337, ujson.decode(input))
+
+ def test_decodeNumericIntNeg(self):
+ input = "-31337"
+ self.assertEquals (-31337, ujson.decode(input))
+
+ @unittest.skipIf(_python_ver(3), "No exception in Python 3")
+ def test_encodeUnicode4BytesUTF8Fail(self):
+ input = "\xfd\xbf\xbf\xbf\xbf\xbf"
+ try:
+ enc = ujson.encode(input)
+ assert False, "Expected exception"
+ except OverflowError:
+ pass
+
+ def test_encodeNullCharacter(self):
+ input = "31337 \x00 1337"
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+
+ input = "\x00"
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+
+ self.assertEquals('" \\u0000\\r\\n "', ujson.dumps(u" \u0000\r\n "))
+ pass
+
+ def test_decodeNullCharacter(self):
+ input = "\"31337 \\u0000 31337\""
+ self.assertEquals(ujson.decode(input), json.loads(input))
+
+
+ def test_encodeListLongConversion(self):
+ input = [9223372036854775807, 9223372036854775807, 9223372036854775807,
+ 9223372036854775807, 9223372036854775807, 9223372036854775807 ]
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_encodeLongConversion(self):
+ input = 9223372036854775807
+ output = ujson.encode(input)
+ self.assertEquals(input, json.loads(output))
+ self.assertEquals(output, json.dumps(input))
+ self.assertEquals(input, ujson.decode(output))
+ pass
+
+ def test_numericIntExp(self):
+ input = "1337E40"
+ output = ujson.decode(input)
+ self.assertEquals(output, json.loads(input))
+
+ def test_numericIntFrcExp(self):
+ input = "1.337E40"
+ output = ujson.decode(input)
+ self.assertEquals(output, json.loads(input))
+
+ def test_decodeNumericIntExpEPLUS(self):
+ input = "1337E+40"
+ output = ujson.decode(input)
+ self.assertEquals(output, json.loads(input))
+
+ def test_decodeNumericIntExpePLUS(self):
+ input = "