# HG changeset patch # User shakefu <shakefu@gmail.com> # Date 1366182970 25200 # Wed Apr 17 00:16:10 2013 -0700 # Node ID 1eaef2b53c0754549b7768b77802f28f7a0654c4 # Parent 8cc5beb051eb5284a19f7f34fa7b50138f8f8512 Initial stab at for_json hook for C extension. diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -260,6 +260,8 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj); static int _is_namedtuple(PyObject *obj); +static int +_has_for_json_hook(PyObject *obj); static PyObject * moduleinit(void); @@ -427,6 +429,20 @@ } static int +_has_for_json_hook(PyObject *obj) +{ + int rval = 0; + PyObject *for_json = PyObject_GetAttrString(obj, "for_json"); + if (for_json == NULL) { + PyErr_Clear(); + return 0; + } + rval = PyCallable_Check(for_json); + Py_DECREF(for_json); + return rval; +} + +static int _convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr) { /* PyObject to Py_ssize_t converter */ @@ -2801,6 +2817,17 @@ if (encoded != NULL) rv = _steal_accumulate(rval, encoded); } + else if (_has_for_json_hook(obj)) { + PyObject *newobj; + if (Py_EnterRecursiveCall(" while encoding a JSON object")) + return rv; + newobj = PyObject_CallMethod(obj, "for_json", NULL); + if (newobj != NULL) { + rv = encoder_listencode_obj(s, rval, newobj, indent_level); + Py_DECREF(newobj); + } + Py_LeaveRecursiveCall(); + } else if (s->namedtuple_as_object && _is_namedtuple(obj)) { PyObject *newobj; if (Py_EnterRecursiveCall(" while encoding a JSON object"))