diff options
author | Daniel Veillard <veillard@redhat.com> | 2013-03-29 13:46:24 +0800 |
---|---|---|
committer | Daniel Veillard <veillard@redhat.com> | 2013-03-30 22:33:06 +0800 |
commit | 3798c4adbb91f80bef1e9f1b4b61dae72577a244 (patch) | |
tree | c50f98b148962a5bd08ff4250924ce2f5719aa43 /python/libxml.c | |
parent | d8a75bffa4dc8e0e3d31c2f87f0f80212f19393c (diff) | |
download | libxml2-3798c4adbb91f80bef1e9f1b4b61dae72577a244.tar.gz |
Fix compilation on Python3
while still compiling on recent Python2:
- change the handling of files, tweak the generator, get the fd
instead of the FILE *, dup it and fdopen based on mode, add a
Release function on Python3 and call to flush from the generated
python stubs
- switch to using Capsules instead of CObjects
- fix PyString to PyBytes
- fix PyInt to PyLong
- tweak the module registration to compile on both versions
- drop PyInstance check for passed xmlNodes and instead check
attributes presence
Daniel
Diffstat (limited to 'python/libxml.c')
-rw-r--r-- | python/libxml.c | 193 |
1 files changed, 140 insertions, 53 deletions
diff --git a/python/libxml.c b/python/libxml.c index 8bb3db27..03cfb9fc 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -41,7 +41,17 @@ /* #define DEBUG_FILES */ /* #define DEBUG_LOADER */ +#if PY_MAJOR_VERSION >= 3 +PyObject *PyInit_libxml2mod(void); + +#define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize +#define PY_IMPORT_STRING PyUnicode_FromString +#else void initlibxml2mod(void); +#define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize +#define PY_IMPORT_STRING PyString_FromString +#endif + /** * TODO: @@ -280,18 +290,42 @@ xmlPythonFileReadRaw (void * context, char * buffer, int len) { if (ret == NULL) { printf("xmlPythonFileReadRaw: result is NULL\n"); return(-1); - } else if (PyString_Check(ret)) { - lenread = PyString_Size(ret); - data = PyString_AsString(ret); - if (lenread > len) - memcpy(buffer, data, len); - else - memcpy(buffer, data, lenread); - Py_DECREF(ret); + } else if (PyBytes_Check(ret)) { + lenread = PyBytes_Size(ret); + data = PyBytes_AsString(ret); +#ifdef PyUnicode_Check + } else if PyUnicode_Check (ret) { +#if PY_VERSION_HEX >= 0x03030000 + size_t size; + const char *tmp; + + /* tmp doesn't need to be deallocated */ + tmp = PyUnicode_AsUTF8AndSize(ret, &size); + + lenread = (int) size; + data = (char *) tmp; +#else + PyObject *b; + b = PyUnicode_AsUTF8String(ret); + if (b == NULL) { + printf("xmlPythonFileReadRaw: failed to convert to UTF-8\n"); + return(-1); + } + lenread = PyBytes_Size(b); + data = PyBytes_AsString(b); + Py_DECREF(b); +#endif +#endif } else { printf("xmlPythonFileReadRaw: result is not a String\n"); Py_DECREF(ret); + return(-1); } + if (lenread > len) + memcpy(buffer, data, len); + else + memcpy(buffer, data, lenread); + Py_DECREF(ret); return(lenread); } @@ -321,18 +355,42 @@ xmlPythonFileRead (void * context, char * buffer, int len) { if (ret == NULL) { printf("xmlPythonFileRead: result is NULL\n"); return(-1); - } else if (PyString_Check(ret)) { - lenread = PyString_Size(ret); - data = PyString_AsString(ret); - if (lenread > len) - memcpy(buffer, data, len); - else - memcpy(buffer, data, lenread); - Py_DECREF(ret); + } else if (PyBytes_Check(ret)) { + lenread = PyBytes_Size(ret); + data = PyBytes_AsString(ret); +#ifdef PyUnicode_Check + } else if PyUnicode_Check (ret) { +#if PY_VERSION_HEX >= 0x03030000 + size_t size; + const char *tmp; + + /* tmp doesn't need to be deallocated */ + tmp = PyUnicode_AsUTF8AndSize(ret, &size); + + lenread = (int) size; + data = (char *) tmp; +#else + PyObject *b; + b = PyUnicode_AsUTF8String(ret); + if (b == NULL) { + printf("xmlPythonFileRead: failed to convert to UTF-8\n"); + return(-1); + } + lenread = PyBytes_Size(b); + data = PyBytes_AsString(b); + Py_DECREF(b); +#endif +#endif } else { printf("xmlPythonFileRead: result is not a String\n"); Py_DECREF(ret); + return(-1); } + if (lenread > len) + memcpy(buffer, data, len); + else + memcpy(buffer, data, lenread); + Py_DECREF(ret); return(lenread); } @@ -358,7 +416,7 @@ xmlPythonFileWrite (void * context, const char * buffer, int len) { #endif file = (PyObject *) context; if (file == NULL) return(-1); - string = PyString_FromStringAndSize(buffer, len); + string = PY_IMPORT_STRING_SIZE(buffer, len); if (string == NULL) return(-1); if (PyObject_HasAttrString(file, (char *) "io_write")) { ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", @@ -371,8 +429,8 @@ xmlPythonFileWrite (void * context, const char * buffer, int len) { if (ret == NULL) { printf("xmlPythonFileWrite: result is NULL\n"); return(-1); - } else if (PyInt_Check(ret)) { - written = (int) PyInt_AsLong(ret); + } else if (PyLong_Check(ret)) { + written = (int) PyLong_AsLong(ret); Py_DECREF(ret); } else if (ret == Py_None) { written = len; @@ -727,7 +785,7 @@ libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { Py_XINCREF(pythonExternalEntityLoaderObjext); xmlSetExternalEntityLoader(pythonExternalEntityLoader); - py_retval = PyInt_FromLong(0); + py_retval = PyLong_FromLong(0); return(py_retval); } @@ -859,10 +917,10 @@ pythonStartElement(void *user_data, const xmlChar * name, } else { dict = PyDict_New(); for (i = 0; attrs[i] != NULL; i++) { - attrname = PyString_FromString((char *) attrs[i]); + attrname = PY_IMPORT_STRING((char *) attrs[i]); i++; if (attrs[i] != NULL) { - attrvalue = PyString_FromString((char *) attrs[i]); + attrvalue = PY_IMPORT_STRING((char *) attrs[i]); } else { Py_XINCREF(Py_None); attrvalue = Py_None; @@ -1265,7 +1323,7 @@ pythonAttributeDecl(void *user_data, nameList = PyList_New(count); count = 0; for (node = tree; node != NULL; node = node->next) { - newName = PyString_FromString((char *) node->name); + newName = PY_IMPORT_STRING((char *) node->name); PyList_SetItem(nameList, count, newName); Py_DECREF(newName); count++; @@ -2128,7 +2186,7 @@ libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader)) return(NULL); - if (!PyCObject_Check(pyobj_reader)) { + if (!PyCapsule_CheckExact(pyobj_reader)) { Py_INCREF(Py_None); return(Py_None); } @@ -2687,6 +2745,10 @@ libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) if (!PyArg_ParseTuple(args, (char *) "O:last", &obj)) return NULL; cur = PyxmlNode_Get(obj); + if (cur == NULL) { + Py_INCREF(Py_None); + return (Py_None); + } #ifdef DEBUG printf("libxml_type: cur = %p\n", cur); @@ -2803,7 +2865,7 @@ libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) PyObject *pyobj_node; xmlChar *href; xmlNsPtr c_retval; - + if (!PyArg_ParseTuple (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href)) return (NULL); @@ -2965,16 +3027,12 @@ libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) &py_file, &encoding, &format)) return (NULL); node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); - if (node == NULL) { - return (PyInt_FromLong((long) -1)); + return (PyLong_FromLong((long) -1)); } - if ((py_file == NULL) || (!(PyFile_Check(py_file)))) { - return (PyInt_FromLong((long) -1)); - } - output = PyFile_AsFile(py_file); + output = PyFile_Get(py_file); if (output == NULL) { - return (PyInt_FromLong((long) -1)); + return (PyLong_FromLong((long) -1)); } if (node->type == XML_DOCUMENT_NODE) { @@ -2993,7 +3051,7 @@ libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) if (encoding != NULL) { handler = xmlFindCharEncodingHandler(encoding); if (handler == NULL) { - return (PyInt_FromLong((long) -1)); + return (PyLong_FromLong((long) -1)); } } if (doc->type == XML_HTML_DOCUMENT_NODE) { @@ -3018,7 +3076,8 @@ libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) xmlNodeDumpOutput(buf, doc, node, 0, format, encoding); len = xmlOutputBufferClose(buf); } - return (PyInt_FromLong((long) len)); + PyFile_Release(output); + return (PyLong_FromLong((long) len)); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -3524,7 +3583,7 @@ PystringSet_Convert(PyObject *py_strings, xmlChar *** result) { int idx; for (idx=0; idx < count; ++idx) { - char* s = PyString_AsString + char* s = PyBytes_AsString (is_tuple ? PyTuple_GET_ITEM(py_strings, idx) : PyList_GET_ITEM(py_strings, idx)); @@ -3613,8 +3672,8 @@ libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self, return NULL; } else { - py_retval = PyString_FromStringAndSize((const char *) doc_txt, - result); + py_retval = PY_IMPORT_STRING_SIZE((const char *) doc_txt, + result); xmlFree(doc_txt); return py_retval; } @@ -3655,11 +3714,7 @@ libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, return NULL; } - if ((py_file == NULL) || (!(PyFile_Check(py_file)))) { - PyErr_SetString(PyExc_TypeError, "bad file."); - return NULL; - } - output = PyFile_AsFile(py_file); + output = PyFile_Get(py_file); if (output == NULL) { PyErr_SetString(PyExc_TypeError, "bad file."); return NULL; @@ -3697,6 +3752,7 @@ libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, xmlFree(prefixes); } + PyFile_Release(output); len = xmlOutputBufferClose(buf); if (result < 0) { @@ -3705,7 +3761,7 @@ libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, return NULL; } else - return PyInt_FromLong((long) len); + return PyLong_FromLong((long) len); } #endif @@ -3719,7 +3775,7 @@ libxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj)) return NULL; - str = PyCObject_GetDesc(obj); + str = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj)); return Py_BuildValue((char *)"s", str); } @@ -3819,28 +3875,59 @@ static PyMethodDef libxmlMethods[] = { {NULL, NULL, 0, NULL} }; +#if PY_MAJOR_VERSION >= 3 +#define INITERROR return NULL + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "libxml2mod", + NULL, + -1, + libxmlMethods, + NULL, + NULL, + NULL, + NULL +}; + +#else +#define INITERROR return + #ifdef MERGED_MODULES extern void initlibxsltmod(void); #endif -void -initlibxml2mod(void) -{ - static int initialized = 0; +#endif - if (initialized != 0) - return; +#if PY_MAJOR_VERSION >= 3 +PyObject *PyInit_libxml2mod(void) +#else +void initlibxml2mod(void) +#endif +{ + PyObject *module; +#if PY_MAJOR_VERSION >= 3 + module = PyModule_Create(&moduledef); +#else /* intialize the python extension module */ - Py_InitModule((char *) "libxml2mod", libxmlMethods); + module = Py_InitModule((char *) "libxml2mod", libxmlMethods); +#endif + if (module == NULL) + INITERROR; /* initialize libxml2 */ xmlInitParser(); + /* TODO this probably need to be revamped for Python3 */ libxml_xmlErrorInitialize(); - initialized = 1; - +#if PY_MAJOR_VERSION < 3 #ifdef MERGED_MODULES initlibxsltmod(); #endif +#endif + +#if PY_MAJOR_VERSION >= 3 + return module; +#endif } |