Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

make yajl.(De|En)coder subclassable. Add default methode to Encoder and

modify ProcessObject to mimick simplejson's JSONEncoder behaviour when
encountering unknown types
  • Loading branch information...
commit 001ba95c4dbed542cf70cbf1338320da4ec303a5 1 parent 70430ea
Igor authored committed
Showing with 29 additions and 2 deletions.
  1. +18 −0 encoder.c
  2. +1 −0  py_yajl.h
  3. +7 −0 tests/unit.py
  4. +3 −2 yajl.c
18 encoder.c
View
@@ -247,6 +247,15 @@ static yajl_gen_status ProcessObject(_YajlEncoder *self, PyObject *object)
}
return yajl_gen_map_close(handle);
}
+ else {
+ object = PyObject_CallMethod((PyObject *)self, "default", "O", object);
+ if (object==NULL)
+ goto exit;
+ status = ProcessObject(self, object);
+ return status;
+ }
+
+
exit:
return yajl_gen_in_error_state;
@@ -366,6 +375,15 @@ PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj, yajl_gen_config ge
#endif
}
+PyObject *py_yajlencoder_default(PYARGS)
+{
+ PyObject *value;
+ if (!PyArg_ParseTuple(args, "O", &value))
+ return NULL;
+ PyErr_SetObject(PyExc_TypeError, PyUnicode_FromString("Not serializable to JSON"));
+ return NULL;
+}
+
PyObject *py_yajlencoder_encode(PYARGS)
{
_YajlEncoder *encoder = (_YajlEncoder *)(self);
1  py_yajl.h
View
@@ -96,6 +96,7 @@ extern PyObject *_internal_decode(_YajlDecoder *self, char *buffer, unsigned int
* Methods defined for the YajlEncoder type in encoder.c
*/
extern PyObject *py_yajlencoder_encode(PYARGS);
+extern PyObject* py_yajlencoder_default(PYARGS);
extern int yajlencoder_init(PYARGS);
extern void yajlencoder_dealloc(_YajlEncoder *self);
extern PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj, yajl_gen_config config);
7 tests/unit.py
View
@@ -102,6 +102,13 @@ def f():
for i in range(10):
yield i
self.assertEncodesTo(f(), '[0,1,2,3,4,5,6,7,8,9]')
+ def test_default(self):
+ class MyEncode(yajl.Encoder):
+ def default(self, obj):
+ return ['foo']
+ rc = MyEncode().encode(MyEncode) #not supported directly -- will call default
+ assert rc == '["foo"]', ('Failed to encode JSON correctly', locals())
+ return True
5 yajl.c
View
@@ -40,6 +40,7 @@ static PyMethodDef yajldecoder_methods[] = {
static PyMethodDef yajlencoder_methods[] = {
{"encode", (PyCFunction)(py_yajlencoder_encode), METH_VARARGS, NULL},
+ {"default", (PyCFunction)(py_yajlencoder_default), METH_VARARGS, NULL},
{NULL}
};
@@ -68,7 +69,7 @@ static PyTypeObject YajlDecoderType = {
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Yajl-based decoder", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -113,7 +114,7 @@ static PyTypeObject YajlEncoderType = {
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Yajl-based encoder", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
Please sign in to comment.
Something went wrong with that request. Please try again.