summaryrefslogtreecommitdiff
path: root/python/libxml.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@redhat.com>2013-03-29 13:46:24 +0800
committerDaniel Veillard <veillard@redhat.com>2013-03-30 22:33:06 +0800
commit3798c4adbb91f80bef1e9f1b4b61dae72577a244 (patch)
treec50f98b148962a5bd08ff4250924ce2f5719aa43 /python/libxml.c
parentd8a75bffa4dc8e0e3d31c2f87f0f80212f19393c (diff)
downloadlibxml2-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.c193
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
}