diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2020-11-19 16:08:03 +0100 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2020-11-19 17:59:37 +0100 |
commit | b3076bccdb818caeea427d3e8fa6b148a77ae78a (patch) | |
tree | 9955f03533bd9cdb9663160c1911bc7f216deea5 | |
parent | a2db8da1ac30d744eaa38e574bad9841af1d9b5d (diff) | |
download | libxslt-b3076bccdb818caeea427d3e8fa6b148a77ae78a.tar.gz |
Finish and clean up Python 3 support
- Handle Python 3 types similar to libxml2
- Copy new versions of libxml_xmlXPathDestructNsNode and
libxml_xmlXPathObjectPtrConvert from libxml2
- Fix compiler warnings
- Fix whitespace
- Remove unneeded imports from __future__
- Remove test in extelem.py (StringIO can't be converted to FILE under
Python 3)
- string.lower() works in both Python 2 and 3
Closes #25.
-rw-r--r-- | configure.ac | 12 | ||||
-rwxr-xr-x | python/generator.py | 44 | ||||
-rw-r--r-- | python/libxml_wrap.h | 35 | ||||
-rw-r--r-- | python/libxslt.c | 42 | ||||
-rwxr-xr-x | python/tests/basic.py | 2 | ||||
-rwxr-xr-x | python/tests/exslt.py | 2 | ||||
-rw-r--r-- | python/tests/extelem.py | 19 | ||||
-rwxr-xr-x | python/tests/extfunc.py | 4 | ||||
-rwxr-xr-x | python/tests/pyxsltproc.py | 14 | ||||
-rw-r--r-- | python/types.c | 340 |
10 files changed, 230 insertions, 284 deletions
diff --git a/configure.ac b/configure.ac index a3dd27bb..cf17242b 100644 --- a/configure.ac +++ b/configure.ac @@ -204,7 +204,7 @@ dnl if test "${NEED_TRIO}" = "1" ; then echo Reusing trio library for string functions WITH_TRIO=1 -else +else WITH_TRIO=0 fi AC_SUBST(WITH_TRIO) @@ -405,7 +405,7 @@ AC_ARG_WITH(debug, [ --with-debug Add the debugging code (on)]) if test "$with_debug" = "no" ; then echo Disabling debug support WITH_XSLT_DEBUG=0 -else +else WITH_XSLT_DEBUG=1 fi AC_SUBST(WITH_XSLT_DEBUG) @@ -414,12 +414,12 @@ AC_ARG_WITH(mem_debug, [ --with-mem-debug Add the memory debugging modul if test "$with_mem_debug" = "yes" ; then echo Enabling memory debug support WITH_MEM_DEBUG=1 -else +else WITH_MEM_DEBUG=0 fi AC_SUBST(WITH_MEM_DEBUG) -dnl +dnl dnl Is debugger support requested dnl AC_ARG_WITH(debugger, [ --with-debugger Add the debugging support (on)]) @@ -463,7 +463,7 @@ AC_ARG_WITH(libxml-prefix, [ --with-libxml-prefix=[PFX] Specify location of libxml config], LIBXML_CONFIG_PREFIX=$withval ) - + AC_ARG_WITH(libxml-include-prefix, [ --with-libxml-include-prefix=[PFX] Specify location of libxml headers], LIBXML_CFLAGS="-I$withval" @@ -493,7 +493,7 @@ else fi dnl -dnl imported from libxml2, c.f. #77827 +dnl imported from libxml2, c.f. #77827 dnl if test "${GCC}" != "yes" ; then case "${host}" in diff --git a/python/generator.py b/python/generator.py index 62d7f784..df9fecec 100755 --- a/python/generator.py +++ b/python/generator.py @@ -2,15 +2,11 @@ # # generate python wrappers from the XML API description # -from __future__ import print_function functions = {} enums = {} # { enumType: { enumConstant: enumValue } } -import sys -if sys.version_info < (3, 0): - import string as re_str -else: - re_str=str + +import string ####################################################################### # @@ -461,7 +457,7 @@ def buildStubs(): failed, skipped)) print("Missing type converters:") for type in list(unknown_types.keys()): - print("%s:%d " % (type, len(unknown_types[type])), end=' ') + print("%s:%d " % (type, len(unknown_types[type]))) print() ####################################################################### @@ -537,55 +533,55 @@ def nameFixup(name, classe, type, file): l = len(classe) if name[0:l] == listname: func = name[l:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:12] == "xmlParserGet" and file == "python_accessor": func = name[12:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:12] == "xmlParserSet" and file == "python_accessor": func = name[12:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:10] == "xmlNodeGet" and file == "python_accessor": func = name[10:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:18] == "xsltXPathParserGet" and file == "python_accessor": func = name[18:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:12] == "xsltXPathGet" and file == "python_accessor": func = name[12:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:16] == "xsltTransformGet" and file == "python_accessor": func = name[16:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:16] == "xsltTransformSet" and file == "python_accessor": func = name[13:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:17] == "xsltStylesheetGet" and file == "python_accessor": func = name[17:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:17] == "xsltStylesheetSet" and file == "python_accessor": func = name[14:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:l] == classe: func = name[l:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:7] == "libxml_": func = name[7:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:8] == "libxslt_": func = name[8:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:6] == "xmlGet": func = name[6:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:3] == "xml": func = name[3:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:7] == "xsltGet": func = name[7:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:4] == "xslt": func = name[4:] - func = re_str.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] else: func = name if func[0:5] == "xPath": diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h index eb8c5753..6d8e1dee 100644 --- a/python/libxml_wrap.h +++ b/python/libxml_wrap.h @@ -15,15 +15,24 @@ #include <libxml/xinclude.h> #include <libxml/xpointer.h> -PyObject* PY_IMPORT_INT(long ival); -PyObject* PY_IMPORT_STRING(const char *u); -PyObject* PY_IMPORT_CPTRD(void *po, const char *na, void *de); -int PY_IMPORT_LONG_CHECK(PyObject *o); -int PY_IMPORT_STRING_CHECK(PyObject *o); -int PY_IMPORT_CPTR_CHECK(PyObject *o); -Py_ssize_t PY_IMPORT_STRING_GET_SIZE(PyObject *o); -char* PY_IMPORT_AS_STRING(PyObject *o); -long PY_IMPORT_AS_LONG(PyObject *io); +/* + * for older versions of Python, we don't use PyBytes, but keep PyString + * and don't use Capsule but CObjects + */ +#if PY_VERSION_HEX < 0x02070000 +#ifndef PyBytes_Check +#define PyBytes_Check PyString_Check +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_GET_SIZE PyString_GET_SIZE +#endif +#ifndef PyCapsule_New +#define PyCapsule_New PyCObject_FromVoidPtrAndDesc +#define PyCapsule_CheckExact PyCObject_Check +#define PyCapsule_GetPointer(o, n) PyCObject_GetDesc((o)) +#endif +#endif #define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \ (((PyxmlNode_Object *)(v))->obj)) @@ -65,8 +74,16 @@ typedef struct { xmlCatalogPtr obj; } Pycatalog_Object; +#if PY_MAJOR_VERSION >= 3 +FILE *libxml_PyFileGet(PyObject *f); +void libxml_PyFileRelease(FILE *f); +#define PyFile_Get(v) (((v) == Py_None) ? NULL : libxml_PyFileGet(v)) +#define PyFile_Release(f) libxml_PyFileRelease(f) +#else #define PyFile_Get(v) (((v) == Py_None) ? NULL : \ (PyFile_Check(v) ? (PyFile_AsFile(v)) : stdout)) +#define PyFile_Release(f) +#endif PyObject * libxml_intWrap(int val); PyObject * libxml_longWrap(long val); diff --git a/python/libxslt.c b/python/libxslt.c index a174fafe..685e49d1 100644 --- a/python/libxslt.c +++ b/python/libxslt.c @@ -28,7 +28,6 @@ /* snprintf emulation taken from http://stackoverflow.com/a/8712996/1956010 */ #if _MSC_VER < 1900 - #include <stdarg.h> #define vsnprintf c99_vsnprintf @@ -78,8 +77,8 @@ libxslt_xsltStylesheetPtrWrap(xsltStylesheetPtr style) { Py_INCREF(Py_None); return(Py_None); } - ret = PY_IMPORT_CPTRD((void *) style, - (char *)"xsltStylesheetPtr", NULL); + ret = PyCapsule_New((void *) style, (char *)"xsltStylesheetPtr", NULL); + return(ret); } @@ -94,9 +93,8 @@ libxslt_xsltTransformContextPtrWrap(xsltTransformContextPtr ctxt) { Py_INCREF(Py_None); return(Py_None); } - ret = PY_IMPORT_CPTRD((void *) ctxt, - (char *)"xsltTransformContextPtr", NULL); - + ret = PyCapsule_New((void *) ctxt, (char *)"xsltTransformContextPtr", + NULL); return(ret); } @@ -111,8 +109,7 @@ libxslt_xsltElemPreCompPtrWrap(xsltElemPreCompPtr ctxt) { Py_INCREF(Py_None); return(Py_None); } - ret = PY_IMPORT_CPTRD((void *) ctxt, - (char *)"xsltElemPreCompPtr", NULL); + ret = PyCapsule_New((void *) ctxt, (char *)"xsltElemPreCompPtr", NULL); return(ret); } @@ -129,7 +126,8 @@ libxslt_xsltGetTransformContextHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObjec tctxt = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt); hash_code = (ptrdiff_t) tctxt; - ret = PY_IMPORT_INT(hash_code); + + ret = PyLong_FromLong(hash_code); return ret; } @@ -166,8 +164,7 @@ libxslt_xsltGetStylesheetHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg style = (xsltStylesheetPtr) Pystylesheet_Get(py_style); hash_code = (ptrdiff_t) style; - ret = PY_IMPORT_INT(hash_code); - + ret = PyLong_FromLong(hash_code); return ret; } @@ -621,8 +618,7 @@ libxslt_xsltSetLoaderFunc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { pythonDocLoaderObject = loader; xsltSetLoaderFunc(pythonDocLoaderFuncWrapper); - py_retval = PY_IMPORT_INT(0); - + py_retval = PyLong_FromLong(0); return(py_retval); } @@ -713,11 +709,13 @@ libxslt_xsltApplyStylesheetUser(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) j = 0; while (PyDict_Next(pyobj_params, &ppos, &name, &value)) { const char *tmp; - int size; #if PY_MAJOR_VERSION >= 3 + Py_ssize_t size; + tmp = PyUnicode_AsUTF8AndSize(name, &size); #else + int size; tmp = PyString_AS_STRING(name); size = PyString_GET_SIZE(name); @@ -800,11 +798,13 @@ libxslt_xsltApplyStylesheet(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { j = 0; while (PyDict_Next(pyobj_params, &ppos, &name, &value)) { const char *tmp; - int size; - #if PY_MAJOR_VERSION >= 3 + Py_ssize_t size; + tmp = PyUnicode_AsUTF8AndSize(name, &size); #else + int size; + tmp = PyString_AS_STRING(name); size = PyString_GET_SIZE(name); #endif @@ -1236,6 +1236,8 @@ extern void initlibxml2mod(void); #endif #if PY_MAJOR_VERSION >= 3 +#define INITERROR return NULL + static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "libxsltmod", @@ -1247,6 +1249,8 @@ static struct PyModuleDef moduledef = { NULL, NULL }; +#else +#define INITERROR return #endif #if PY_MAJOR_VERSION >= 3 @@ -1254,7 +1258,6 @@ PyObject* PyInit_libxsltmod(void){ #else void initlibxsltmod(void) { #endif - static int initialized = 0; PyObject *m; #ifdef MERGED_MODULES @@ -1265,16 +1268,13 @@ void initlibxsltmod(void) { #endif #endif - if (initialized != 0) - return; #if PY_MAJOR_VERSION >= 3 m = PyModule_Create(&moduledef); #else m = Py_InitModule((char *)"libxsltmod", libxsltMethods); #endif if (!m) - return; - initialized = 1; + INITERROR; /* * Specific XSLT initializations */ diff --git a/python/tests/basic.py b/python/tests/basic.py index 56cdf145..7d9f9867 100755 --- a/python/tests/basic.py +++ b/python/tests/basic.py @@ -1,6 +1,4 @@ #!/usr/bin/python -u -from __future__ import print_function - import sys import libxml2 # Memory debug specific diff --git a/python/tests/exslt.py b/python/tests/exslt.py index 1368fff2..de5e42bf 100755 --- a/python/tests/exslt.py +++ b/python/tests/exslt.py @@ -1,6 +1,4 @@ #!/usr/bin/python -u -from __future__ import print_function - import sys import libxml2 # Memory debug specific diff --git a/python/tests/extelem.py b/python/tests/extelem.py index 2f3e047a..0e1bf4bf 100644 --- a/python/tests/extelem.py +++ b/python/tests/extelem.py @@ -1,15 +1,6 @@ #!/usr/bin/python -u -from __future__ import print_function - import sys import string -import sys - -if sys.version_info < (3, 0): - import StringIO as io -else: - import io - import libxml2 # Memory debug specific libxml2.debugMemory(1) @@ -42,7 +33,7 @@ def transform_test(ctx, node, inst, comp): pass tctxt.insertNode().addContent('SUCCESS') - + styledoc = libxml2.parseDoc(""" @@ -65,14 +56,6 @@ result = style.applyStylesheet(doc, None) style.freeStylesheet() doc.freeDoc() - -extensions = io.StringIO() -libxslt.debugDumpExtensions(extensions) - -if 0 and extensions.buf.find(EXT_URL) < 0: - print("Element extension not registered (or dumping broken)") - sys.exit(1) - root = result.children if root.name != "article": diff --git a/python/tests/extfunc.py b/python/tests/extfunc.py index 2bb6bea2..a775494a 100755 --- a/python/tests/extfunc.py +++ b/python/tests/extfunc.py @@ -1,6 +1,4 @@ #!/usr/bin/python -u -from __future__ import print_function - import sys import string import libxml2 @@ -24,7 +22,7 @@ def f(ctx, str): except: pass - return string.upper(str) + return str.upper() libxslt.registerExtModuleFunction("foo", "http://example.com/foo", f) diff --git a/python/tests/pyxsltproc.py b/python/tests/pyxsltproc.py index d9871cc0..4fadfc73 100755 --- a/python/tests/pyxsltproc.py +++ b/python/tests/pyxsltproc.py @@ -4,8 +4,6 @@ # bindings, not complete yet and shows up the things missing # from the existing python interfaces # -from __future__ import print_function - import sys import time import os @@ -150,7 +148,7 @@ def main(args = None): args = sys.argv[1:] if len(args) <= 0: usage(sys.argv[0]) - + i = 0 while i < len(args): @@ -211,12 +209,12 @@ def main(args = None): print("Unknown option %s" % (args[i])) usage() return(3) - - - - + + + + i = i + 1 - + libxml2.lineNumbersDefault(1) libxml2.substituteEntitiesDefault(1) # TODO: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS diff --git a/python/types.c b/python/types.c index d076a2bb..583b2929 100644 --- a/python/types.c +++ b/python/types.c @@ -13,101 +13,80 @@ xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL, #include "libxml_wrap.h" #include <libxml/xpathInternals.h> -/* Helper functions */ - -PyObject* PY_IMPORT_INT(long ival){ - PyObject *ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyLong_FromLong(ival); - #else - ret=PyInt_FromLong(ival); - #endif - return ret; -} - -PyObject* PY_IMPORT_STRING(const char *u){ - PyObject *ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyUnicode_FromString(u); - #else - ret=PyString_FromString(u); - #endif - return ret; -} - -PyObject* PY_IMPORT_CPTRD(void *po, - const char *na, - void *de){ - PyObject *ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyCapsule_New(po,na,de); - #else - ret=PyCObject_FromVoidPtrAndDesc(po,(void *)na,de); - #endif - return ret; -} - -int PY_IMPORT_LONG_CHECK(PyObject *o){ - int ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyLong_Check(o); - #else - ret=PyInt_Check(o); - #endif - return ret; -} - -int PY_IMPORT_STRING_CHECK(PyObject *o){ - int ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyUnicode_Check(o); - #else - ret=PyString_Check(o); - #endif - return ret; -} - -int PY_IMPORT_CPTR_CHECK(PyObject *o){ - int ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyCapsule_CheckExact(o); - #else - ret=PyCObject_Check(o); - #endif - return ret; -} +#if PY_MAJOR_VERSION >= 3 +#define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize +#define PY_IMPORT_STRING PyUnicode_FromString +#define PY_IMPORT_INT PyLong_FromLong +#else +#define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize +#define PY_IMPORT_STRING PyString_FromString +#define PY_IMPORT_INT PyInt_FromLong +#endif -Py_ssize_t PY_IMPORT_STRING_GET_SIZE(PyObject *o){ - Py_ssize_t ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyUnicode_GET_SIZE(o); - #else - ret=PyString_GET_SIZE(o); - #endif - return ret; -} +#if PY_MAJOR_VERSION >= 3 +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> + +FILE * +libxml_PyFileGet(PyObject *f) { + int fd, flags; + FILE *res; + const char *mode; + + fd = PyObject_AsFileDescriptor(f); + /* + * Get the flags on the fd to understand how it was opened + */ + flags = fcntl(fd, F_GETFL, 0); + switch (flags & O_ACCMODE) { + case O_RDWR: + if (flags & O_APPEND) + mode = "a+"; + else + mode = "rw"; + break; + case O_RDONLY: + if (flags & O_APPEND) + mode = "r+"; + else + mode = "r"; + break; + case O_WRONLY: + if (flags & O_APPEND) + mode = "a"; + else + mode = "w"; + break; + default: + return(NULL); + } -char* PY_IMPORT_AS_STRING(PyObject *o){ - char *ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyUnicode_AS_DATA(o); - #else - ret=PyString_AS_STRING(o); - #endif - return ret; + /* + * the FILE struct gets a new fd, so that it can be closed + * independently of the file descriptor given. The risk though is + * lack of sync. So at the python level sync must be implemented + * before and after a conversion took place. No way around it + * in the Python3 infrastructure ! + * The duplicated fd and FILE * will be released in the subsequent + * call to libxml_PyFileRelease() which must be generated accordingly + */ + fd = dup(fd); + if (fd == -1) + return(NULL); + res = fdopen(fd, mode); + if (res == NULL) { + close(fd); + return(NULL); + } + return(res); } -long PY_IMPORT_AS_LONG(PyObject *io){ - long ret; - #if PY_MAJOR_VERSION >= 3 - ret=PyLong_AS_LONG(io); - #else - ret=PyInt_AS_LONG(io); - #endif - return ret; +void libxml_PyFileRelease(FILE *f) { + if (f != NULL) + fclose(f); } - -/* */ +#endif PyObject * libxml_intWrap(int val) @@ -129,9 +108,7 @@ libxml_longWrap(long val) #ifdef DEBUG printf("libxml_longWrap: val = %ld\n", val); #endif - ret = PY_IMPORT_INT(val); - return (ret); } @@ -177,6 +154,7 @@ libxml_charPtrConstWrap(const char *str) Py_INCREF(Py_None); return (Py_None); } + /* TODO: look at deallocation */ ret = PY_IMPORT_STRING(str); return (ret); } @@ -229,7 +207,7 @@ libxml_constcharPtrWrap(const char *str) return (Py_None); } /* TODO: look at deallocation */ - ret = PY_IMPORT_STRING((char *) str); + ret = PY_IMPORT_STRING(str); return (ret); } @@ -263,8 +241,7 @@ libxml_xmlDocPtrWrap(xmlDocPtr doc) return (Py_None); } /* TODO: look at deallocation */ - ret = PY_IMPORT_CPTRD((void *) doc, (char *) "xmlDocPtr", - NULL); + ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL); return (ret); } @@ -280,10 +257,7 @@ libxml_xmlNodePtrWrap(xmlNodePtr node) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) node, (char *) "xmlNodePtr", - NULL); - + ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL); return (ret); } @@ -299,10 +273,7 @@ libxml_xmlURIPtrWrap(xmlURIPtr uri) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) uri, (char *) "xmlURIPtr", - NULL); - + ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL); return (ret); } @@ -318,9 +289,7 @@ libxml_xmlNsPtrWrap(xmlNsPtr ns) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) ns, (char *) "xmlNsPtr", - NULL); + ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL); return (ret); } @@ -336,10 +305,7 @@ libxml_xmlAttrPtrWrap(xmlAttrPtr attr) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) attr, (char *) "xmlAttrPtr", - NULL); - + ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL); return (ret); } @@ -355,10 +321,7 @@ libxml_xmlAttributePtrWrap(xmlAttributePtr attr) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) attr, - (char *) "xmlAttributePtr", NULL); - + ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL); return (ret); } @@ -374,9 +337,7 @@ libxml_xmlElementPtrWrap(xmlElementPtr elem) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) elem, - (char *) "xmlElementPtr", NULL); + ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL); return (ret); } @@ -392,11 +353,7 @@ libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) Py_INCREF(Py_None); return (Py_None); } - - ret = - PY_IMPORT_CPTRD((void *) ctxt, - (char *) "xmlXPathContextPtr", NULL); - + ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL); return (ret); } @@ -412,9 +369,8 @@ libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt) Py_INCREF(Py_None); return (Py_None); } - ret = PY_IMPORT_CPTRD((void *) ctxt, - (char *) "xmlXPathParserContextPtr", - NULL); + ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathParserContextPtr", + NULL); return (ret); } @@ -430,9 +386,7 @@ libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) ctxt, - (char *) "xmlParserCtxtPtr", NULL); + ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL); return (ret); } @@ -446,12 +400,22 @@ libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt) * object returned in node set not directly linked to the original * xmlDoc document, see xmlXPathNodeSetDupNs. */ +#if PY_VERSION_HEX < 0x02070000 static void -libxml_xmlXPathDestructNsNode(void *cobj, void *desc ATTRIBUTE_UNUSED) { +libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED) +#else +static void +libxml_xmlXPathDestructNsNode(PyObject *cap) +#endif +{ #ifdef DEBUG fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cobj); #endif - xmlXPathNodeSetFreeNs((xmlNsPtr) cobj); +#if PY_VERSION_HEX < 0x02070000 + xmlXPathNodeSetFreeNs((xmlNsPtr) cap); +#else + xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr")); +#endif } PyObject * @@ -506,9 +470,9 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) node = obj->nodesetval->nodeTab[i]; if (node->type == XML_NAMESPACE_DECL) { PyObject *ns = - PY_IMPORT_CPTRD((void *) node, + PyCapsule_New((void *) node, (char *) "xmlNsPtr", - libxml_xmlXPathDestructNsNode); + libxml_xmlXPathDestructNsNode); PyList_SetItem(ret, i, ns); /* make sure the xmlNsPtr is not destroyed now */ obj->nodesetval->nodeTab[i] = NULL; @@ -542,7 +506,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) } xmlXPathObjectPtr -libxml_xmlXPathObjectPtrConvert(PyObject * obj) +libxml_xmlXPathObjectPtrConvert(PyObject *obj) { xmlXPathObjectPtr ret = NULL; @@ -552,11 +516,15 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) if (obj == NULL) { return (NULL); } - if PyFloat_Check - (obj) { + if (PyFloat_Check (obj)) { ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj)); - } else if (PY_IMPORT_LONG_CHECK (obj)) { - ret = xmlXPathNewFloat((double) PY_IMPORT_AS_LONG(obj)); + } else if (PyLong_Check(obj)) { +#ifdef PyLong_AS_LONG + ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj)); +#else + ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj)); +#endif +#ifdef PyBool_Check } else if (PyBool_Check (obj)) { if (obj == Py_True) { @@ -565,13 +533,38 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) else { ret = xmlXPathNewBoolean(0); } - } else if (PY_IMPORT_STRING_CHECK(obj)) { +#endif + } else if (PyBytes_Check (obj)) { xmlChar *str; - str = xmlStrndup((const xmlChar *) PY_IMPORT_AS_STRING(obj), - PY_IMPORT_STRING_GET_SIZE(obj)); + str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj), + PyBytes_GET_SIZE(obj)); ret = xmlXPathWrapString(str); - } else if (PyList_Check(obj)) { +#ifdef PyUnicode_Check + } else if (PyUnicode_Check (obj)) { +#if PY_VERSION_HEX >= 0x03030000 + xmlChar *str; + const char *tmp; + Py_ssize_t size; + + /* tmp doesn't need to be deallocated */ + tmp = PyUnicode_AsUTF8AndSize(obj, &size); + str = xmlStrndup((const xmlChar *) tmp, (int) size); + ret = xmlXPathWrapString(str); +#else + xmlChar *str = NULL; + PyObject *b; + + b = PyUnicode_AsUTF8String(obj); + if (b != NULL) { + str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b), + PyBytes_GET_SIZE(b)); + Py_DECREF(b); + } + ret = xmlXPathWrapString(str); +#endif +#endif + } else if (PyList_Check (obj)) { int i; PyObject *node; xmlNodePtr cur; @@ -585,43 +578,19 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) continue; cur = NULL; - if (PY_IMPORT_CPTR_CHECK(node)) { + if (PyCapsule_CheckExact(node)) { #ifdef DEBUG - printf("Got a CObject\n"); + printf("Got a Capsule\n"); #endif cur = PyxmlNode_Get(node); - } -#if PY_MAJOR_VERSION >= 3 - else if ((PyObject_HasAttrString(node, (char *) "_o")) && - (PyObject_HasAttrString(node, (char *) "get_doc"))) { - PyObject *wrapper; - - wrapper = PyObject_GetAttrString(node, (char *) "_o"); - if (wrapper != NULL) - cur = PyxmlNode_Get(wrapper); - } -#else - else if (PyInstance_Check(node)) { - PyInstanceObject *inst = (PyInstanceObject *) node; - PyObject *name = inst->in_class->cl_name; - - if PyString_Check - (name) { - - char *type = PyString_AS_STRING(name); - PyObject *wrapper; - - if (!strcmp(type, "xmlNode")) { - wrapper = - PyObject_GetAttrString(node, (char *) "_o"); - if (wrapper != NULL) { - cur = PyxmlNode_Get(wrapper); - } - } - } - } -#endif - else { + } else if ((PyObject_HasAttrString(node, (char *) "_o")) && + (PyObject_HasAttrString(node, (char *) "get_doc"))) { + PyObject *wrapper; + + wrapper = PyObject_GetAttrString(node, (char *) "_o"); + if (wrapper != NULL) + cur = PyxmlNode_Get(wrapper); + } else { #ifdef DEBUG printf("Unknown object in Python return list\n"); #endif @@ -636,7 +605,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) printf("Unable to convert Python Object to XPath"); #endif } - Py_DECREF(obj); return (ret); } @@ -652,9 +620,7 @@ libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) catal, - (char *) "xmlCatalogPtr", NULL); + ret = PyCapsule_New((void *) catal, (char *) "xmlCatalogPtr", NULL); return (ret); } @@ -670,10 +636,7 @@ libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) buffer, - (char *) "xmlOutputBufferPtr", NULL); - + ret = PyCapsule_New((void *) buffer, (char *) "xmlOutputBufferPtr", NULL); return (ret); } @@ -689,10 +652,8 @@ libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) buffer, - (char *) "xmlParserInputBufferPtr", NULL); - + ret = PyCapsule_New((void *) buffer, (char *) "xmlParserInputBufferPtr", + NULL); return (ret); } @@ -708,9 +669,6 @@ libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp) Py_INCREF(Py_None); return (Py_None); } - ret = - PY_IMPORT_CPTRD((void *) regexp, - (char *) "xmlRegexpPtr", NULL); - + ret = PyCapsule_New((void *) regexp, (char *) "xmlRegexpPtr", NULL); return (ret); } |