summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Ippolito <bob@redivi.com>2016-10-28 17:02:47 +0800
committerBob Ippolito <bob@redivi.com>2016-10-28 17:02:47 +0800
commit392e2e7b51635b060dafdb4a08c130fa26421685 (patch)
treec176f6597a33292b7a281719de4268f1a8eb01d6
parent3233faaf438690d0aa853d131ead4a9c99935485 (diff)
parentda17e3529c4e41173519ea18ff3ee908761ef5d4 (diff)
downloadsimplejson-392e2e7b51635b060dafdb4a08c130fa26421685.tar.gz
Merge branch 'raw_json' of https://github.com/lamflam/simplejson into lamflam-raw_json
-rw-r--r--simplejson/__init__.py2
-rw-r--r--simplejson/_speedups.c22
-rw-r--r--simplejson/encoder.py10
-rw-r--r--simplejson/tests/test_raw_json.py30
4 files changed, 63 insertions, 1 deletions
diff --git a/simplejson/__init__.py b/simplejson/__init__.py
index 84acfa4..37a6012 100644
--- a/simplejson/__init__.py
+++ b/simplejson/__init__.py
@@ -110,7 +110,7 @@ from decimal import Decimal
from .scanner import JSONDecodeError
from .decoder import JSONDecoder
-from .encoder import JSONEncoder, JSONEncoderForHTML
+from .encoder import JSONEncoder, JSONEncoderForHTML, RawJSON
def _import_OrderedDict():
import collections
try:
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 9976464..2d81063 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -245,6 +245,8 @@ static void
encoder_dealloc(PyObject *self);
static int
encoder_clear(PyObject *self);
+static int
+is_raw_json(PyObject *obj);
static PyObject *
encoder_stringify_key(PyEncoderObject *s, PyObject *key);
static int
@@ -277,6 +279,20 @@ moduleinit(void);
#define MIN_EXPANSION 6
+static PyObject* RawJSONType;
+static int
+is_raw_json(PyObject *obj)
+{
+ if (RawJSONType == NULL) {
+ PyObject *encoder_module = PyImport_ImportModule("simplejson.encoder");
+ RawJSONType = PyObject_GetAttrString(encoder_module, "RawJSON");
+ Py_DECREF(encoder_module);
+ if (RawJSONType == NULL)
+ return 0;
+ }
+ return PyObject_IsInstance(obj, RawJSONType) ? 1 : 0;
+}
+
static int
JSON_Accu_Init(JSON_Accu *acc)
{
@@ -2868,6 +2884,12 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss
if (encoded != NULL)
rv = _steal_accumulate(rval, encoded);
}
+ else if (is_raw_json(obj))
+ {
+ PyObject *encoded = PyObject_GetAttrString(obj, "encoded_json");
+ if (encoded != NULL)
+ rv = _steal_accumulate(rval, encoded);
+ }
else if (PyInt_Check(obj) || PyLong_Check(obj)) {
PyObject *encoded;
if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)) {
diff --git a/simplejson/encoder.py b/simplejson/encoder.py
index d453d09..9c9b81e 100644
--- a/simplejson/encoder.py
+++ b/simplejson/encoder.py
@@ -39,6 +39,10 @@ for i in [0x2028, 0x2029]:
FLOAT_REPR = repr
+class RawJSON(object):
+ def __init__(self, encoded_json):
+ self.encoded_json = encoded_json
+
def encode_basestring(s, _PY3=PY3, _q=u('"')):
"""Return a JSON representation of a Python string
@@ -472,6 +476,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
if (isinstance(value, string_types) or
(_PY3 and isinstance(value, binary_type))):
yield buf + _encoder(value)
+ elif isinstance(value, RawJSON):
+ yield buf + value.encoded_json
elif value is None:
yield buf + 'null'
elif value is True:
@@ -590,6 +596,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
if (isinstance(value, string_types) or
(_PY3 and isinstance(value, binary_type))):
yield _encoder(value)
+ elif isinstance(value, RawJSON):
+ yield value.encoded_json
elif value is None:
yield 'null'
elif value is True:
@@ -632,6 +640,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
if (isinstance(o, string_types) or
(_PY3 and isinstance(o, binary_type))):
yield _encoder(o)
+ elif isinstance(o, RawJSON):
+ buf + o.encoded_json
elif o is None:
yield 'null'
elif o is True:
diff --git a/simplejson/tests/test_raw_json.py b/simplejson/tests/test_raw_json.py
new file mode 100644
index 0000000..6fa6349
--- /dev/null
+++ b/simplejson/tests/test_raw_json.py
@@ -0,0 +1,30 @@
+import unittest
+import simplejson as json
+
+dct1 = {
+ 'key1': 'value1'
+}
+
+dct2 = {
+ 'key2': 'value2',
+ 'd1': dct1
+}
+
+dct3 = {
+ 'key2': 'value2',
+ 'd1': json.dumps(dct1)
+}
+
+dct4 = {
+ 'key2': 'value2',
+ 'd1': json.RawJSON(json.dumps(dct1))
+}
+
+
+class TestRawJson(unittest.TestCase):
+
+ def test_normal_str(self):
+ self.assertNotEqual(json.dumps(dct2), json.dumps(dct3))
+
+ def test_raw_json_str(self):
+ self.assertEqual(json.dumps(dct2), json.dumps(dct4))