| Patch added by neurogeek@gentoo.org |
| Patch added 03/01/2010 |
| Taken from: http://www.freebsd.org/cgi/cvsweb.cgi/ports/net/py-xmlrpc/files/ |
| Thanks to sobomax @ FreeBSD |
| |
| Due to unresponsiveness of the development team of the py-xmlrpc, I'm sending |
| this change request here in hope it can help the developers that use this |
| port. |
| |
| The py-xmlrpc module has a problem with boolean type - it implements boolean |
| type internally thus creating difficulties on encode/decode path of the |
| boolean variables. I've changed the source code to use internal Python's |
| boolean type and this made things straight to the user of this module. |
| |
| Another change I've made to the module is support for the <nil/> element. |
| Despite the fact this element isn't mentioned in the XML-RPC specification, |
| many of implementations support it, as this is the very convenient way to |
| pass null values from the environments with dynamic typing such as |
| Python, Perl, etc. |
| |
| |
| --- src/rpcBoolean.c.orig 2002-02-21 09:08:11.000000000 +0200 |
| +++ src/rpcBoolean.c 2008-10-15 10:41:34.000000000 +0300 |
| @@ -2,142 +2,3 @@ |
| * Copyright (C) 2001, Shilad Sen, Sourcelight Technologies, Inc. |
| * See xmlrpc.h or the README for more copyright information. |
| */ |
| - |
| - |
| -#include "xmlrpc.h" |
| -#include "rpcInternal.h" |
| - |
| - |
| -static void rpcBoolDealloc(rpcBool *bp); |
| -static int rpcBoolLength(rpcBool *bp); |
| -static int rpcBoolCompare(rpcBool *b1, rpcBool *b2); |
| -static PyObject *rpcBoolRepr(rpcBool *bp); |
| - |
| - |
| -/* |
| - * create a new edb boolean object |
| - */ |
| -PyObject * |
| -rpcBoolNew(bool value) |
| -{ |
| - rpcBool *bp; |
| - |
| - bp = PyObject_NEW(rpcBool, &rpcBoolType); |
| - if (bp == NULL) |
| - return NULL; |
| - bp->value = value; |
| - return (PyObject *)bp; |
| -} |
| - |
| - |
| -/* |
| - * get the value (true or false) of a boolean rpc object |
| - */ |
| -bool |
| -rpcBoolValue(PyObject *obj) |
| -{ |
| - return ((rpcBool *)obj)->value; |
| -} |
| - |
| - |
| -/* |
| - * free resources associated with a boolean object |
| - */ |
| -static void |
| -rpcBoolDealloc(rpcBool *bp) |
| -{ |
| - PyMem_DEL(bp); |
| -} |
| - |
| - |
| -/* |
| - * tell whether a boolean object is true or false |
| - */ |
| -static int |
| -rpcBoolLength(rpcBool *bp) |
| -{ |
| - if (bp->value) |
| - return 1; |
| - else |
| - return 0; |
| -} |
| - |
| - |
| -/* |
| - * bool object to dictionary conversion |
| - */ |
| -static PyMappingMethods rpcBoolAsMapping = { |
| - (inquiry)rpcBoolLength, /* mapping length */ |
| - (binaryfunc)NULL, /* mapping subscript */ |
| - (objobjargproc)NULL, /* mapping associate subscript */ |
| -}; |
| - |
| - |
| -/* |
| - * boolean comparison |
| - */ |
| -static int |
| -rpcBoolCompare(rpcBool *b1, rpcBool *b2) |
| -{ |
| - if (not b1->value and not b2->value) |
| - return 0; |
| - else if (b1->value and b2->value) |
| - return 0; |
| - else |
| - return 1; |
| -} |
| - |
| - |
| -/* |
| - * represent a boolean xml object |
| - */ |
| -static PyObject * |
| -rpcBoolStr(rpcBool *bp) |
| -{ |
| - if (bp->value) |
| - return PyString_FromString("<xmlrpc boolean true>"); |
| - else |
| - return PyString_FromString("<xmlrpc boolean false>"); |
| -} |
| - |
| - |
| -/* |
| - * represent a boolean xml object |
| - */ |
| -static PyObject * |
| -rpcBoolRepr(rpcBool *bp) |
| -{ |
| - if (bp->value) |
| - return PyString_FromString("boolean(1)"); |
| - else |
| - return PyString_FromString("boolean(0)"); |
| -} |
| - |
| - |
| -/* |
| - * map characterstics of a boolean |
| - */ |
| -PyTypeObject rpcBoolType = { |
| - PyObject_HEAD_INIT(0) |
| - 0, |
| - "rpcBoolean", |
| - sizeof(rpcBool), |
| - 0, |
| - (destructor)rpcBoolDealloc, /* tp_dealloc */ |
| - 0, /* tp_print */ |
| - 0, /* tp_getattr */ |
| - 0, /* tp_setattr */ |
| - (cmpfunc)rpcBoolCompare, /* tp_compare */ |
| - (reprfunc)rpcBoolRepr, /* tp_repr */ |
| - 0, /* tp_as_number */ |
| - 0, /* tp_as_sequence */ |
| - &rpcBoolAsMapping, /* tp_as_mapping */ |
| - 0, /* tp_hash */ |
| - 0, /* tp_call */ |
| - (reprfunc)rpcBoolStr, /* tp_str */ |
| - 0, /* tp_getattro */ |
| - 0, /* tp_setattro */ |
| - 0, /* tp_as_buffer */ |
| - 0, /* tp_xxx4 */ |
| - 0, /* tp_doc */ |
| -}; |
| --- src/rpcBoolean.h.orig 2008-10-15 10:46:52.000000000 +0300 |
| +++ src/rpcBoolean.h 2008-10-15 10:46:59.000000000 +0300 |
| @@ -6,26 +6,3 @@ |
| * |
| */ |
| |
| - |
| -#ifndef _RPCBOOL_H_ |
| -#define _RPCBOOL_H_ |
| - |
| - |
| -#include "rpcInclude.h" |
| -PyTypeObject rpcBoolType; |
| - |
| - |
| -/* |
| - * boolean object |
| - */ |
| -typedef struct { |
| - PyObject_HEAD /* python standard */ |
| - bool value; /* true/false value */ |
| -} rpcBool; |
| - |
| - |
| -PyObject *rpcBoolNew(bool value); |
| -bool rpcBoolValue(PyObject *obj); |
| - |
| - |
| -#endif /* _RPCBOOL_H_ */ |
| --- src/rpcUtils.c.orig 2003-04-21 18:39:15.000000000 +0300 |
| +++ src/rpcUtils.c 2008-10-15 10:45:01.000000000 +0300 |
| @@ -47,6 +47,7 @@ |
| |
| static strBuff *encodeValue(strBuff *sp, PyObject *value, uint tabs); |
| static strBuff *encodeBool(strBuff *sp, PyObject *value); |
| +static strBuff *encodeNone(strBuff *sp); |
| static strBuff *encodeInt(strBuff *sp, PyObject *value); |
| static strBuff *encodeDouble(strBuff *sp, PyObject *value); |
| static strBuff *encodeString(strBuff *sp, PyObject *value); |
| @@ -63,6 +64,7 @@ |
| static PyObject *decodeString(char **cp, char *ep, ulong *lines); |
| static PyObject *decodeTaglessString(char **cp, char *ep, ulong *lines); |
| static PyObject *decodeBool(char **cp, char *ep, ulong *lines); |
| +static PyObject *decodeNone(char **cp, char *ep, ulong *lines); |
| static PyObject *decodeBase64(char **cp, char *ep, ulong *lines); |
| static PyObject *decodeArray(char **cp, char *ep, ulong *lines); |
| static PyObject *decodeStruct(char **cp, char *ep, ulong *lines); |
| @@ -205,11 +207,13 @@ |
| { |
| if (buffConstant(sp, "<value>") == NULL) |
| return NULL; |
| - if (PyInt_Check(value) or PyLong_Check(value)) |
| + if (PyInt_CheckExact(value) or PyLong_Check(value)) |
| sp = encodeInt(sp, value); |
| + else if (value == Py_None) |
| + sp = encodeNone(sp); |
| else if (PyFloat_Check(value)) |
| sp = encodeDouble(sp, value); |
| - else if (value->ob_type == &rpcBoolType) |
| + else if (PyBool_Check(value)) |
| sp = encodeBool(sp, value); |
| else if (value->ob_type == &rpcDateType) |
| sp = encodeDate(sp, value); |
| @@ -286,12 +290,25 @@ |
| } |
| |
| /* |
| + * encode the None as: "<nil/>" |
| + */ |
| +static strBuff * |
| +encodeNone(strBuff *sp) |
| +{ |
| + if (buffConstant(sp, "<nil/>") == NULL) |
| + return NULL; |
| + |
| + return sp; |
| +} |
| + |
| +/* |
| +/* |
| * encode the boolean true (for example) as: "<boolean>1</boolean>" |
| */ |
| static strBuff * |
| encodeBool(strBuff *sp, PyObject *value) |
| { |
| - if (((rpcBool *)value)->value) |
| + if (value == Py_True) |
| return buffConstant(sp, "<boolean>1</boolean>"); |
| else |
| return buffConstant(sp, "<boolean>0</boolean>"); |
| @@ -569,6 +586,8 @@ |
| res = decodeDate(cp, ep, lines); |
| else if (strncmp(*cp, "<base64>", 8) == 0) |
| res = decodeBase64(cp, ep, lines); |
| + else if (strncmp(*cp, "<nil/>", 6) == 0) |
| + res = decodeNone(cp, ep, lines); |
| else { /* it must be a string */ |
| *cp = tp; |
| res = decodeTaglessString(cp, ep, lines); |
| @@ -619,6 +638,20 @@ |
| |
| |
| static PyObject * |
| +decodeNone(char **cp, char *ep, ulong *lines) |
| +{ |
| + if (*cp + 6 >= ep) |
| + return eosErr(); |
| + *cp += 6; |
| + if (chompStr(cp, ep, lines) >= ep) |
| + return eosErr(); |
| + |
| + Py_INCREF(Py_None); |
| + return Py_None; |
| +} |
| + |
| + |
| +static PyObject * |
| decodeBool(char **cp, char *ep, ulong *lines) |
| { |
| PyObject *res; |
| @@ -638,7 +671,12 @@ |
| if (chompStr(cp, ep, lines) >= ep) |
| return eosErr(); |
| |
| - return rpcBoolNew(value); |
| + if (value) { |
| + Py_INCREF(Py_True); |
| + return Py_True; |
| + } |
| + Py_INCREF(Py_False); |
| + return Py_False; |
| } |
| |
| |
| --- src/xmlrpc.c.orig 2003-04-21 18:39:15.000000000 +0300 |
| +++ src/xmlrpc.c 2008-10-15 10:47:23.000000000 +0300 |
| @@ -45,7 +45,6 @@ |
| rpcLogLevel = 3; |
| rpcLogger = stderr; |
| rpcDateFormat = XMLRPC_DATE_FORMAT_US; |
| - rpcBoolType.ob_type = &PyType_Type; |
| rpcDateType.ob_type = &PyType_Type; |
| rpcBase64Type.ob_type = &PyType_Type; |
| rpcClientType.ob_type = &PyType_Type; |
| --- src/xmlrpc.h.orig 2003-04-21 18:39:15.000000000 +0300 |
| +++ src/xmlrpc.h 2008-10-15 10:40:35.000000000 +0300 |
| @@ -45,7 +45,6 @@ |
| #define XMLRPC_DATE_FORMAT_EUROPE 2 |
| |
| #include "rpcBase64.h" |
| -#include "rpcBoolean.h" |
| #include "rpcClient.h" |
| #include "rpcDate.h" |
| #include "rpcDispatch.h" |
| --- src/xmlrpcmodule.c.orig 2003-04-21 19:22:54.000000000 +0300 |
| +++ src/xmlrpcmodule.c 2008-10-15 10:48:42.000000000 +0300 |
| @@ -197,7 +197,12 @@ |
| unless (PyArg_ParseTuple(args, "i", &value)) |
| return NULL; |
| |
| - return rpcBoolNew(value); |
| + if (value) { |
| + Py_INCREF(Py_True); |
| + return Py_True; |
| + } |
| + Py_INCREF(Py_False); |
| + return Py_False; |
| } |
| |
| |
| |
| |