diff options
Diffstat (limited to 'python')
65 files changed, 1682 insertions, 911 deletions
diff --git a/python/Makefile.am b/python/Makefile.am index 4a8b5d5..34aed96 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -24,8 +24,8 @@ AM_CPPFLAGS = \ python_LTLIBRARIES = libxml2mod.la libxml2mod_la_SOURCES = libxml.c libxml_wrap.h libxml2-py.h libxml2-py.c types.c -libxml2mod_la_LIBADD = $(top_builddir)/libxml2.la $(CYGWIN_EXTRA_PYTHON_LIBADD) $(WIN32_EXTRA_PYTHON_LIBADD) $(PYTHON_LIBS) -lpython$(PYTHON_VERSION) -libxml2mod_la_LDFLAGS = $(CYGWIN_EXTRA_LDFLAGS) $(WIN32_EXTRA_LDFLAGS) -module -avoid-version +libxml2mod_la_LDFLAGS = $(CYGWIN_EXTRA_LDFLAGS) $(WIN32_EXTRA_LDFLAGS) -module -avoid-version \ + $(top_builddir)/libxml2.la $(CYGWIN_EXTRA_PYTHON_LIBADD) $(WIN32_EXTRA_PYTHON_LIBADD) $(PYTHON_LIBS) BUILT_SOURCES = libxml2-export.c libxml2-py.h libxml2-py.c diff --git a/python/Makefile.in b/python/Makefile.in index 9f1a044..efdea43 100644 --- a/python/Makefile.in +++ b/python/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -17,6 +17,23 @@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -80,11 +97,7 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pythondir)" "$(DESTDIR)$(docsdir)" \ "$(DESTDIR)$(pythondir)" LTLIBRARIES = $(python_LTLIBRARIES) -am__DEPENDENCIES_1 = -@WITH_PYTHON_TRUE@libxml2mod_la_DEPENDENCIES = \ -@WITH_PYTHON_TRUE@ $(top_builddir)/libxml2.la \ -@WITH_PYTHON_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ -@WITH_PYTHON_TRUE@ $(am__DEPENDENCIES_1) +libxml2mod_la_LIBADD = am__libxml2mod_la_SOURCES_DIST = libxml.c libxml_wrap.h libxml2-py.h \ libxml2-py.c types.c @WITH_PYTHON_TRUE@am_libxml2mod_la_OBJECTS = libxml.lo libxml2-py.lo \ @@ -132,6 +145,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__dist_python_DATA_DIST = drv_libxml2.py libxml2.py DATA = $(dist_docs_DATA) $(dist_python_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ @@ -264,7 +282,6 @@ RANLIB = @RANLIB@ RDL_LIBS = @RDL_LIBS@ READER_TEST = @READER_TEST@ RELDATE = @RELDATE@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -321,6 +338,7 @@ WITH_SAX1 = @WITH_SAX1@ WITH_SCHEMAS = @WITH_SCHEMAS@ WITH_SCHEMATRON = @WITH_SCHEMATRON@ WITH_THREADS = @WITH_THREADS@ +WITH_THREAD_ALLOC = @WITH_THREAD_ALLOC@ WITH_TREE = @WITH_TREE@ WITH_TRIO = @WITH_TRIO@ WITH_VALID = @WITH_VALID@ @@ -416,8 +434,9 @@ EXTRA_DIST = \ @WITH_PYTHON_TRUE@python_LTLIBRARIES = libxml2mod.la @WITH_PYTHON_TRUE@libxml2mod_la_SOURCES = libxml.c libxml_wrap.h libxml2-py.h libxml2-py.c types.c -@WITH_PYTHON_TRUE@libxml2mod_la_LIBADD = $(top_builddir)/libxml2.la $(CYGWIN_EXTRA_PYTHON_LIBADD) $(WIN32_EXTRA_PYTHON_LIBADD) $(PYTHON_LIBS) -lpython$(PYTHON_VERSION) -@WITH_PYTHON_TRUE@libxml2mod_la_LDFLAGS = $(CYGWIN_EXTRA_LDFLAGS) $(WIN32_EXTRA_LDFLAGS) -module -avoid-version +@WITH_PYTHON_TRUE@libxml2mod_la_LDFLAGS = $(CYGWIN_EXTRA_LDFLAGS) $(WIN32_EXTRA_LDFLAGS) -module -avoid-version \ +@WITH_PYTHON_TRUE@ $(top_builddir)/libxml2.la $(CYGWIN_EXTRA_PYTHON_LIBADD) $(WIN32_EXTRA_PYTHON_LIBADD) $(PYTHON_LIBS) + @WITH_PYTHON_TRUE@BUILT_SOURCES = libxml2-export.c libxml2-py.h libxml2-py.c @WITH_PYTHON_TRUE@dist_python_DATA = \ @WITH_PYTHON_TRUE@ drv_libxml2.py \ @@ -466,7 +485,6 @@ setup.py: $(top_builddir)/config.status $(srcdir)/setup.py.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-pythonLTLIBRARIES: $(python_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(pythondir)" || $(MKDIR_P) "$(DESTDIR)$(pythondir)" @list='$(python_LTLIBRARIES)'; test -n "$(pythondir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -474,6 +492,8 @@ install-pythonLTLIBRARIES: $(python_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pythondir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pythondir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythondir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythondir)"; \ } @@ -536,8 +556,11 @@ clean-libtool: -rm -rf .libs _libs install-dist_docsDATA: $(dist_docs_DATA) @$(NORMAL_INSTALL) - test -z "$(docsdir)" || $(MKDIR_P) "$(DESTDIR)$(docsdir)" @list='$(dist_docs_DATA)'; test -n "$(docsdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docsdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docsdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -554,8 +577,11 @@ uninstall-dist_docsDATA: dir='$(DESTDIR)$(docsdir)'; $(am__uninstall_files_from_dir) install-dist_pythonDATA: $(dist_python_DATA) @$(NORMAL_INSTALL) - test -z "$(pythondir)" || $(MKDIR_P) "$(DESTDIR)$(pythondir)" @list='$(dist_python_DATA)'; test -n "$(pythondir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pythondir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pythondir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -738,13 +764,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ diff --git a/python/generator.py b/python/generator.py index 767c4bb..82109e3 100755 --- a/python/generator.py +++ b/python/generator.py @@ -47,19 +47,19 @@ class docParser(xml.sax.handler.ContentHandler): def close(self): if debug: - print "close" + print("close") def getmethodname(self): return self._methodname def data(self, text): if debug: - print "data %s" % text + print("data %s" % text) self._data.append(text) def start(self, tag, attrs): if debug: - print "start %s, %s" % (tag, attrs) + print("start %s, %s" % (tag, attrs)) if tag == 'function': self._data = [] self.in_function = 1 @@ -69,9 +69,9 @@ class docParser(xml.sax.handler.ContentHandler): self.function_descr = None self.function_return = None self.function_file = None - if attrs.has_key('name'): + if 'name' in attrs.keys(): self.function = attrs['name'] - if attrs.has_key('file'): + if 'file' in attrs.keys(): self.function_file = attrs['file'] elif tag == 'cond': self._data = [] @@ -82,29 +82,29 @@ class docParser(xml.sax.handler.ContentHandler): self.function_arg_name = None self.function_arg_type = None self.function_arg_info = None - if attrs.has_key('name'): + if 'name' in attrs.keys(): self.function_arg_name = attrs['name'] - if attrs.has_key('type'): + if 'type' in attrs.keys(): self.function_arg_type = attrs['type'] - if attrs.has_key('info'): + if 'info' in attrs.keys(): self.function_arg_info = attrs['info'] elif tag == 'return': if self.in_function == 1: self.function_return_type = None self.function_return_info = None self.function_return_field = None - if attrs.has_key('type'): + if 'type' in attrs.keys(): self.function_return_type = attrs['type'] - if attrs.has_key('info'): + if 'info' in attrs.keys(): self.function_return_info = attrs['info'] - if attrs.has_key('field'): + if 'field' in attrs.keys(): self.function_return_field = attrs['field'] elif tag == 'enum': enum(attrs['type'],attrs['name'],attrs['value']) def end(self, tag): if debug: - print "end %s" % tag + print("end %s" % tag) if tag == 'function': if self.function != None: function(self.function, self.function_descr, @@ -133,13 +133,13 @@ class docParser(xml.sax.handler.ContentHandler): str = str + c if self.in_function == 1: self.function_cond = str - - + + def function(name, desc, ret, args, file, cond): functions[name] = (desc, ret, args, file, cond) def enum(type, name, value): - if not enums.has_key(type): + if type not in enums: enums[type] = {} enums[type][name] = value @@ -339,6 +339,8 @@ def skip_function(name): return 1 if name == "xmlValidateAttributeDecl": return 1 + if name == "xmlPopInputCallbacks": + return 1 return 0 @@ -351,10 +353,10 @@ def print_function_wrapper(name, output, export, include): try: (desc, ret, args, file, cond) = functions[name] except: - print "failed to get function %s infos" + print("failed to get function %s infos") return - if skipped_modules.has_key(file): + if file in skipped_modules: return 0 if skip_function(name) == 1: return 0 @@ -368,16 +370,17 @@ def print_function_wrapper(name, output, export, include): c_args="" c_return="" c_convert="" + c_release="" num_bufs=0 for arg in args: # This should be correct if arg[1][0:6] == "const ": arg[1] = arg[1][6:] c_args = c_args + " %s %s;\n" % (arg[1], arg[0]) - if py_types.has_key(arg[1]): + if arg[1] in py_types: (f, t, n, c) = py_types[arg[1]] if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0): - f = 't#' + f = 's#' if f != None: format = format + f if t != None: @@ -388,17 +391,20 @@ def print_function_wrapper(name, output, export, include): arg[1], t, arg[0]) else: format_args = format_args + ", &%s" % (arg[0]) - if f == 't#': + if f == 's#': format_args = format_args + ", &py_buffsize%d" % num_bufs c_args = c_args + " int py_buffsize%d;\n" % num_bufs num_bufs = num_bufs + 1 if c_call != "": c_call = c_call + ", " c_call = c_call + "%s" % (arg[0]) + if t == "File": + c_release = c_release + \ + " PyFile_Release(%s);\n" % (arg[0]) else: - if skipped_types.has_key(arg[1]): + if arg[1] in skipped_types: return 0 - if unknown_types.has_key(arg[1]): + if arg[1] in unknown_types: lst = unknown_types[arg[1]] lst.append(name) else: @@ -420,25 +426,25 @@ def print_function_wrapper(name, output, export, include): else: c_call = "\n %s(%s);\n" % (name, c_call) ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n" - elif py_types.has_key(ret[0]): + elif ret[0] in py_types: (f, t, n, c) = py_types[ret[0]] - c_return = " %s c_retval;\n" % (ret[0]) + c_return = c_return + " %s c_retval;\n" % (ret[0]) if file == "python_accessor" and ret[2] != None: c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2]) else: c_call = "\n c_retval = %s(%s);\n" % (name, c_call) ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return(py_retval);\n" - elif py_return_types.has_key(ret[0]): + elif ret[0] in py_return_types: (f, t, n, c) = py_return_types[ret[0]] - c_return = " %s c_retval;\n" % (ret[0]) + c_return = c_return + " %s c_retval;\n" % (ret[0]) c_call = "\n c_retval = %s(%s);\n" % (name, c_call) ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return(py_retval);\n" else: - if skipped_types.has_key(ret[0]): + if ret[0] in skipped_types: return 0 - if unknown_types.has_key(ret[0]): + if ret[0] in unknown_types: lst = unknown_types[ret[0]] lst.append(name) else: @@ -489,8 +495,10 @@ def print_function_wrapper(name, output, export, include): output.write(" return(NULL);\n") if c_convert != "": output.write(c_convert) - + output.write(c_call) + if c_release != "": + output.write(c_release) output.write(ret_convert) output.write("}\n\n") if cond != None and cond != "": @@ -510,19 +518,19 @@ def buildStubs(): (parser, target) = getparser() parser.feed(data) parser.close() - except IOError, msg: + except IOError as msg: try: f = open(os.path.join(srcPref,"..","doc","libxml2-api.xml")) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() - except IOError, msg: - print file, ":", msg + except IOError as msg: + print(file, ":", msg) sys.exit(1) - n = len(functions.keys()) - print "Found %d functions in libxml2-api.xml" % (n) + n = len(list(functions.keys())) + print("Found %d functions in libxml2-api.xml" % (n)) py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject") try: @@ -531,12 +539,12 @@ def buildStubs(): (parser, target) = getparser() parser.feed(data) parser.close() - except IOError, msg: - print file, ":", msg + except IOError as msg: + print(file, ":", msg) - print "Found %d functions in libxml2-python-api.xml" % ( - len(functions.keys()) - n) + print("Found %d functions in libxml2-python-api.xml" % ( + len(list(functions.keys())) - n)) nb_wrap = 0 failed = 0 skipped = 0 @@ -567,12 +575,12 @@ def buildStubs(): export.close() wrapper.close() - print "Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap, - failed, skipped) - print "Missing type converters: " - for type in unknown_types.keys(): - print "%s:%d " % (type, len(unknown_types[type])), - print + print("Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap, + failed, skipped)) + print("Missing type converters: ") + for type in list(unknown_types.keys()): + print("%s:%d " % (type, len(unknown_types[type]))) + print() ####################################################################### # @@ -697,40 +705,40 @@ def nameFixup(name, classe, type, file): l = len(classe) if name[0:l] == listname: func = name[l:] - func = string.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 = string.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 = string.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 = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:9] == "xmlURIGet" and file == "python_accessor": func = name[9:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:9] == "xmlURISet" and file == "python_accessor": func = name[6:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:11] == "xmlErrorGet" and file == "python_accessor": func = name[11:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor": func = name[17:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:11] == "xmlXPathGet" and file == "python_accessor": func = name[11:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:11] == "xmlXPathSet" and file == "python_accessor": func = name[8:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:15] == "xmlOutputBuffer" and file != "python": func = name[15:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:20] == "xmlParserInputBuffer" and file != "python": func = name[20:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:9] == "xmlRegexp" and file == "xmlregexp": func = "regexp" + name[9:] elif name[0:6] == "xmlReg" and file == "xmlregexp": @@ -745,19 +753,19 @@ def nameFixup(name, classe, type, file): func = name[9:] elif name[0:11] == "xmlACatalog": func = name[11:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:l] == classe: func = name[l:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:7] == "libxml_": func = name[7:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:6] == "xmlGet": func = name[6:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] elif name[0:3] == "xml": func = name[3:] - func = string.lower(func[0:1]) + func[1:] + func = func[0:1].lower() + func[1:] else: func = name if func[0:5] == "xPath": @@ -795,11 +803,29 @@ def functionCompare(info1, info2): return 1 return 0 +def cmp_to_key(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + def __ne__(self, other): + return mycmp(self.obj, other.obj) != 0 + return K def writeDoc(name, args, indent, output): if functions[name][0] is None or functions[name][0] == "": return val = functions[name][0] - val = string.replace(val, "NULL", "None") + val = val.replace("NULL", "None") output.write(indent) output.write('"""') while len(val) > 60: @@ -807,7 +833,7 @@ def writeDoc(name, args, indent, output): val = val[1:] continue str = val[0:60] - i = string.rfind(str, " ") + i = str.rfind(" ") if i < 0: i = 60 str = val[0:i] @@ -857,13 +883,13 @@ def buildWrappers(): ctypes.append(type) ctypes_processed[type] = () for type in sorted(classes_type.keys()): - if ctypes_processed.has_key(type): + if type in ctypes_processed: continue tinfo = classes_type[type] - if not classes_processed.has_key(tinfo[2]): + if tinfo[2] not in classes_processed: classes_list.append(tinfo[2]) classes_processed[tinfo[2]] = () - + ctypes.append(type) ctypes_processed[type] = () @@ -912,9 +938,9 @@ def buildWrappers(): txt.write(" Generated Classes for libxml2-python\n\n") txt.write("#\n# Global functions of the module\n#\n\n") - if function_classes.has_key("None"): + if "None" in function_classes: flist = function_classes["None"] - flist.sort(functionCompare) + flist = sorted(flist, key=cmp_to_key(functionCompare)) oldfile = "" for info in flist: (index, func, name, ret, args, file) = info @@ -934,11 +960,17 @@ def buildWrappers(): writeDoc(name, args, ' ', classes) for arg in args: - if classes_type.has_key(arg[1]): + if arg[1] in classes_type: classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) classes.write(" else: %s__o = %s%s\n" % (arg[0], arg[0], classes_type[arg[1]][0])) + if arg[1] in py_types: + (f, t, n, c) = py_types[arg[1]] + if t == "File": + classes.write(" if %s is not None: %s.flush()\n" % ( + arg[0], arg[0])) + if ret[0] != "void": classes.write(" ret = ") else: @@ -949,26 +981,36 @@ def buildWrappers(): if n != 0: classes.write(", ") classes.write("%s" % arg[0]) - if classes_type.has_key(arg[1]): + if arg[1] in classes_type: classes.write("__o") n = n + 1 classes.write(")\n") + +# This may be needed to reposition the I/O, but likely to cause more harm +# than good. Those changes in Python3 really break the model. +# for arg in args: +# if arg[1] in py_types: +# (f, t, n, c) = py_types[arg[1]] +# if t == "File": +# classes.write(" if %s is not None: %s.seek(0,0)\n"%( +# arg[0], arg[0])) + if ret[0] != "void": - if classes_type.has_key(ret[0]): + if ret[0] in classes_type: # # Raise an exception # - if functions_noexcept.has_key(name): + if name in functions_noexcept: classes.write(" if ret is None:return None\n") - elif string.find(name, "URI") >= 0: + elif name.find("URI") >= 0: classes.write( " if ret is None:raise uriError('%s() failed')\n" % (name)) - elif string.find(name, "XPath") >= 0: + elif name.find("XPath") >= 0: classes.write( " if ret is None:raise xpathError('%s() failed')\n" % (name)) - elif string.find(name, "Parse") >= 0: + elif name.find("Parse") >= 0: classes.write( " if ret is None:raise parserError('%s() failed')\n" % (name)) @@ -988,7 +1030,7 @@ def buildWrappers(): if classname == "None": pass else: - if classes_ancestor.has_key(classname): + if classname in classes_ancestor: txt.write("\n\nClass %s(%s)\n" % (classname, classes_ancestor[classname])) classes.write("class %s(%s):\n" % (classname, @@ -996,12 +1038,11 @@ def buildWrappers(): classes.write(" def __init__(self, _obj=None):\n") if classes_ancestor[classname] == "xmlCore" or \ classes_ancestor[classname] == "xmlNode": - classes.write(" if type(_obj).__name__ != ") - classes.write("'PyCObject':\n") - classes.write(" raise TypeError, ") - classes.write("'%s needs a PyCObject argument'\n" % \ + classes.write(" if checkWrapper(_obj) != 0:") + classes.write(" raise TypeError") + classes.write("('%s got a wrong wrapper object type')\n" % \ classname) - if reference_keepers.has_key(classname): + if classname in reference_keepers: rlist = reference_keepers[classname] for ref in rlist: classes.write(" self.%s = None\n" % ref[1]) @@ -1012,20 +1053,20 @@ def buildWrappers(): classes_ancestor[classname] == "xmlNode": classes.write(" def __repr__(self):\n") format = "<%s (%%s) object at 0x%%x>" % (classname) - classes.write(" return \"%s\" %% (self.name, long(pos_id (self)))\n\n" % ( + classes.write(" return \"%s\" %% (self.name, int(pos_id (self)))\n\n" % ( format)) else: txt.write("Class %s()\n" % (classname)) classes.write("class %s:\n" % (classname)) classes.write(" def __init__(self, _obj=None):\n") - if reference_keepers.has_key(classname): + if classname in reference_keepers: list = reference_keepers[classname] for ref in list: classes.write(" self.%s = None\n" % ref[1]) classes.write(" if _obj != None:self._o = _obj;return\n") classes.write(" self._o = None\n\n") destruct=None - if classes_destructors.has_key(classname): + if classname in classes_destructors: classes.write(" def __del__(self):\n") classes.write(" if self._o != None:\n") classes.write(" libxml2mod.%s(self._o)\n" % @@ -1033,7 +1074,7 @@ def buildWrappers(): classes.write(" self._o = None\n\n") destruct=classes_destructors[classname] flist = function_classes[classname] - flist.sort(functionCompare) + flist = sorted(flist, key=cmp_to_key(functionCompare)) oldfile = "" for info in flist: (index, func, name, ret, args, file) = info @@ -1065,7 +1106,7 @@ def buildWrappers(): writeDoc(name, args, ' ', classes) n = 0 for arg in args: - if classes_type.has_key(arg[1]): + if arg[1] in classes_type: if n != index: classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) @@ -1083,31 +1124,31 @@ def buildWrappers(): classes.write(", ") if n != index: classes.write("%s" % arg[0]) - if classes_type.has_key(arg[1]): + if arg[1] in classes_type: classes.write("__o") else: classes.write("self") - if classes_type.has_key(arg[1]): + if arg[1] in classes_type: classes.write(classes_type[arg[1]][0]) n = n + 1 classes.write(")\n") if ret[0] != "void": - if classes_type.has_key(ret[0]): + if ret[0] in classes_type: # # Raise an exception # - if functions_noexcept.has_key(name): + if name in functions_noexcept: classes.write( " if ret is None:return None\n") - elif string.find(name, "URI") >= 0: + elif name.find("URI") >= 0: classes.write( " if ret is None:raise uriError('%s() failed')\n" % (name)) - elif string.find(name, "XPath") >= 0: + elif name.find("XPath") >= 0: classes.write( " if ret is None:raise xpathError('%s() failed')\n" % (name)) - elif string.find(name, "Parse") >= 0: + elif name.find("Parse") >= 0: classes.write( " if ret is None:raise parserError('%s() failed')\n" % (name)) @@ -1129,7 +1170,7 @@ def buildWrappers(): # See reference_keepers for the list # tclass = classes_type[ret[0]][2] - if reference_keepers.has_key(tclass): + if tclass in reference_keepers: list = reference_keepers[tclass] for pref in list: if pref[0] == classname: @@ -1139,22 +1180,22 @@ def buildWrappers(): # return the class # classes.write(" return __tmp\n") - elif converter_type.has_key(ret[0]): + elif ret[0] in converter_type: # # Raise an exception # - if functions_noexcept.has_key(name): + if name in functions_noexcept: classes.write( " if ret is None:return None") - elif string.find(name, "URI") >= 0: + elif name.find("URI") >= 0: classes.write( " if ret is None:raise uriError('%s() failed')\n" % (name)) - elif string.find(name, "XPath") >= 0: + elif name.find("XPath") >= 0: classes.write( " if ret is None:raise xpathError('%s() failed')\n" % (name)) - elif string.find(name, "Parse") >= 0: + elif name.find("Parse") >= 0: classes.write( " if ret is None:raise parserError('%s() failed')\n" % (name)) @@ -1175,7 +1216,7 @@ def buildWrappers(): for type,enum in enums.items(): classes.write("# %s\n" % type) items = enum.items() - items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1]))) + items = sorted(items, key=(lambda i: int(i[1]))) for name,value in items: classes.write("%s = %s\n" % (name,value)) classes.write("\n") diff --git a/python/libxml.c b/python/libxml.c index a556160..03cfb9f 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; @@ -665,7 +723,7 @@ pythonExternalEntityLoader(const char *URL, const char *ID, Py_XDECREF(ctxtobj); #ifdef DEBUG_LOADER printf("pythonExternalEntityLoader: result "); - PyObject_Print(ret, stderr, 0); + PyObject_Print(ret, stdout, 0); printf("\n"); #endif @@ -711,19 +769,114 @@ libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) { &loader)) return(NULL); + if (!PyCallable_Check(loader)) { + PyErr_SetString(PyExc_ValueError, "entity loader is not callable"); + return(NULL); + } + #ifdef DEBUG_LOADER printf("libxml_xmlSetEntityLoader\n"); #endif if (defaultExternalEntityLoader == NULL) defaultExternalEntityLoader = xmlGetExternalEntityLoader(); + Py_XDECREF(pythonExternalEntityLoaderObjext); pythonExternalEntityLoaderObjext = loader; + Py_XINCREF(pythonExternalEntityLoaderObjext); xmlSetExternalEntityLoader(pythonExternalEntityLoader); - py_retval = PyInt_FromLong(0); + py_retval = PyLong_FromLong(0); return(py_retval); } +/************************************************************************ + * * + * Input callback registration * + * * + ************************************************************************/ +static PyObject *pythonInputOpenCallbackObject; +static int pythonInputCallbackID = -1; + +static int +pythonInputMatchCallback(ATTRIBUTE_UNUSED const char *URI) +{ + /* Always return success, real decision whether URI is supported will be + * made in open callback. */ + return 1; +} + +static void * +pythonInputOpenCallback(const char *URI) +{ + PyObject *ret; + + ret = PyObject_CallFunction(pythonInputOpenCallbackObject, + (char *)"s", URI); + if (ret == Py_None) { + Py_DECREF(Py_None); + return NULL; + } + return ret; +} + +PyObject * +libxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject *self, + PyObject *args) { + PyObject *cb; + + if (!PyArg_ParseTuple(args, + (const char *)"O:libxml_xmlRegisterInputCallback", &cb)) + return(NULL); + + if (!PyCallable_Check(cb)) { + PyErr_SetString(PyExc_ValueError, "input callback is not callable"); + return(NULL); + } + + /* Python module registers a single callback and manages the list of + * all callbacks internally. This is necessitated by xmlInputMatchCallback + * API, which does not allow for passing of data objects to discriminate + * different Python methods. */ + if (pythonInputCallbackID == -1) { + pythonInputCallbackID = xmlRegisterInputCallbacks( + pythonInputMatchCallback, pythonInputOpenCallback, + xmlPythonFileReadRaw, xmlPythonFileCloseRaw); + if (pythonInputCallbackID == -1) + return PyErr_NoMemory(); + pythonInputOpenCallbackObject = cb; + Py_INCREF(pythonInputOpenCallbackObject); + } + + Py_INCREF(Py_None); + return(Py_None); +} + +PyObject * +libxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject *self, + ATTRIBUTE_UNUSED PyObject *args) { + int ret; + + ret = xmlPopInputCallbacks(); + if (pythonInputCallbackID != -1) { + /* Assert that the right input callback was popped. libxml's API does not + * allow removal by ID, so all that could be done is an assert. */ + if (pythonInputCallbackID == ret) { + pythonInputCallbackID = -1; + Py_DECREF(pythonInputOpenCallbackObject); + pythonInputOpenCallbackObject = NULL; + } else { + PyErr_SetString(PyExc_AssertionError, "popped non-python input callback"); + return(NULL); + } + } else if (ret == -1) { + /* No more callbacks to pop */ + PyErr_SetString(PyExc_IndexError, "no input callbacks to pop"); + return(NULL); + } + + Py_INCREF(Py_None); + return(Py_None); +} /************************************************************************ * * @@ -764,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; @@ -1170,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++; @@ -2033,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); } @@ -2234,6 +2387,32 @@ libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self, return (py_retval); } +PyObject * +libxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self, + PyObject * args) +{ + PyObject *py_retval; + int c_retval = 0; + xmlChar *name; + xmlChar *ns_uri; + xmlXPathContextPtr ctx; + xmlXPathObjectPtr val; + PyObject *pyobj_ctx; + PyObject *pyobj_value; + + if (!PyArg_ParseTuple + (args, (char *) "OszO:xpathRegisterVariable", &pyobj_ctx, &name, + &ns_uri, &pyobj_value)) + return (NULL); + + ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx); + val = libxml_xmlXPathObjectPtrConvert(pyobj_value); + + c_retval = xmlXPathRegisterVariableNS(ctx, name, ns_uri, val); + py_retval = libxml_intWrap(c_retval); + return (py_retval); +} + /************************************************************************ * * * Global properties access * @@ -2566,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); @@ -2682,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); @@ -2844,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)); - } - if ((py_file == NULL) || (!(PyFile_Check(py_file)))) { - return (PyInt_FromLong((long) -1)); + return (PyLong_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) { @@ -2872,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) { @@ -2897,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 */ @@ -3403,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)); @@ -3492,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; } @@ -3534,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; @@ -3576,6 +3752,7 @@ libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, xmlFree(prefixes); } + PyFile_Release(output); len = xmlOutputBufferClose(buf); if (result < 0) { @@ -3584,7 +3761,7 @@ libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self, return NULL; } else - return PyInt_FromLong((long) len); + return PyLong_FromLong((long) len); } #endif @@ -3598,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); } @@ -3693,31 +3870,64 @@ static PyMethodDef libxmlMethods[] = { {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL}, {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL}, {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL}, + {(char *) "xmlRegisterInputCallback", libxml_xmlRegisterInputCallback, METH_VARARGS, NULL}, + {(char *) "xmlUnregisterInputCallback", libxml_xmlUnregisterInputCallback, METH_VARARGS, NULL}, {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 } diff --git a/python/libxml.py b/python/libxml.py index c861a70..e507e0f 100644 --- a/python/libxml.py +++ b/python/libxml.py @@ -5,13 +5,23 @@ import sys # The root of all libxml2 errors. class libxmlError(Exception): pass +# Type of the wrapper class for the C objects wrappers +def checkWrapper(obj): + try: + n = type(_obj).__name__ + if n != 'PyCObject' and n != 'PyCapsule': + return 1 + except: + return 0 + return 0 + # # id() is sometimes negative ... # def pos_id(o): i = id(o) if (i < 0): - return (sys.maxint - i) + return (sys.maxsize - i) return i # @@ -62,9 +72,20 @@ class ioWrapper: def io_read(self, len = -1): if self.__io == None: return(-1) - if len < 0: - return(self.__io.read()) - return(self.__io.read(len)) + try: + if len < 0: + ret = self.__io.read() + else: + ret = self.__io.read(len) + except Exception: + import sys + e = sys.exc_info()[1] + print("failed to read from Python:", type(e)) + print("on IO:", self.__io) + self.__io == None + return(-1) + + return(ret) def io_write(self, str, len = -1): if self.__io == None: @@ -79,7 +100,7 @@ class ioReadWrapper(ioWrapper): self._o = libxml2mod.xmlCreateInputBuffer(self, enc) def __del__(self): - print "__del__" + print("__del__") self.io_close() if self._o != None: libxml2mod.xmlFreeParserInputBuffer(self._o) @@ -95,12 +116,19 @@ class ioWriteWrapper(ioWrapper): def __init__(self, _obj, enc = ""): # print "ioWriteWrapper.__init__", _obj if type(_obj) == type(''): - print "write io from a string" + print("write io from a string") self.o = None - elif type(_obj) == types.InstanceType: - print "write io from instance of %s" % (_obj.__class__) - ioWrapper.__init__(self, _obj) - self._o = libxml2mod.xmlCreateOutputBuffer(self, enc) + elif type(_obj).__name__ == 'PyCapsule': + file = libxml2mod.outputBufferGetPythonFile(_obj) + if file != None: + ioWrapper.__init__(self, file) + else: + ioWrapper.__init__(self, _obj) + self._o = _obj +# elif type(_obj) == types.InstanceType: +# print(("write io from instance of %s" % (_obj.__class__))) +# ioWrapper.__init__(self, _obj) +# self._o = libxml2mod.xmlCreateOutputBuffer(self, enc) else: file = libxml2mod.outputBufferGetPythonFile(_obj) if file != None: @@ -265,22 +293,22 @@ class xmlCore: ret = libxml2mod.parent(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_children(self): ret = libxml2mod.children(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_last(self): ret = libxml2mod.last(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_next(self): ret = libxml2mod.next(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_properties(self): ret = libxml2mod.properties(self._o) if ret == None: @@ -290,7 +318,7 @@ class xmlCore: ret = libxml2mod.prev(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_content(self): return libxml2mod.xmlNodeGetContent(self._o) getContent = get_content # why is this duplicate naming needed ? @@ -317,7 +345,7 @@ class xmlCore: ret = libxml2mod.parent(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "properties": ret = libxml2mod.properties(self._o) if ret == None: @@ -327,22 +355,22 @@ class xmlCore: ret = libxml2mod.children(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "last": ret = libxml2mod.last(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "next": ret = libxml2mod.next(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "prev": ret = libxml2mod.prev(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "content": return libxml2mod.xmlNodeGetContent(self._o) elif attr == "name": @@ -357,7 +385,7 @@ class xmlCore: else: return None return xmlDoc(_obj=ret) - raise AttributeError,attr + raise AttributeError(attr) else: parent = property(get_parent, None, None, "Parent node") children = property(get_children, None, None, "First child node") @@ -400,7 +428,7 @@ class xmlCore: prefixes=None, with_comments=0): if nodes: - nodes = map(lambda n: n._o, nodes) + nodes = [n._o for n in nodes] return libxml2mod.xmlC14NDocDumpMemory( self.get_doc()._o, nodes, @@ -414,7 +442,7 @@ class xmlCore: prefixes=None, with_comments=0): if nodes: - nodes = map(lambda n: n._o, nodes) + nodes = [n._o for n in nodes] return libxml2mod.xmlC14NDocSaveTo( self.get_doc()._o, nodes, @@ -564,10 +592,10 @@ def nodeWrap(o): def xpathObjectRet(o): otype = type(o) if otype == type([]): - ret = map(xpathObjectRet, o) + ret = list(map(xpathObjectRet, o)) return ret elif otype == type(()): - ret = map(xpathObjectRet, o) + ret = list(map(xpathObjectRet, o)) return tuple(ret) elif otype == type('') or otype == type(0) or otype == type(0.0): return o @@ -603,7 +631,7 @@ def registerErrorHandler(f, ctx): """Register a Python written function to for error reporting. The function is called back as f(ctx, error). """ import sys - if not sys.modules.has_key('libxslt'): + if 'libxslt' not in sys.modules: # normal behaviour when libxslt is not imported ret = libxml2mod.xmlRegisterErrorHandler(f,ctx) else: @@ -682,8 +710,9 @@ class relaxNgValidCtxtCore: libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg) -def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator): +def _xmlTextReaderErrorFunc(xxx_todo_changeme,msg,severity,locator): """Intermediate callback to wrap the locator""" + (f,arg) = xxx_todo_changeme return f(arg,msg,severity,xmlTextReaderLocator(locator)) class xmlTextReaderCore: @@ -719,11 +748,35 @@ class xmlTextReaderCore: return arg # -# The cleanup now goes though a wrappe in libxml.c +# The cleanup now goes though a wrapper in libxml.c # def cleanupParser(): libxml2mod.xmlPythonCleanupParser() +# +# The interface to xmlRegisterInputCallbacks. +# Since this API does not allow to pass a data object along with +# match/open callbacks, it is necessary to maintain a list of all +# Python callbacks. +# +__input_callbacks = [] +def registerInputCallback(func): + def findOpenCallback(URI): + for cb in reversed(__input_callbacks): + o = cb(URI) + if o is not None: + return o + libxml2mod.xmlRegisterInputCallback(findOpenCallback) + __input_callbacks.append(func) + +def popInputCallbacks(): + # First pop python-level callbacks, when no more available - start + # popping built-in ones. + if len(__input_callbacks) > 0: + __input_callbacks.pop() + if len(__input_callbacks) == 0: + libxml2mod.xmlUnregisterInputCallback() + # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # # Everything before this line comes from libxml.py diff --git a/python/libxml2-export.c b/python/libxml2-export.c index 19ef337..f7d96e1 100644 --- a/python/libxml2-export.c +++ b/python/libxml2-export.c @@ -650,7 +650,6 @@ { (char *)"xmlPathToURI", libxml_xmlPathToURI, METH_VARARGS, NULL }, { (char *)"xmlPedanticParserDefault", libxml_xmlPedanticParserDefault, METH_VARARGS, NULL }, { (char *)"xmlPopInput", libxml_xmlPopInput, METH_VARARGS, NULL }, - { (char *)"xmlPopInputCallbacks", libxml_xmlPopInputCallbacks, METH_VARARGS, NULL }, #if defined(LIBXML_TREE_ENABLED) { (char *)"xmlPreviousElementSibling", libxml_xmlPreviousElementSibling, METH_VARARGS, NULL }, #endif /* defined(LIBXML_TREE_ENABLED) */ @@ -1919,6 +1918,9 @@ { (char *)"xmlXPathNextSelf", libxml_xmlXPathNextSelf, METH_VARARGS, NULL }, #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) + { (char *)"xmlXPathNodeEval", libxml_xmlXPathNodeEval, METH_VARARGS, NULL }, +#endif /* defined(LIBXML_XPATH_ENABLED) */ +#if defined(LIBXML_XPATH_ENABLED) { (char *)"xmlXPathNodeSetFreeNs", libxml_xmlXPathNodeSetFreeNs, METH_VARARGS, NULL }, #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) @@ -1967,6 +1969,9 @@ { (char *)"xmlXPathRegisterNs", libxml_xmlXPathRegisterNs, METH_VARARGS, NULL }, #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) + { (char *)"xmlXPathRegisterVariable", libxml_xmlXPathRegisterVariable, METH_VARARGS, NULL }, +#endif +#if defined(LIBXML_XPATH_ENABLED) { (char *)"xmlXPathRegisteredFuncsCleanup", libxml_xmlXPathRegisteredFuncsCleanup, METH_VARARGS, NULL }, #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) diff --git a/python/libxml2-py.c b/python/libxml2-py.c index cb2e585..5d66e54 100644 --- a/python/libxml2-py.c +++ b/python/libxml2-py.c @@ -65,7 +65,7 @@ libxml_htmlCreateMemoryParserCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg int py_buffsize0; int size; - if (!PyArg_ParseTuple(args, (char *)"t#i:htmlCreateMemoryParserCtxt", &buffer, &py_buffsize0, &size)) + if (!PyArg_ParseTuple(args, (char *)"s#i:htmlCreateMemoryParserCtxt", &buffer, &py_buffsize0, &size)) return(NULL); c_retval = htmlCreateMemoryParserCtxt(buffer, size); @@ -155,7 +155,7 @@ libxml_htmlCtxtReadMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char * encoding; int options; - if (!PyArg_ParseTuple(args, (char *)"Ot#izzi:htmlCtxtReadMemory", &pyobj_ctxt, &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) + if (!PyArg_ParseTuple(args, (char *)"Os#izzi:htmlCtxtReadMemory", &pyobj_ctxt, &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) return(NULL); ctxt = (htmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); @@ -267,6 +267,7 @@ libxml_htmlDocDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); c_retval = htmlDocDump(f, cur); + PyFile_Release(f); py_retval = libxml_intWrap((int) c_retval); return(py_retval); } @@ -448,6 +449,7 @@ libxml_htmlNodeDumpFile(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlNodePtr) PyxmlNode_Get(pyobj_cur); htmlNodeDumpFile(out, doc, cur); + PyFile_Release(out); Py_INCREF(Py_None); return(Py_None); } @@ -474,6 +476,7 @@ libxml_htmlNodeDumpFileFormat(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlNodePtr) PyxmlNode_Get(pyobj_cur); c_retval = htmlNodeDumpFileFormat(out, doc, cur, encoding, format); + PyFile_Release(out); py_retval = libxml_intWrap((int) c_retval); return(py_retval); } @@ -556,7 +559,7 @@ libxml_htmlParseChunk(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int size; int terminate; - if (!PyArg_ParseTuple(args, (char *)"Ot#ii:htmlParseChunk", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &terminate)) + if (!PyArg_ParseTuple(args, (char *)"Os#ii:htmlParseChunk", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &terminate)) return(NULL); ctxt = (htmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); @@ -702,7 +705,7 @@ libxml_htmlReadMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char * encoding; int options; - if (!PyArg_ParseTuple(args, (char *)"t#izzi:htmlReadMemory", &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) + if (!PyArg_ParseTuple(args, (char *)"s#izzi:htmlReadMemory", &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) return(NULL); c_retval = htmlReadMemory(buffer, size, URL, encoding, options); @@ -913,6 +916,7 @@ libxml_xmlACatalogDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { out = (FILE *) PyFile_Get(pyobj_out); xmlACatalogDump(catal, out); + PyFile_Release(out); Py_INCREF(Py_None); return(Py_None); } @@ -1312,6 +1316,7 @@ libxml_xmlCatalogDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { out = (FILE *) PyFile_Get(pyobj_out); xmlCatalogDump(out); + PyFile_Release(out); Py_INCREF(Py_None); return(Py_None); } @@ -1892,7 +1897,7 @@ libxml_xmlCreateMemoryParserCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args int py_buffsize0; int size; - if (!PyArg_ParseTuple(args, (char *)"t#i:xmlCreateMemoryParserCtxt", &buffer, &py_buffsize0, &size)) + if (!PyArg_ParseTuple(args, (char *)"s#i:xmlCreateMemoryParserCtxt", &buffer, &py_buffsize0, &size)) return(NULL); c_retval = xmlCreateMemoryParserCtxt(buffer, size); @@ -1997,7 +2002,7 @@ libxml_xmlCtxtReadMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char * encoding; int options; - if (!PyArg_ParseTuple(args, (char *)"Ot#izzi:xmlCtxtReadMemory", &pyobj_ctxt, &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) + if (!PyArg_ParseTuple(args, (char *)"Os#izzi:xmlCtxtReadMemory", &pyobj_ctxt, &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) return(NULL); ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); @@ -2032,7 +2037,7 @@ libxml_xmlCtxtResetPush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char * filename; char * encoding; - if (!PyArg_ParseTuple(args, (char *)"Ot#izz:xmlCtxtResetPush", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &filename, &encoding)) + if (!PyArg_ParseTuple(args, (char *)"Os#izz:xmlCtxtResetPush", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &filename, &encoding)) return(NULL); ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); @@ -2074,6 +2079,7 @@ libxml_xmlDebugCheckDocument(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); c_retval = xmlDebugCheckDocument(output, doc); + PyFile_Release(output); py_retval = libxml_intWrap((int) c_retval); return(py_retval); } @@ -2094,6 +2100,7 @@ libxml_xmlDebugDumpAttr(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { attr = (xmlAttrPtr) PyxmlNode_Get(pyobj_attr); xmlDebugDumpAttr(output, attr, depth); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2114,6 +2121,7 @@ libxml_xmlDebugDumpAttrList(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { attr = (xmlAttrPtr) PyxmlNode_Get(pyobj_attr); xmlDebugDumpAttrList(output, attr, depth); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2133,6 +2141,7 @@ libxml_xmlDebugDumpDTD(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { dtd = (xmlDtdPtr) PyxmlNode_Get(pyobj_dtd); xmlDebugDumpDTD(output, dtd); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2152,6 +2161,7 @@ libxml_xmlDebugDumpDocument(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); xmlDebugDumpDocument(output, doc); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2171,6 +2181,7 @@ libxml_xmlDebugDumpDocumentHead(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); xmlDebugDumpDocumentHead(output, doc); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2190,6 +2201,7 @@ libxml_xmlDebugDumpEntities(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc); xmlDebugDumpEntities(output, doc); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2210,6 +2222,7 @@ libxml_xmlDebugDumpNode(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); xmlDebugDumpNode(output, node, depth); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2230,6 +2243,7 @@ libxml_xmlDebugDumpNodeList(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); xmlDebugDumpNodeList(output, node, depth); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2250,6 +2264,7 @@ libxml_xmlDebugDumpOneNode(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); xmlDebugDumpOneNode(output, node, depth); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2267,6 +2282,7 @@ libxml_xmlDebugDumpString(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { output = (FILE *) PyFile_Get(pyobj_output); xmlDebugDumpString(output, str); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -2380,6 +2396,7 @@ libxml_xmlDocDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); c_retval = xmlDocDump(f, cur); + PyFile_Release(f); py_retval = libxml_intWrap((int) c_retval); return(py_retval); } @@ -2402,6 +2419,7 @@ libxml_xmlDocFormatDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); c_retval = xmlDocFormatDump(f, cur, format); + PyFile_Release(f); py_retval = libxml_intWrap((int) c_retval); return(py_retval); } @@ -2461,6 +2479,7 @@ libxml_xmlElemDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { cur = (xmlNodePtr) PyxmlNode_Get(pyobj_cur); xmlElemDump(f, doc, cur); + PyFile_Release(f); Py_INCREF(Py_None); return(Py_None); } @@ -3639,6 +3658,7 @@ libxml_xmlLsOneNode(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); xmlLsOneNode(output, node); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -4839,7 +4859,7 @@ libxml_xmlParseChunk(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int size; int terminate; - if (!PyArg_ParseTuple(args, (char *)"Ot#ii:xmlParseChunk", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &terminate)) + if (!PyArg_ParseTuple(args, (char *)"Os#ii:xmlParseChunk", &pyobj_ctxt, &chunk, &py_buffsize0, &size, &terminate)) return(NULL); ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt); @@ -5135,7 +5155,7 @@ libxml_xmlParseMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int py_buffsize0; int size; - if (!PyArg_ParseTuple(args, (char *)"t#i:xmlParseMemory", &buffer, &py_buffsize0, &size)) + if (!PyArg_ParseTuple(args, (char *)"s#i:xmlParseMemory", &buffer, &py_buffsize0, &size)) return(NULL); c_retval = xmlParseMemory(buffer, size); @@ -5731,16 +5751,6 @@ libxml_xmlPopInput(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { return(py_retval); } -PyObject * -libxml_xmlPopInputCallbacks(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) { - PyObject *py_retval; - int c_retval; - - c_retval = xmlPopInputCallbacks(); - py_retval = libxml_intWrap((int) c_retval); - return(py_retval); -} - #if defined(LIBXML_TREE_ENABLED) PyObject * libxml_xmlPreviousElementSibling(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { @@ -5772,6 +5782,7 @@ libxml_xmlPrintURI(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { uri = (xmlURIPtr) PyURI_Get(pyobj_uri); xmlPrintURI(stream, uri); + PyFile_Release(stream); Py_INCREF(Py_None); return(Py_None); } @@ -5837,7 +5848,7 @@ libxml_xmlReadMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { char * encoding; int options; - if (!PyArg_ParseTuple(args, (char *)"t#izzi:xmlReadMemory", &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) + if (!PyArg_ParseTuple(args, (char *)"s#izzi:xmlReadMemory", &buffer, &py_buffsize0, &size, &URL, &encoding, &options)) return(NULL); c_retval = xmlReadMemory(buffer, size, URL, encoding, options); @@ -6110,7 +6121,7 @@ libxml_xmlRecoverMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { int py_buffsize0; int size; - if (!PyArg_ParseTuple(args, (char *)"t#i:xmlRecoverMemory", &buffer, &py_buffsize0, &size)) + if (!PyArg_ParseTuple(args, (char *)"s#i:xmlRecoverMemory", &buffer, &py_buffsize0, &size)) return(NULL); c_retval = xmlRecoverMemory(buffer, size); @@ -6202,6 +6213,7 @@ libxml_xmlRegexpPrint(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { regexp = (xmlRegexpPtr) PyxmlReg_Get(pyobj_regexp); xmlRegexpPrint(output, regexp); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -6261,6 +6273,7 @@ libxml_xmlRelaxNGDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { schema = (xmlRelaxNGPtr) PyrelaxNgSchema_Get(pyobj_schema); xmlRelaxNGDump(output, schema); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -6280,6 +6293,7 @@ libxml_xmlRelaxNGDumpTree(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { schema = (xmlRelaxNGPtr) PyrelaxNgSchema_Get(pyobj_schema); xmlRelaxNGDumpTree(output, schema); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -6815,6 +6829,7 @@ libxml_xmlSchemaDump(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { schema = (xmlSchemaPtr) PySchema_Get(pyobj_schema); xmlSchemaDump(output, schema); + PyFile_Release(output); Py_INCREF(Py_None); return(Py_None); } @@ -13930,6 +13945,28 @@ libxml_xmlXPathNextSelf(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) PyObject * +libxml_xmlXPathNodeEval(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + xmlXPathObjectPtr c_retval; + xmlNodePtr node; + PyObject *pyobj_node; + xmlChar * str; + xmlXPathContextPtr ctx; + PyObject *pyobj_ctx; + + if (!PyArg_ParseTuple(args, (char *)"OzO:xmlXPathNodeEval", &pyobj_node, &str, &pyobj_ctx)) + return(NULL); + node = (xmlNodePtr) PyxmlNode_Get(pyobj_node); + ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx); + + c_retval = xmlXPathNodeEval(node, str, ctx); + py_retval = libxml_xmlXPathObjectPtrWrap((xmlXPathObjectPtr) c_retval); + return(py_retval); +} + +#endif /* defined(LIBXML_XPATH_ENABLED) */ +#if defined(LIBXML_XPATH_ENABLED) +PyObject * libxml_xmlXPathNodeSetFreeNs(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { xmlNsPtr ns; PyObject *pyobj_ns; @@ -14212,6 +14249,8 @@ libxml_xmlXPathRegisterNs(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) +#endif +#if defined(LIBXML_XPATH_ENABLED) PyObject * libxml_xmlXPathRegisteredFuncsCleanup(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { xmlXPathContextPtr ctxt; diff --git a/python/libxml2-py.h b/python/libxml2-py.h index acc0e05..ab57087 100644 --- a/python/libxml2-py.h +++ b/python/libxml2-py.h @@ -650,7 +650,6 @@ PyObject * libxml_xmlParserSetValidate(PyObject *self, PyObject *args); PyObject * libxml_xmlPathToURI(PyObject *self, PyObject *args); PyObject * libxml_xmlPedanticParserDefault(PyObject *self, PyObject *args); PyObject * libxml_xmlPopInput(PyObject *self, PyObject *args); -PyObject * libxml_xmlPopInputCallbacks(PyObject *self, PyObject *args); #if defined(LIBXML_TREE_ENABLED) PyObject * libxml_xmlPreviousElementSibling(PyObject *self, PyObject *args); #endif /* defined(LIBXML_TREE_ENABLED) */ @@ -1919,6 +1918,9 @@ PyObject * libxml_xmlXPathNextPrecedingSibling(PyObject *self, PyObject *args); PyObject * libxml_xmlXPathNextSelf(PyObject *self, PyObject *args); #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) +PyObject * libxml_xmlXPathNodeEval(PyObject *self, PyObject *args); +#endif /* defined(LIBXML_XPATH_ENABLED) */ +#if defined(LIBXML_XPATH_ENABLED) PyObject * libxml_xmlXPathNodeSetFreeNs(PyObject *self, PyObject *args); #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) @@ -1967,6 +1969,9 @@ PyObject * libxml_xmlXPathRegisterAllFunctions(PyObject *self, PyObject *args); PyObject * libxml_xmlXPathRegisterNs(PyObject *self, PyObject *args); #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) +PyObject * libxml_xmlXPathRegisterVariable(PyObject *self, PyObject *args); +#endif +#if defined(LIBXML_XPATH_ENABLED) PyObject * libxml_xmlXPathRegisteredFuncsCleanup(PyObject *self, PyObject *args); #endif /* defined(LIBXML_XPATH_ENABLED) */ #if defined(LIBXML_XPATH_ENABLED) diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml index 42f661d..032b44b 100644 --- a/python/libxml2-python-api.xml +++ b/python/libxml2-python-api.xml @@ -10,6 +10,15 @@ <arg name='ns_uri' type='xmlChar *' info='the namespace or NULL'/> <arg name='f' type='pythonObject' info='the python function'/> </function> + <function name='xmlXPathRegisterVariable' file='python'> + <cond>defined(LIBXML_XPATH_ENABLED)</cond> + <info>Register a variable with the XPath context</info> + <return type='int' info="1 in case of success, 0 or -1 in case of error"/> + <arg name='ctx' type='xmlXPathContextPtr' info='the xpathContext'/> + <arg name='name' type='xmlChar *' info='the variable name'/> + <arg name='ns_uri' type='xmlChar *' info='the namespace or NULL'/> + <arg name='value' type='pythonObject' info='the value'/> + </function> <function name='xmlNewNode' file='python'> <info>Create a new Node</info> <return type='xmlNodePtr' info="A new element node"/> diff --git a/python/libxml2.py b/python/libxml2.py index 086389b..9712d16 100644 --- a/python/libxml2.py +++ b/python/libxml2.py @@ -5,13 +5,23 @@ import sys # The root of all libxml2 errors. class libxmlError(Exception): pass +# Type of the wrapper class for the C objects wrappers +def checkWrapper(obj): + try: + n = type(_obj).__name__ + if n != 'PyCObject' and n != 'PyCapsule': + return 1 + except: + return 0 + return 0 + # # id() is sometimes negative ... # def pos_id(o): i = id(o) if (i < 0): - return (sys.maxint - i) + return (sys.maxsize - i) return i # @@ -62,9 +72,20 @@ class ioWrapper: def io_read(self, len = -1): if self.__io == None: return(-1) - if len < 0: - return(self.__io.read()) - return(self.__io.read(len)) + try: + if len < 0: + ret = self.__io.read() + else: + ret = self.__io.read(len) + except Exception: + import sys + e = sys.exc_info()[1] + print("failed to read from Python:", type(e)) + print("on IO:", self.__io) + self.__io == None + return(-1) + + return(ret) def io_write(self, str, len = -1): if self.__io == None: @@ -79,7 +100,7 @@ class ioReadWrapper(ioWrapper): self._o = libxml2mod.xmlCreateInputBuffer(self, enc) def __del__(self): - print "__del__" + print("__del__") self.io_close() if self._o != None: libxml2mod.xmlFreeParserInputBuffer(self._o) @@ -95,12 +116,19 @@ class ioWriteWrapper(ioWrapper): def __init__(self, _obj, enc = ""): # print "ioWriteWrapper.__init__", _obj if type(_obj) == type(''): - print "write io from a string" + print("write io from a string") self.o = None - elif type(_obj) == types.InstanceType: - print "write io from instance of %s" % (_obj.__class__) - ioWrapper.__init__(self, _obj) - self._o = libxml2mod.xmlCreateOutputBuffer(self, enc) + elif type(_obj).__name__ == 'PyCapsule': + file = libxml2mod.outputBufferGetPythonFile(_obj) + if file != None: + ioWrapper.__init__(self, file) + else: + ioWrapper.__init__(self, _obj) + self._o = _obj +# elif type(_obj) == types.InstanceType: +# print(("write io from instance of %s" % (_obj.__class__))) +# ioWrapper.__init__(self, _obj) +# self._o = libxml2mod.xmlCreateOutputBuffer(self, enc) else: file = libxml2mod.outputBufferGetPythonFile(_obj) if file != None: @@ -265,22 +293,22 @@ class xmlCore: ret = libxml2mod.parent(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_children(self): ret = libxml2mod.children(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_last(self): ret = libxml2mod.last(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_next(self): ret = libxml2mod.next(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_properties(self): ret = libxml2mod.properties(self._o) if ret == None: @@ -290,7 +318,7 @@ class xmlCore: ret = libxml2mod.prev(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) def get_content(self): return libxml2mod.xmlNodeGetContent(self._o) getContent = get_content # why is this duplicate naming needed ? @@ -317,7 +345,7 @@ class xmlCore: ret = libxml2mod.parent(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "properties": ret = libxml2mod.properties(self._o) if ret == None: @@ -327,22 +355,22 @@ class xmlCore: ret = libxml2mod.children(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "last": ret = libxml2mod.last(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "next": ret = libxml2mod.next(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "prev": ret = libxml2mod.prev(self._o) if ret == None: return None - return xmlNode(_obj=ret) + return nodeWrap(ret) elif attr == "content": return libxml2mod.xmlNodeGetContent(self._o) elif attr == "name": @@ -357,7 +385,7 @@ class xmlCore: else: return None return xmlDoc(_obj=ret) - raise AttributeError,attr + raise AttributeError(attr) else: parent = property(get_parent, None, None, "Parent node") children = property(get_children, None, None, "First child node") @@ -400,7 +428,7 @@ class xmlCore: prefixes=None, with_comments=0): if nodes: - nodes = map(lambda n: n._o, nodes) + nodes = [n._o for n in nodes] return libxml2mod.xmlC14NDocDumpMemory( self.get_doc()._o, nodes, @@ -414,7 +442,7 @@ class xmlCore: prefixes=None, with_comments=0): if nodes: - nodes = map(lambda n: n._o, nodes) + nodes = [n._o for n in nodes] return libxml2mod.xmlC14NDocSaveTo( self.get_doc()._o, nodes, @@ -564,10 +592,10 @@ def nodeWrap(o): def xpathObjectRet(o): otype = type(o) if otype == type([]): - ret = map(xpathObjectRet, o) + ret = list(map(xpathObjectRet, o)) return ret elif otype == type(()): - ret = map(xpathObjectRet, o) + ret = list(map(xpathObjectRet, o)) return tuple(ret) elif otype == type('') or otype == type(0) or otype == type(0.0): return o @@ -603,7 +631,7 @@ def registerErrorHandler(f, ctx): """Register a Python written function to for error reporting. The function is called back as f(ctx, error). """ import sys - if not sys.modules.has_key('libxslt'): + if 'libxslt' not in sys.modules: # normal behaviour when libxslt is not imported ret = libxml2mod.xmlRegisterErrorHandler(f,ctx) else: @@ -682,8 +710,9 @@ class relaxNgValidCtxtCore: libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg) -def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator): +def _xmlTextReaderErrorFunc(xxx_todo_changeme,msg,severity,locator): """Intermediate callback to wrap the locator""" + (f,arg) = xxx_todo_changeme return f(arg,msg,severity,xmlTextReaderLocator(locator)) class xmlTextReaderCore: @@ -719,11 +748,35 @@ class xmlTextReaderCore: return arg # -# The cleanup now goes though a wrappe in libxml.c +# The cleanup now goes though a wrapper in libxml.c # def cleanupParser(): libxml2mod.xmlPythonCleanupParser() +# +# The interface to xmlRegisterInputCallbacks. +# Since this API does not allow to pass a data object along with +# match/open callbacks, it is necessary to maintain a list of all +# Python callbacks. +# +__input_callbacks = [] +def registerInputCallback(func): + def findOpenCallback(URI): + for cb in reversed(__input_callbacks): + o = cb(URI) + if o is not None: + return o + libxml2mod.xmlRegisterInputCallback(findOpenCallback) + __input_callbacks.append(func) + +def popInputCallbacks(): + # First pop python-level callbacks, when no more available - start + # popping built-in ones. + if len(__input_callbacks) > 0: + __input_callbacks.pop() + if len(__input_callbacks) == 0: + libxml2mod.xmlUnregisterInputCallback() + # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # # Everything before this line comes from libxml.py @@ -866,6 +919,7 @@ def catalogConvert(): def catalogDump(out): """Dump all the global catalog content to the given file. """ + if out is not None: out.flush() libxml2mod.xmlCatalogDump(out) def catalogGetPublic(pubID): @@ -1025,6 +1079,7 @@ def boolToText(boolval): def debugDumpString(output, str): """Dumps informations about the string, shorten it if necessary """ + if output is not None: output.flush() libxml2mod.xmlDebugDumpString(output, str) def shellPrintXPathError(errorType, arg): @@ -1042,8 +1097,7 @@ def dictCleanup(): def initializeDict(): """Do the dictionary mutex initialization. this function is - not thread safe, initialization should preferably be done - once at startup """ + deprecated """ ret = libxml2mod.xmlInitializeDict() return ret @@ -1850,12 +1904,6 @@ def parserGetDirectory(filename): ret = libxml2mod.xmlParserGetDirectory(filename) return ret -def popInputCallbacks(): - """Clear the top input callback from the input stack. this - includes the compiled-in I/O. """ - ret = libxml2mod.xmlPopInputCallbacks() - return ret - def registerDefaultInputCallbacks(): """Registers the default compiled-in I/O handlers. """ libxml2mod.xmlRegisterDefaultInputCallbacks() @@ -2966,13 +3014,12 @@ def valuePop(ctxt): class xmlNode(xmlCore): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlNode needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlNode got a wrong wrapper object type') self._o = _obj xmlCore.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlNode (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlNode (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # accessors for xmlNode def ns(self): @@ -3671,6 +3718,16 @@ class xmlNode(xmlCore): ret = libxml2mod.xmlXPathCmpNodes(self._o, node2__o) return ret + def xpathNodeEval(self, str, ctx): + """Evaluate the XPath Location Path in the given context. The + node 'node' is set as the context node. The context node is + not restored. """ + if ctx is None: ctx__o = None + else: ctx__o = ctx._o + ret = libxml2mod.xmlXPathNodeEval(self._o, str, ctx__o) + if ret is None:raise xpathError('xmlXPathNodeEval() failed') + return xpathObjectRet(ret) + # # xmlNode functions from module xpathInternals # @@ -3901,13 +3958,12 @@ class xmlNode(xmlCore): class xmlDoc(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlDoc needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlDoc got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlDoc (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlDoc (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlDoc functions from module HTMLparser @@ -5503,13 +5559,12 @@ class parserCtxt(parserCtxtCore): class xmlAttr(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlAttr needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlAttr got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlAttr (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlAttr (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlAttr functions from module debugXML @@ -5582,13 +5637,12 @@ class xmlAttr(xmlNode): class xmlAttribute(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlAttribute needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlAttribute got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlAttribute (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlAttribute (%s) object at 0x%x>" % (self.name, int(pos_id (self))) class catalog: def __init__(self, _obj=None): @@ -5652,13 +5706,12 @@ class catalog: class xmlDtd(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlDtd needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlDtd got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlDtd (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlDtd (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlDtd functions from module debugXML @@ -5719,23 +5772,21 @@ class xmlDtd(xmlNode): class xmlElement(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlElement needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlElement got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlElement (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlElement (%s) object at 0x%x>" % (self.name, int(pos_id (self))) class xmlEntity(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlEntity needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlEntity got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlEntity (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlEntity (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlEntity functions from module parserInternals @@ -5802,13 +5853,12 @@ class Error: class xmlNs(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlNs needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlNs got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlNs (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlNs (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlNs functions from module tree @@ -7259,6 +7309,11 @@ class xpathContext: ret = libxml2mod.xmlRegisterXPathFunction(self._o, name, ns_uri, f) return ret + def xpathRegisterVariable(self, name, ns_uri, value): + """Register a variable with the XPath context """ + ret = libxml2mod.xmlXPathRegisterVariable(self._o, name, ns_uri, value) + return ret + # # xpathContext functions from module xpath # @@ -8165,6 +8220,7 @@ XML_WAR_ENTITY_REDEFINED = 107 XML_ERR_UNKNOWN_VERSION = 108 XML_ERR_VERSION_MISMATCH = 109 XML_ERR_NAME_TOO_LONG = 110 +XML_ERR_USER_STOP = 111 XML_NS_ERR_XML_NAMESPACE = 200 XML_NS_ERR_UNDEFINED_NAMESPACE = 201 XML_NS_ERR_QNAME = 202 diff --git a/python/libxml2class.py b/python/libxml2class.py index 96e8c3f..48aa7ba 100644 --- a/python/libxml2class.py +++ b/python/libxml2class.py @@ -133,6 +133,7 @@ def catalogConvert(): def catalogDump(out): """Dump all the global catalog content to the given file. """ + if out is not None: out.flush() libxml2mod.xmlCatalogDump(out) def catalogGetPublic(pubID): @@ -292,6 +293,7 @@ def boolToText(boolval): def debugDumpString(output, str): """Dumps informations about the string, shorten it if necessary """ + if output is not None: output.flush() libxml2mod.xmlDebugDumpString(output, str) def shellPrintXPathError(errorType, arg): @@ -309,8 +311,7 @@ def dictCleanup(): def initializeDict(): """Do the dictionary mutex initialization. this function is - not thread safe, initialization should preferably be done - once at startup """ + deprecated """ ret = libxml2mod.xmlInitializeDict() return ret @@ -1117,12 +1118,6 @@ def parserGetDirectory(filename): ret = libxml2mod.xmlParserGetDirectory(filename) return ret -def popInputCallbacks(): - """Clear the top input callback from the input stack. this - includes the compiled-in I/O. """ - ret = libxml2mod.xmlPopInputCallbacks() - return ret - def registerDefaultInputCallbacks(): """Registers the default compiled-in I/O handlers. """ libxml2mod.xmlRegisterDefaultInputCallbacks() @@ -2233,13 +2228,12 @@ def valuePop(ctxt): class xmlNode(xmlCore): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlNode needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlNode got a wrong wrapper object type') self._o = _obj xmlCore.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlNode (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlNode (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # accessors for xmlNode def ns(self): @@ -2938,6 +2932,16 @@ class xmlNode(xmlCore): ret = libxml2mod.xmlXPathCmpNodes(self._o, node2__o) return ret + def xpathNodeEval(self, str, ctx): + """Evaluate the XPath Location Path in the given context. The + node 'node' is set as the context node. The context node is + not restored. """ + if ctx is None: ctx__o = None + else: ctx__o = ctx._o + ret = libxml2mod.xmlXPathNodeEval(self._o, str, ctx__o) + if ret is None:raise xpathError('xmlXPathNodeEval() failed') + return xpathObjectRet(ret) + # # xmlNode functions from module xpathInternals # @@ -3168,13 +3172,12 @@ class xmlNode(xmlCore): class xmlDoc(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlDoc needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlDoc got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlDoc (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlDoc (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlDoc functions from module HTMLparser @@ -4770,13 +4773,12 @@ class parserCtxt(parserCtxtCore): class xmlAttr(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlAttr needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlAttr got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlAttr (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlAttr (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlAttr functions from module debugXML @@ -4849,13 +4851,12 @@ class xmlAttr(xmlNode): class xmlAttribute(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlAttribute needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlAttribute got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlAttribute (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlAttribute (%s) object at 0x%x>" % (self.name, int(pos_id (self))) class catalog: def __init__(self, _obj=None): @@ -4919,13 +4920,12 @@ class catalog: class xmlDtd(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlDtd needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlDtd got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlDtd (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlDtd (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlDtd functions from module debugXML @@ -4986,23 +4986,21 @@ class xmlDtd(xmlNode): class xmlElement(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlElement needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlElement got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlElement (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlElement (%s) object at 0x%x>" % (self.name, int(pos_id (self))) class xmlEntity(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlEntity needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlEntity got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlEntity (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlEntity (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlEntity functions from module parserInternals @@ -5069,13 +5067,12 @@ class Error: class xmlNs(xmlNode): def __init__(self, _obj=None): - if type(_obj).__name__ != 'PyCObject': - raise TypeError, 'xmlNs needs a PyCObject argument' + if checkWrapper(_obj) != 0: raise TypeError('xmlNs got a wrong wrapper object type') self._o = _obj xmlNode.__init__(self, _obj=_obj) def __repr__(self): - return "<xmlNs (%s) object at 0x%x>" % (self.name, long(pos_id (self))) + return "<xmlNs (%s) object at 0x%x>" % (self.name, int(pos_id (self))) # # xmlNs functions from module tree @@ -6526,6 +6523,11 @@ class xpathContext: ret = libxml2mod.xmlRegisterXPathFunction(self._o, name, ns_uri, f) return ret + def xpathRegisterVariable(self, name, ns_uri, value): + """Register a variable with the XPath context """ + ret = libxml2mod.xmlXPathRegisterVariable(self._o, name, ns_uri, value) + return ret + # # xpathContext functions from module xpath # @@ -7432,6 +7434,7 @@ XML_WAR_ENTITY_REDEFINED = 107 XML_ERR_UNKNOWN_VERSION = 108 XML_ERR_VERSION_MISMATCH = 109 XML_ERR_NAME_TOO_LONG = 110 +XML_ERR_USER_STOP = 111 XML_NS_ERR_XML_NAMESPACE = 200 XML_NS_ERR_UNDEFINED_NAMESPACE = 201 XML_NS_ERR_QNAME = 202 diff --git a/python/libxml2class.txt b/python/libxml2class.txt index b16567c..ca88544 100644 --- a/python/libxml2class.txt +++ b/python/libxml2class.txt @@ -209,7 +209,6 @@ iOFTPMatch() iOHTTPMatch() normalizeWindowsPath() parserGetDirectory() -popInputCallbacks() registerDefaultInputCallbacks() registerDefaultOutputCallbacks() registerHTTPPostCallbacks() @@ -523,6 +522,7 @@ Class xmlNode(xmlCore) xpathCastNodeToNumber() xpathCastNodeToString() xpathCmpNodes() + xpathNodeEval() # functions from module xpathInternals xpathNewNodeSet() @@ -1087,6 +1087,7 @@ Class xpathContext() # functions from module python registerXPathFunction() + xpathRegisterVariable() # functions from module xpath xpathContextSetCache() diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h index eaa5e96..a9b9739 100644 --- a/python/libxml_wrap.h +++ b/python/libxml_wrap.h @@ -23,6 +23,25 @@ #include <libxml/xmlschemas.h> #endif +/* + * 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 + +#define PyCapsule_New PyCObject_FromVoidPtrAndDesc +#define PyCapsule_CheckExact PyCObject_Check +#define PyCapsule_GetPointer(o, n) PyCObject_GetDesc((o)) + +#endif +#endif + /** * ATTRIBUTE_UNUSED: * @@ -150,8 +169,16 @@ typedef struct { } PyURI_Object; /* FILE * have their own internal representation */ +#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 #ifdef LIBXML_SCHEMAS_ENABLED typedef struct { @@ -247,3 +274,6 @@ PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid); #endif /* LIBXML_SCHEMAS_ENABLED */ PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error); PyObject * libxml_xmlSchemaSetValidErrors(PyObject * self, PyObject * args); +PyObject * libxml_xmlRegisterInputCallback(PyObject *self, PyObject *args); +PyObject * libxml_xmlUnregisterInputCallback(PyObject *self, PyObject *args); +PyObject * libxml_xmlNodeRemoveNsDef(PyObject * self, PyObject * args); diff --git a/python/setup.py b/python/setup.py index 7cb8bfc..f24674c 100755 --- a/python/setup.py +++ b/python/setup.py @@ -32,7 +32,7 @@ except: if WITHDLLS: # libxml dlls (expected in ROOT/bin) dlls = [ 'iconv.dll','libxml2.dll','libxslt.dll','libexslt.dll' ] - dlls = map(lambda dll: os.path.join(ROOT,'bin',dll),dlls) + dlls = [os.path.join(ROOT,'bin',dll) for dll in dlls] # create __init__.py for the libxmlmods package if not os.path.exists("libxmlmods"): @@ -70,7 +70,7 @@ for dir in includes_dir: break; if xml_includes == "": - print "failed to find headers for libxml2: update includes_dir" + print("failed to find headers for libxml2: update includes_dir") sys.exit(1) iconv_includes="" @@ -80,7 +80,7 @@ for dir in includes_dir: break; if iconv_includes == "": - print "failed to find headers for libiconv: update includes_dir" + print("failed to find headers for libiconv: update includes_dir") sys.exit(1) # those are added in the linker search path for libraries @@ -103,8 +103,8 @@ if missing("libxml2-py.c") or missing("libxml2.py"): except: import generator except: - print "failed to find and generate stubs for libxml2, aborting ..." - print sys.exc_type, sys.exc_value + print("failed to find and generate stubs for libxml2, aborting ...") + print(sys.exc_info()[0], sys.exc_info()[1]) sys.exit(1) head = open("libxml.py", "r") @@ -124,13 +124,13 @@ if missing("libxml2-py.c") or missing("libxml2.py"): with_xslt=0 if missing("libxslt-py.c") or missing("libxslt.py"): if missing("xsltgenerator.py") or missing("libxslt-api.xml"): - print "libxslt stub generator not found, libxslt not built" + print("libxslt stub generator not found, libxslt not built") else: try: import xsltgenerator except: - print "failed to generate stubs for libxslt, aborting ..." - print sys.exc_type, sys.exc_value + print("failed to generate stubs for libxslt, aborting ...") + print(sys.exc_info()[0], sys.exc_info()[1]) else: head = open("libxsl.py", "r") generated = open("libxsltclass.py", "r") @@ -157,7 +157,7 @@ if with_xslt == 1: break; if xslt_includes == "": - print "failed to find headers for libxslt: update includes_dir" + print("failed to find headers for libxslt: update includes_dir") with_xslt = 0 @@ -226,7 +226,7 @@ else: setup (name = "libxml2-python", # On *nix, the version number is created from setup.py.in # On windows, it is set by configure.js - version = "2.9.0", + version = "2.9.1", description = descr, author = "Daniel Veillard", author_email = "veillard@redhat.com", diff --git a/python/setup.py.in b/python/setup.py.in index 7eaf530..0e72338 100755 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -32,7 +32,7 @@ except: if WITHDLLS: # libxml dlls (expected in ROOT/bin) dlls = [ 'iconv.dll','libxml2.dll','libxslt.dll','libexslt.dll' ] - dlls = map(lambda dll: os.path.join(ROOT,'bin',dll),dlls) + dlls = [os.path.join(ROOT,'bin',dll) for dll in dlls] # create __init__.py for the libxmlmods package if not os.path.exists("libxmlmods"): @@ -70,7 +70,7 @@ for dir in includes_dir: break; if xml_includes == "": - print "failed to find headers for libxml2: update includes_dir" + print("failed to find headers for libxml2: update includes_dir") sys.exit(1) iconv_includes="" @@ -80,7 +80,7 @@ for dir in includes_dir: break; if iconv_includes == "": - print "failed to find headers for libiconv: update includes_dir" + print("failed to find headers for libiconv: update includes_dir") sys.exit(1) # those are added in the linker search path for libraries @@ -103,8 +103,8 @@ if missing("libxml2-py.c") or missing("libxml2.py"): except: import generator except: - print "failed to find and generate stubs for libxml2, aborting ..." - print sys.exc_type, sys.exc_value + print("failed to find and generate stubs for libxml2, aborting ...") + print(sys.exc_info()[0], sys.exc_info()[1]) sys.exit(1) head = open("libxml.py", "r") @@ -124,13 +124,13 @@ if missing("libxml2-py.c") or missing("libxml2.py"): with_xslt=0 if missing("libxslt-py.c") or missing("libxslt.py"): if missing("xsltgenerator.py") or missing("libxslt-api.xml"): - print "libxslt stub generator not found, libxslt not built" + print("libxslt stub generator not found, libxslt not built") else: try: import xsltgenerator except: - print "failed to generate stubs for libxslt, aborting ..." - print sys.exc_type, sys.exc_value + print("failed to generate stubs for libxslt, aborting ...") + print(sys.exc_info()[0], sys.exc_info()[1]) else: head = open("libxsl.py", "r") generated = open("libxsltclass.py", "r") @@ -157,7 +157,7 @@ if with_xslt == 1: break; if xslt_includes == "": - print "failed to find headers for libxslt: update includes_dir" + print("failed to find headers for libxslt: update includes_dir") with_xslt = 0 diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am index ab079bb..95ebead 100644 --- a/python/tests/Makefile.am +++ b/python/tests/Makefile.am @@ -19,6 +19,7 @@ PYTESTS= \ xpath.py \ outbuf.py \ inbuf.py \ + input_callback.py \ resolver.py \ regexp.py \ reader.py \ diff --git a/python/tests/Makefile.in b/python/tests/Makefile.in index 699d403..132538f 100644 --- a/python/tests/Makefile.in +++ b/python/tests/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -16,6 +16,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -56,6 +73,11 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -182,7 +204,6 @@ RANLIB = @RANLIB@ RDL_LIBS = @RDL_LIBS@ READER_TEST = @READER_TEST@ RELDATE = @RELDATE@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -239,6 +260,7 @@ WITH_SAX1 = @WITH_SAX1@ WITH_SCHEMAS = @WITH_SCHEMAS@ WITH_SCHEMATRON = @WITH_SCHEMATRON@ WITH_THREADS = @WITH_THREADS@ +WITH_THREAD_ALLOC = @WITH_THREAD_ALLOC@ WITH_TREE = @WITH_TREE@ WITH_TRIO = @WITH_TRIO@ WITH_VALID = @WITH_VALID@ @@ -332,6 +354,7 @@ PYTESTS = \ xpath.py \ outbuf.py \ inbuf.py \ + input_callback.py \ resolver.py \ regexp.py \ reader.py \ @@ -410,8 +433,11 @@ clean-libtool: -rm -rf .libs _libs install-dist_exampleDATA: $(dist_example_DATA) @$(NORMAL_INSTALL) - test -z "$(exampledir)" || $(MKDIR_P) "$(DESTDIR)$(exampledir)" @list='$(dist_example_DATA)'; test -n "$(exampledir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ diff --git a/python/tests/attribs.py b/python/tests/attribs.py index 9331a27..99132c2 100755 --- a/python/tests/attribs.py +++ b/python/tests/attribs.py @@ -20,7 +20,7 @@ doc = libxml2.parseDoc( elem = doc.getRootElement() attr = elem.hasNsProp('attr', 'http://abc.org') if attr == None or attr.serialize()[:-1] != """<!ATTLIST test abc:attr CDATA #FIXED "def">""": - print "Failed to find defaulted attribute abc:attr" + print("Failed to find defaulted attribute abc:attr") sys.exit(1) doc.freeDoc() @@ -28,7 +28,7 @@ doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/build.py b/python/tests/build.py index bfc776c..b2d3f78 100755 --- a/python/tests/build.py +++ b/python/tests/build.py @@ -23,29 +23,29 @@ doc = libxml2.parseFile("tmp.xml") comment = doc.children if comment.type != "comment" or \ comment.content != "This is a generated document": - print "error rereading comment" + print("error rereading comment") sys.exit(1) pi = comment.next if pi.type != "pi" or pi.name != "test" or pi.content != "PI content": - print "error rereading PI" + print("error rereading PI") sys.exit(1) root = pi.next if root.name != "doc": - print "error rereading root" + print("error rereading root") sys.exit(1) ns = root.ns() if ns.name != "my" or ns.content != "http://example.com/doc": - print "error rereading namespace" + print("error rereading namespace") sys.exit(1) elem = root.children if elem.name != "foo": - print "error rereading elem" + print("error rereading elem") sys.exit(1) if elem.getBase(None) != "http://example.com/imgs": - print "error rereading base" + print("error rereading base") sys.exit(1) if elem.prop("img") != "image.gif": - print "error rereading property" + print("error rereading property") sys.exit(1) doc.freeDoc() @@ -53,7 +53,7 @@ doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/compareNodes.py b/python/tests/compareNodes.py index ec04323..ca5a5a2 100755 --- a/python/tests/compareNodes.py +++ b/python/tests/compareNodes.py @@ -17,25 +17,25 @@ foonode2 = root.children # Now check that [in]equality tests work ok if not ( foonode1 == foonode2 ): - print "Error comparing nodes with ==, nodes should be equal but are unequal" + print("Error comparing nodes with ==, nodes should be equal but are unequal") sys.exit(1) if not ( foonode1 != root ): - print "Error comparing nodes with ==, nodes should not be equal but are equal" + print("Error comparing nodes with ==, nodes should not be equal but are equal") sys.exit(1) if not ( foonode1 != root ): - print "Error comparing nodes with !=, nodes should not be equal but are equal" + print("Error comparing nodes with !=, nodes should not be equal but are equal") if ( foonode1 != foonode2 ): - print "Error comparing nodes with !=, nodes should be equal but are unequal" + print("Error comparing nodes with !=, nodes should be equal but are unequal") # Next check that the hash function for the objects also works ok if not (hash(foonode1) == hash(foonode2)): - print "Error hash values for two equal nodes are different" + print("Error hash values for two equal nodes are different") sys.exit(1) if not (hash(foonode1) != hash(root)): - print "Error hash values for two unequal nodes are not different" + print("Error hash values for two unequal nodes are not different") sys.exit(1) if hash(foonode1) == hash(root): - print "Error hash values for two unequal nodes are equal" + print("Error hash values for two unequal nodes are equal") sys.exit(1) # Basic tests successful @@ -44,7 +44,7 @@ doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/ctxterror.py b/python/tests/ctxterror.py index f2a897a..416e384 100755 --- a/python/tests/ctxterror.py +++ b/python/tests/ctxterror.py @@ -23,7 +23,7 @@ s = """<x xmlns="foo"></y>""" parserCtxt = libxml2.createPushParser(None,"",0,"test.xml") parserCtxt.setErrorHandler(callback, "-->") if parserCtxt.getErrorHandler() != (callback,"-->"): - print "getErrorHandler failed" + print("getErrorHandler failed") sys.exit(1) parserCtxt.parseChunk(s,len(s),1) doc = parserCtxt.doc() @@ -31,9 +31,9 @@ doc.freeDoc() parserCtxt = None if err != expect: - print "error" - print "received %s" %(err) - print "expected %s" %(expect) + print("error") + print("received %s" %(err)) + print("expected %s" %(expect)) sys.exit(1) i = 10000 @@ -50,7 +50,7 @@ while i > 0: # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/cutnpaste.py b/python/tests/cutnpaste.py index 0f9665a..7787246 100755 --- a/python/tests/cutnpaste.py +++ b/python/tests/cutnpaste.py @@ -35,14 +35,14 @@ source.freeDoc() # check the resulting tree str = dest.serialize() if str != """<root xmlns:foobar="http://example.org/bar" xmlns:default="http://example.org/include" xmlns:foo="http://example.org/foo"><default:fragment><foo:elem bar="tricky"/></default:fragment></root>""": - print "reconciliateNs() failed" + print("reconciliateNs() failed") sys.exit(1) target.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/dtdvalid.py b/python/tests/dtdvalid.py index 2011f2c..d4049b8 100755 --- a/python/tests/dtdvalid.py +++ b/python/tests/dtdvalid.py @@ -14,7 +14,7 @@ ctxt = libxml2.newValidCtxt() doc = libxml2.parseDoc(instance) ret = doc.validateDtd(ctxt, dtd) if ret != 1: - print "error doing DTD validation" + print("error doing DTD validation") sys.exit(1) doc.freeDoc() @@ -25,8 +25,8 @@ del ctxt # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/error.py b/python/tests/error.py index da6d0c1..530c2ee 100755 --- a/python/tests/error.py +++ b/python/tests/error.py @@ -24,13 +24,13 @@ except libxml2.parserError: got_exc = 1 if got_exc == 0: - print "Failed to get a parser exception" + print("Failed to get a parser exception") sys.exit(1) if err != expect: - print "error" - print "received %s" %(err) - print "expected %s" %(expect) + print("error") + print("received %s" %(err)) + print("expected %s" %(expect)) sys.exit(1) i = 10000 @@ -45,7 +45,7 @@ while i > 0: # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/inbuf.py b/python/tests/inbuf.py index a7cc7a6..0c16674 100755 --- a/python/tests/inbuf.py +++ b/python/tests/inbuf.py @@ -1,14 +1,19 @@ #!/usr/bin/python -u import sys import libxml2 -import StringIO +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) i = 0 while i < 5000: - f = StringIO.StringIO("foobar") + f = str_io("foobar") buf = libxml2.inputBuffer(f) i = i + 1 @@ -18,8 +23,8 @@ del buf # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/indexes.py b/python/tests/indexes.py index 8d7a7fc..e41a0d9 100755 --- a/python/tests/indexes.py +++ b/python/tests/indexes.py @@ -20,16 +20,16 @@ class callback: def startDocument(self): global ctxt if ctxt.byteConsumed() != self.startd: - print "document start at wrong index: %d expecting %d\n" % ( - ctxt.byteConsumed(), self.startd) + print("document start at wrong index: %d expecting %d\n" % ( + ctxt.byteConsumed(), self.startd)) sys.exit(1) def endDocument(self): global ctxt expect = self.ende + self.delta * (self.count - 1) + self.endd if ctxt.byteConsumed() != expect: - print "document end at wrong index: %d expecting %d\n" % ( - ctxt.byteConsumed(), expect) + print("document end at wrong index: %d expecting %d\n" % ( + ctxt.byteConsumed(), expect)) sys.exit(1) def startElement(self, tag, attrs): @@ -37,8 +37,8 @@ class callback: if tag == "bar1": expect = self.starte + self.delta * self.count if ctxt.byteConsumed() != expect: - print "element start at wrong index: %d expecting %d\n" % ( - ctxt.byteConsumed(), expect) + print("element start at wrong index: %d expecting %d\n" % ( + ctxt.byteConsumed(), expect)) sys.exit(1) @@ -47,8 +47,8 @@ class callback: if tag == "bar1": expect = self.ende + self.delta * self.count if ctxt.byteConsumed() != expect: - print "element end at wrong index: %d expecting %d\n" % ( - ctxt.byteConsumed(), expect) + print("element end at wrong index: %d expecting %d\n" % ( + ctxt.byteConsumed(), expect)) sys.exit(1) self.count = self.count + 1 @@ -107,7 +107,7 @@ ctxt=None # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/input_callback.py b/python/tests/input_callback.py new file mode 100755 index 0000000..495ab62 --- /dev/null +++ b/python/tests/input_callback.py @@ -0,0 +1,148 @@ +#!/usr/bin/python -u +# +# This tests custom input callbacks +# +import sys +import libxml2 +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO + +# We implement a new scheme, py://strings/ that will reference this dictionary +pystrings = { + 'catalogs/catalog.xml' : +'''<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <rewriteSystem systemIdStartString="http://example.com/dtds/" rewritePrefix="../dtds/"/> +</catalog>''', + + 'xml/sample.xml' : +'''<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE root SYSTEM "http://example.com/dtds/sample.dtd"> +<root>&sample.entity;</root>''', + + 'dtds/sample.dtd' : +''' +<!ELEMENT root (#PCDATA)> +<!ENTITY sample.entity "replacement text">''' +} + +prefix = "py://strings/" +startURL = prefix + "xml/sample.xml" +catURL = prefix + "catalogs/catalog.xml" + +def my_input_cb(URI): + if not(URI.startswith(prefix)): + return None + path = URI[len(prefix):] + if path not in pystrings: + return None + return str_io(pystrings[path]) + + +def run_test(desc, docpath, catalog, exp_status="verified", exp_err=[], test_callback=None, + root_name="root", root_content="replacement text"): + opts = libxml2.XML_PARSE_DTDLOAD | libxml2.XML_PARSE_NONET | libxml2.XML_PARSE_COMPACT + actual_err = [] + + def my_global_error_cb(ctx, msg): + actual_err.append((-1, msg)) + def my_ctx_error_cb(arg, msg, severity, reserved): + actual_err.append((severity, msg)) + + libxml2.registerErrorHandler(my_global_error_cb, None) + try: + parser = libxml2.createURLParserCtxt(docpath, opts) + parser.setErrorHandler(my_ctx_error_cb, None) + if catalog is not None: + parser.addLocalCatalog(catalog) + if test_callback is not None: + test_callback() + parser.parseDocument() + doc = parser.doc() + actual_status = "loaded" + e = doc.getRootElement() + if e.name == root_name and e.content == root_content: + actual_status = "verified" + doc.freeDoc() + except libxml2.parserError: + actual_status = "not loaded" + + if actual_status != exp_status: + print("Test '%s' failed: expect status '%s', actual '%s'" % (desc, exp_status, actual_status)) + sys.exit(1) + elif actual_err != exp_err: + print("Test '%s' failed" % desc) + print("Expect errors:") + for s,m in exp_err: print(" [%2d] '%s'" % (s,m)) + print("Actual errors:") + for s,m in actual_err: print(" [%2d] '%s'" % (s,m)) + sys.exit(1) + + +# Check that we cannot read custom schema without custom callback +run_test(desc="Loading entity without custom callback", + docpath=startURL, catalog=None, + exp_status="not loaded", exp_err=[ + (-1, "I/O "), + (-1, "warning : "), + (-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n") + ]) + +# Register handler and try to load the same entity +libxml2.registerInputCallback(my_input_cb) +run_test(desc="Loading entity with custom callback", + docpath=startURL, catalog=None, + exp_status="loaded", exp_err=[ + (-1, "Attempt to load network entity http://example.com/dtds/sample.dtd"), + ( 4, "Entity 'sample.entity' not defined\n") + ]) + +# Register a catalog (also accessible via pystr://) and retry +run_test(desc="Loading entity with custom callback and catalog", + docpath=startURL, catalog=catURL) + +# Unregister custom callback when parser is already created +run_test(desc="Loading entity and unregistering callback", + docpath=startURL, catalog=catURL, + test_callback=lambda: libxml2.popInputCallbacks(), + exp_status="loaded", exp_err=[ + ( 3, "failed to load external entity \"py://strings/dtds/sample.dtd\"\n"), + ( 4, "Entity 'sample.entity' not defined\n") + ]) + +# Try to load the document again +run_test(desc="Retry loading document after unregistering callback", + docpath=startURL, catalog=catURL, + exp_status="not loaded", exp_err=[ + (-1, "I/O "), + (-1, "warning : "), + (-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n") + ]) + +# But should be able to read standard I/O yet... +run_test(desc="Loading using standard i/o after unregistering callback", + docpath="tst.xml", catalog=None, + root_name='doc', root_content='bar') + +# Now pop ALL input callbacks, should fail to load even standard I/O +try: + while True: + libxml2.popInputCallbacks() +except IndexError: + pass + +run_test(desc="Loading using standard i/o after unregistering all callbacks", + docpath="tst.xml", catalog=None, + exp_status="not loaded", exp_err=[ + (-1, "I/O "), + (-1, "warning : "), + (-1, "failed to load external entity \"tst.xml\"\n") + ]) + +print("OK") +sys.exit(0); diff --git a/python/tests/nsdel.py b/python/tests/nsdel.py index c06ded3..079399a 100755 --- a/python/tests/nsdel.py +++ b/python/tests/nsdel.py @@ -19,7 +19,7 @@ def checkNamespaceDefs(node, count): nsList = list(namespaceDefs(node)) #print nsList if len(nsList) != count : - raise Exception, "Error: saw %d namespace declarations. Expected %d" % (len(nsList), count) + raise Exception("Error: saw %d namespace declarations. Expected %d" % (len(nsList), count)) # Memory debug specific libxml2.debugMemory(1) @@ -56,7 +56,7 @@ doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/outbuf.py b/python/tests/outbuf.py index 09cd9b5..62761cc 100755 --- a/python/tests/outbuf.py +++ b/python/tests/outbuf.py @@ -1,17 +1,22 @@ #!/usr/bin/python -u import sys import libxml2 -import StringIO +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO def testSimpleBufferWrites(): - f = StringIO.StringIO() + f = str_io() buf = libxml2.createOutputBuffer(f, "ISO-8859-1") buf.write(3, "foo") buf.writeString("bar") buf.close() - + if f.getvalue() != "foobar": - print "Failed to save to StringIO" + print("Failed to save to StringIO") sys.exit(1) def testSaveDocToBuffer(): @@ -23,15 +28,15 @@ def testSaveDocToBuffer(): <?xml version="1.0" encoding="UTF-8"?> <foo>Hello</foo> ''' - f = StringIO.StringIO() + f = str_io() buf = libxml2.createOutputBuffer(f, 'UTF-8') doc = libxml2.parseDoc(input) doc.saveFileTo(buf, 'UTF-8') doc.freeDoc() if f.getvalue() != expected: - print 'xmlDoc.saveFileTo() call failed.' - print ' got: %s' % repr(f.getvalue()) - print 'expected: %s' % repr(expected) + print('xmlDoc.saveFileTo() call failed.') + print(' got: %s' % repr(f.getvalue())) + print('expected: %s' % repr(expected)) sys.exit(1) def testSaveFormattedDocToBuffer(): @@ -49,13 +54,13 @@ def testSaveFormattedDocToBuffer(): ''') doc = libxml2.parseDoc(input) for i in (0, 1): - f = StringIO.StringIO() + f = str_io() buf = libxml2.createOutputBuffer(f, 'UTF-8') doc.saveFormatFileTo(buf, 'UTF-8', i) if f.getvalue() != expected[i]: - print 'xmlDoc.saveFormatFileTo() call failed.' - print ' got: %s' % repr(f.getvalue()) - print 'expected: %s' % repr(expected[i]) + print('xmlDoc.saveFormatFileTo() call failed.') + print(' got: %s' % repr(f.getvalue())) + print('expected: %s' % repr(expected[i])) sys.exit(1) doc.freeDoc() @@ -69,22 +74,22 @@ def testSaveIntoOutputBuffer(): <?xml version="1.0" encoding="UTF-8"?> <foo>Hello</foo> ''' - f = StringIO.StringIO() + f = str_io() doc = libxml2.parseDoc(input) buf = libxml2.createOutputBuffer(f, 'UTF-8') buf.saveFileTo(doc, 'UTF-8') if f.getvalue() != expected: - print 'outputBuffer.saveFileTo() call failed.' - print ' got: %s' % repr(f.getvalue()) - print 'expected: %s' % repr(expected) + print('outputBuffer.saveFileTo() call failed.') + print(' got: %s' % repr(f.getvalue())) + print('expected: %s' % repr(expected)) sys.exit(1) - f = StringIO.StringIO() + f = str_io() buf = libxml2.createOutputBuffer(f, 'UTF-8') buf.saveFormatFileTo(doc, 'UTF-8', 1) if f.getvalue() != expected: - print 'outputBuffer.saveFormatFileTo() call failed.' - print ' got: %s' % repr(f.getvalue()) - print 'expected: %s' % repr(expected) + print('outputBuffer.saveFormatFileTo() call failed.') + print(' got: %s' % repr(f.getvalue())) + print('expected: %s' % repr(expected)) sys.exit(1) doc.freeDoc() @@ -99,7 +104,7 @@ if __name__ == '__main__': libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/push.py b/python/tests/push.py index 5b60a16..0edd61d 100755 --- a/python/tests/push.py +++ b/python/tests/push.py @@ -10,11 +10,11 @@ ctxt.parseChunk("/>", 2, 1) doc = ctxt.doc() ctxt=None if doc.name != "test.xml": - print "document name error" + print("document name error") sys.exit(1) root = doc.children if root.name != "foo": - print "root element name error" + print("root element name error") sys.exit(1) doc.freeDoc() i = 10000 @@ -29,7 +29,7 @@ ctxt=None # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/pushSAX.py b/python/tests/pushSAX.py index 1c1e786..48f6e82 100755 --- a/python/tests/pushSAX.py +++ b/python/tests/pushSAX.py @@ -51,14 +51,14 @@ ctxt=None reference = "startDocument:startElement foo {'url': 'tst'}:characters: bar:endElement foo:endDocument:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/pushSAXhtml.py b/python/tests/pushSAXhtml.py index e6e89d9..159d308 100755 --- a/python/tests/pushSAXhtml.py +++ b/python/tests/pushSAXhtml.py @@ -52,14 +52,14 @@ ctxt=None reference = """startDocument:startElement html None:startElement body None:startElement foo {'url': 'tst'}:error: Tag foo invalid :characters: bar:endElement foo:endElement body:endElement html:endDocument:""" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader.py b/python/tests/reader.py index 6c37762..173ce66 100755 --- a/python/tests/reader.py +++ b/python/tests/reader.py @@ -4,91 +4,96 @@ # this tests the basic APIs of the XmlTextReader interface # import libxml2 -import StringIO import sys +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) -f = StringIO.StringIO("""<a><b b1="b1"/><c>content of c</c></a>""") +f = str_io("""<a><b b1="b1"/><c>content of c</c></a>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test1") ret = reader.Read() if ret != 1: - print "test1: Error reading to first element" + print("test1: Error reading to first element") sys.exit(1) if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 1 or reader.HasAttributes() != 0: - print "test1: Error reading the first element" + print("test1: Error reading the first element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test1: Error reading to second element" + print("test1: Error reading to second element") sys.exit(1) if reader.Name() != "b" or reader.IsEmptyElement() != 1 or \ reader.NodeType() != 1 or reader.HasAttributes() != 1: - print "test1: Error reading the second element" + print("test1: Error reading the second element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test1: Error reading to third element" + print("test1: Error reading to third element") sys.exit(1) if reader.Name() != "c" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 1 or reader.HasAttributes() != 0: - print "test1: Error reading the third element" + print("test1: Error reading the third element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test1: Error reading to text node" + print("test1: Error reading to text node") sys.exit(1) if reader.Name() != "#text" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 3 or reader.HasAttributes() != 0 or \ reader.Value() != "content of c": - print "test1: Error reading the text node" + print("test1: Error reading the text node") sys.exit(1) ret = reader.Read() if ret != 1: - print "test1: Error reading to end of third element" + print("test1: Error reading to end of third element") sys.exit(1) if reader.Name() != "c" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 15 or reader.HasAttributes() != 0: - print "test1: Error reading the end of third element" + print("test1: Error reading the end of third element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test1: Error reading to end of first element" + print("test1: Error reading to end of first element") sys.exit(1) if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 15 or reader.HasAttributes() != 0: - print "test1: Error reading the end of first element" + print("test1: Error reading the end of first element") sys.exit(1) ret = reader.Read() if ret != 0: - print "test1: Error reading to end of document" + print("test1: Error reading to end of document") sys.exit(1) # # example from the XmlTextReader docs # -f = StringIO.StringIO("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""") +f = str_io("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test2") ret = reader.Read() if ret != 1: - print "Error reading test element" + print("Error reading test element") sys.exit(1) if reader.GetAttributeNo(0) != "urn:datatypes" or \ reader.GetAttributeNo(1) != "int" or \ reader.GetAttributeNs("type", "urn:datatypes") != "int" or \ reader.GetAttribute("dt:type") != "int": - print "error reading test attributes" + print("error reading test attributes") sys.exit(1) # # example from the XmlTextReader docs # -f = StringIO.StringIO("""<root xmlns:a="urn:456"> +f = str_io("""<root xmlns:a="urn:456"> <item> <ref href="a:b"/> </item> @@ -100,203 +105,203 @@ ret = reader.Read() while ret == 1: if reader.Name() == "ref": if reader.LookupNamespace("a") != "urn:456": - print "error resolving namespace prefix" + print("error resolving namespace prefix") sys.exit(1) break ret = reader.Read() if ret != 1: - print "Error finding the ref element" + print("Error finding the ref element") sys.exit(1) # # Home made example for the various attribute access functions # -f = StringIO.StringIO("""<testattr xmlns="urn:1" xmlns:a="urn:2" b="b" a:b="a:b"/>""") +f = str_io("""<testattr xmlns="urn:1" xmlns:a="urn:2" b="b" a:b="a:b"/>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test4") ret = reader.Read() if ret != 1: - print "Error reading the testattr element" + print("Error reading the testattr element") sys.exit(1) # # Attribute exploration by index # if reader.MoveToAttributeNo(0) != 1: - print "Failed moveToAttribute(0)" + print("Failed moveToAttribute(0)") sys.exit(1) if reader.Value() != "urn:1": - print "Failed to read attribute(0)" + print("Failed to read attribute(0)") sys.exit(1) if reader.Name() != "xmlns": - print "Failed to read attribute(0) name" + print("Failed to read attribute(0) name") sys.exit(1) if reader.MoveToAttributeNo(1) != 1: - print "Failed moveToAttribute(1)" + print("Failed moveToAttribute(1)") sys.exit(1) if reader.Value() != "urn:2": - print "Failed to read attribute(1)" + print("Failed to read attribute(1)") sys.exit(1) if reader.Name() != "xmlns:a": - print "Failed to read attribute(1) name" + print("Failed to read attribute(1) name") sys.exit(1) if reader.MoveToAttributeNo(2) != 1: - print "Failed moveToAttribute(2)" + print("Failed moveToAttribute(2)") sys.exit(1) if reader.Value() != "b": - print "Failed to read attribute(2)" + print("Failed to read attribute(2)") sys.exit(1) if reader.Name() != "b": - print "Failed to read attribute(2) name" + print("Failed to read attribute(2) name") sys.exit(1) if reader.MoveToAttributeNo(3) != 1: - print "Failed moveToAttribute(3)" + print("Failed moveToAttribute(3)") sys.exit(1) if reader.Value() != "a:b": - print "Failed to read attribute(3)" + print("Failed to read attribute(3)") sys.exit(1) if reader.Name() != "a:b": - print "Failed to read attribute(3) name" + print("Failed to read attribute(3) name") sys.exit(1) # # Attribute exploration by name # if reader.MoveToAttribute("xmlns") != 1: - print "Failed moveToAttribute('xmlns')" + print("Failed moveToAttribute('xmlns')") sys.exit(1) if reader.Value() != "urn:1": - print "Failed to read attribute('xmlns')" + print("Failed to read attribute('xmlns')") sys.exit(1) if reader.MoveToAttribute("xmlns:a") != 1: - print "Failed moveToAttribute('xmlns')" + print("Failed moveToAttribute('xmlns')") sys.exit(1) if reader.Value() != "urn:2": - print "Failed to read attribute('xmlns:a')" + print("Failed to read attribute('xmlns:a')") sys.exit(1) if reader.MoveToAttribute("b") != 1: - print "Failed moveToAttribute('b')" + print("Failed moveToAttribute('b')") sys.exit(1) if reader.Value() != "b": - print "Failed to read attribute('b')" + print("Failed to read attribute('b')") sys.exit(1) if reader.MoveToAttribute("a:b") != 1: - print "Failed moveToAttribute('a:b')" + print("Failed moveToAttribute('a:b')") sys.exit(1) if reader.Value() != "a:b": - print "Failed to read attribute('a:b')" + print("Failed to read attribute('a:b')") sys.exit(1) if reader.MoveToAttributeNs("b", "urn:2") != 1: - print "Failed moveToAttribute('b', 'urn:2')" + print("Failed moveToAttribute('b', 'urn:2')") sys.exit(1) if reader.Value() != "a:b": - print "Failed to read attribute('b', 'urn:2')" + print("Failed to read attribute('b', 'urn:2')") sys.exit(1) # # Go back and read in sequence # if reader.MoveToElement() != 1: - print "Failed to move back to element" + print("Failed to move back to element") sys.exit(1) if reader.MoveToFirstAttribute() != 1: - print "Failed to move to first attribute" + print("Failed to move to first attribute") sys.exit(1) if reader.Value() != "urn:1": - print "Failed to read attribute(0)" + print("Failed to read attribute(0)") sys.exit(1) if reader.Name() != "xmlns": - print "Failed to read attribute(0) name" + print("Failed to read attribute(0) name") sys.exit(1) if reader.MoveToNextAttribute() != 1: - print "Failed to move to next attribute" + print("Failed to move to next attribute") sys.exit(1) if reader.Value() != "urn:2": - print "Failed to read attribute(1)" + print("Failed to read attribute(1)") sys.exit(1) if reader.Name() != "xmlns:a": - print "Failed to read attribute(1) name" + print("Failed to read attribute(1) name") sys.exit(1) if reader.MoveToNextAttribute() != 1: - print "Failed to move to next attribute" + print("Failed to move to next attribute") sys.exit(1) if reader.Value() != "b": - print "Failed to read attribute(2)" + print("Failed to read attribute(2)") sys.exit(1) if reader.Name() != "b": - print "Failed to read attribute(2) name" + print("Failed to read attribute(2) name") sys.exit(1) if reader.MoveToNextAttribute() != 1: - print "Failed to move to next attribute" + print("Failed to move to next attribute") sys.exit(1) if reader.Value() != "a:b": - print "Failed to read attribute(3)" + print("Failed to read attribute(3)") sys.exit(1) if reader.Name() != "a:b": - print "Failed to read attribute(3) name" + print("Failed to read attribute(3) name") sys.exit(1) if reader.MoveToNextAttribute() != 0: - print "Failed to detect last attribute" + print("Failed to detect last attribute") sys.exit(1) # # a couple of tests for namespace nodes # -f = StringIO.StringIO("""<a xmlns="http://example.com/foo"/>""") +f = str_io("""<a xmlns="http://example.com/foo"/>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test6") ret = reader.Read() if ret != 1: - print "test6: failed to Read()" + print("test6: failed to Read()") sys.exit(1) ret = reader.MoveToFirstAttribute() if ret != 1: - print "test6: failed to MoveToFirstAttribute()" + print("test6: failed to MoveToFirstAttribute()") sys.exit(1) if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \ reader.LocalName() != "xmlns" or reader.Name() != "xmlns" or \ reader.Value() != "http://example.com/foo" or reader.NodeType() != 2: - print "test6: failed to read the namespace node" + print("test6: failed to read the namespace node") sys.exit(1) -f = StringIO.StringIO("""<a xmlns:prefix="http://example.com/foo"/>""") +f = str_io("""<a xmlns:prefix="http://example.com/foo"/>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test7") ret = reader.Read() if ret != 1: - print "test7: failed to Read()" + print("test7: failed to Read()") sys.exit(1) ret = reader.MoveToFirstAttribute() if ret != 1: - print "test7: failed to MoveToFirstAttribute()" + print("test7: failed to MoveToFirstAttribute()") sys.exit(1) if reader.NamespaceUri() != "http://www.w3.org/2000/xmlns/" or \ reader.LocalName() != "prefix" or reader.Name() != "xmlns:prefix" or \ reader.Value() != "http://example.com/foo" or reader.NodeType() != 2: - print "test7: failed to read the namespace node" + print("test7: failed to read the namespace node") sys.exit(1) # # Test for a limit case: # -f = StringIO.StringIO("""<a/>""") +f = str_io("""<a/>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test8") ret = reader.Read() if ret != 1: - print "test8: failed to read the node" + print("test8: failed to read the node") sys.exit(1) if reader.Name() != "a" or reader.IsEmptyElement() != 1: - print "test8: failed to analyze the node" + print("test8: failed to analyze the node") sys.exit(1) ret = reader.Read() if ret != 0: - print "test8: failed to detect the EOF" + print("test8: failed to detect the EOF") sys.exit(1) # # Another test provided by Stéphane Bidoul and checked with C# # def tst_reader(s): - f = StringIO.StringIO(s) + f = str_io(s) input = libxml2.inputBuffer(f) reader = input.newTextReader("tst") res = "" @@ -322,8 +327,8 @@ expect="""1 (a) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test5 failed" - print res + print("test5 failed") + print(res) sys.exit(1) doc="""<test><b/><c/></test>""" @@ -334,8 +339,8 @@ expect="""1 (test) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test9 failed" - print res + print("test9 failed") + print(res) sys.exit(1) doc="""<a><b>bbb</b><c>ccc</c></a>""" @@ -350,8 +355,8 @@ expect="""1 (a) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test10 failed" - print res + print("test10 failed") + print(res) sys.exit(1) doc="""<test a="a"/>""" @@ -360,8 +365,8 @@ expect="""1 (test) [None] 1 0 """ res = tst_reader(doc) if res != expect: - print "test11 failed" - print res + print("test11 failed") + print(res) sys.exit(1) doc="""<test><a>aaa</a><b/></test>""" @@ -374,8 +379,8 @@ expect="""1 (test) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test12 failed" - print res + print("test12 failed") + print(res) sys.exit(1) doc="""<test><p></p></test>""" @@ -386,8 +391,8 @@ expect="""1 (test) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test13 failed" - print res + print("test13 failed") + print(res) sys.exit(1) doc="""<p></p>""" @@ -396,8 +401,8 @@ expect="""1 (p) [None] 0 0 """ res = tst_reader(doc) if res != expect: - print "test14 failed" - print res + print("test14 failed") + print(res) sys.exit(1) # @@ -421,8 +426,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx """ res = tst_reader(doc) if res != expect: - print "test15 failed" - print res + print("test15 failed") + print(res) sys.exit(1) # @@ -435,7 +440,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader2.py b/python/tests/reader2.py index ea890ec..8570575 100755 --- a/python/tests/reader2.py +++ b/python/tests/reader2.py @@ -5,8 +5,13 @@ import sys import glob import string -import StringIO import libxml2 +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) @@ -30,7 +35,11 @@ libxml2.registerErrorHandler(callback, "") valid_files = glob.glob("../../test/valid/*.x*") valid_files.sort() for file in valid_files: - if string.find(file, "t8") != -1: + if file.find("t8") != -1: + continue + if file == "../../test/valid/rss.xml": + continue + if file == "../../test/valid/xlink.xml": continue reader = libxml2.newTextReaderFilename(file) #print "%s:" % (file) @@ -39,11 +48,11 @@ for file in valid_files: while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing and validating %s" % (file) + print("Error parsing and validating %s" % (file)) #sys.exit(1) if err != expect: - print err + print(err) # # another separate test based on Stephane Bidoul one @@ -79,7 +88,7 @@ expect="""10,test res="" err="" -input = libxml2.inputBuffer(StringIO.StringIO(s)) +input = libxml2.inputBuffer(str_io(s)) reader = input.newTextReader("test2") reader.SetParserProp(libxml2.PARSER_LOADDTD,1) reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1) @@ -89,12 +98,12 @@ while reader.Read() == 1: res = res + "%s,%s\n" % (reader.NodeType(),reader.Name()) if res != expect: - print "test2 failed: unexpected output" - print res + print("test2 failed: unexpected output") + print(res) sys.exit(1) if err != "": - print "test2 failed: validation error found" - print err + print("test2 failed: validation error found") + print(err) sys.exit(1) # @@ -124,12 +133,12 @@ res="" def myResolver(URL, ID, ctxt): if URL == "tst.ent": - return(StringIO.StringIO(tst_ent)) + return(str_io(tst_ent)) return None libxml2.setEntityLoader(myResolver) -input = libxml2.inputBuffer(StringIO.StringIO(s)) +input = libxml2.inputBuffer(str_io(s)) reader = input.newTextReader("test3") reader.SetParserProp(libxml2.PARSER_LOADDTD,1) reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1) @@ -139,12 +148,12 @@ while reader.Read() == 1: res = res + "%s %s\n" % (reader.NodeType(),reader.Name()) if res != expect: - print "test3 failed: unexpected output" - print res + print("test3 failed: unexpected output") + print(res) sys.exit(1) if err != "": - print "test3 failed: validation error found" - print err + print("test3 failed: validation error found") + print(err) sys.exit(1) # @@ -183,7 +192,7 @@ expect="""10 test 0 res="" err="" -input = libxml2.inputBuffer(StringIO.StringIO(s)) +input = libxml2.inputBuffer(str_io(s)) reader = input.newTextReader("test4") reader.SetParserProp(libxml2.PARSER_LOADDTD,1) reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1) @@ -193,12 +202,12 @@ while reader.Read() == 1: res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth()) if res != expect: - print "test4 failed: unexpected output" - print res + print("test4 failed: unexpected output") + print(res) sys.exit(1) if err != "": - print "test4 failed: validation error found" - print err + print("test4 failed: validation error found") + print(err) sys.exit(1) # @@ -228,18 +237,18 @@ expect="""10 test 0 res="" err="" -input = libxml2.inputBuffer(StringIO.StringIO(s)) +input = libxml2.inputBuffer(str_io(s)) reader = input.newTextReader("test5") reader.SetParserProp(libxml2.PARSER_VALIDATE,1) while reader.Read() == 1: res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth()) if res != expect: - print "test5 failed: unexpected output" - print res + print("test5 failed: unexpected output") + print(res) if err != "": - print "test5 failed: validation error found" - print err + print("test5 failed: validation error found") + print(err) # # cleanup @@ -250,7 +259,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader3.py b/python/tests/reader3.py index 2458c89..4302b6c 100755 --- a/python/tests/reader3.py +++ b/python/tests/reader3.py @@ -3,8 +3,13 @@ # this tests the entities substitutions with the XmlTextReader interface # import sys -import StringIO import libxml2 +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO docstr="""<?xml version='1.0'?> <!DOCTYPE doc [ @@ -18,90 +23,90 @@ libxml2.debugMemory(1) # # First test, normal don't substitute entities. # -f = StringIO.StringIO(docstr) +f = str_io(docstr) input = libxml2.inputBuffer(f) reader = input.newTextReader("test_noent") ret = reader.Read() if ret != 1: - print "Error reading to root" + print("Error reading to root") sys.exit(1) if reader.Name() == "doc" or reader.NodeType() == 10: ret = reader.Read() if ret != 1: - print "Error reading to root" + print("Error reading to root") sys.exit(1) if reader.Name() != "doc" or reader.NodeType() != 1: - print "test_normal: Error reading the root element" + print("test_normal: Error reading the root element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_normal: Error reading to the entity" + print("test_normal: Error reading to the entity") sys.exit(1) if reader.Name() != "tst" or reader.NodeType() != 5: - print "test_normal: Error reading the entity" + print("test_normal: Error reading the entity") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_normal: Error reading to the end of root" + print("test_normal: Error reading to the end of root") sys.exit(1) if reader.Name() != "doc" or reader.NodeType() != 15: - print "test_normal: Error reading the end of the root element" + print("test_normal: Error reading the end of the root element") sys.exit(1) ret = reader.Read() if ret != 0: - print "test_normal: Error detecting the end" + print("test_normal: Error detecting the end") sys.exit(1) # # Second test, completely substitute the entities. # -f = StringIO.StringIO(docstr) +f = str_io(docstr) input = libxml2.inputBuffer(f) reader = input.newTextReader("test_noent") reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES, 1) ret = reader.Read() if ret != 1: - print "Error reading to root" + print("Error reading to root") sys.exit(1) if reader.Name() == "doc" or reader.NodeType() == 10: ret = reader.Read() if ret != 1: - print "Error reading to root" + print("Error reading to root") sys.exit(1) if reader.Name() != "doc" or reader.NodeType() != 1: - print "test_noent: Error reading the root element" + print("test_noent: Error reading the root element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_noent: Error reading to the entity content" + print("test_noent: Error reading to the entity content") sys.exit(1) if reader.Name() != "p" or reader.NodeType() != 1: - print "test_noent: Error reading the p element from entity" + print("test_noent: Error reading the p element from entity") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_noent: Error reading to the text node" + print("test_noent: Error reading to the text node") sys.exit(1) if reader.NodeType() != 3 or reader.Value() != "test": - print "test_noent: Error reading the text node" + print("test_noent: Error reading the text node") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_noent: Error reading to the end of p element" + print("test_noent: Error reading to the end of p element") sys.exit(1) if reader.Name() != "p" or reader.NodeType() != 15: - print "test_noent: Error reading the end of the p element" + print("test_noent: Error reading the end of the p element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_noent: Error reading to the end of root" + print("test_noent: Error reading to the end of root") sys.exit(1) if reader.Name() != "doc" or reader.NodeType() != 15: - print "test_noent: Error reading the end of the root element" + print("test_noent: Error reading the end of the root element") sys.exit(1) ret = reader.Read() if ret != 0: - print "test_noent: Error detecting the end" + print("test_noent: Error detecting the end") sys.exit(1) # @@ -122,12 +127,12 @@ simplestruct2_ent="""<descr/>""" def myResolver(URL, ID, ctxt): if URL == "simplestruct2.ent": - return(StringIO.StringIO(simplestruct2_ent)) + return(str_io(simplestruct2_ent)) return None libxml2.setEntityLoader(myResolver) -input = libxml2.inputBuffer(StringIO.StringIO(s)) +input = libxml2.inputBuffer(str_io(s)) reader = input.newTextReader("test3") reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1) while reader.Read() == 1: @@ -135,8 +140,8 @@ while reader.Read() == 1: reader.Depth(),reader.IsEmptyElement()) if res != expect: - print "test3 failed: unexpected output" - print res + print("test3 failed: unexpected output") + print(res) sys.exit(1) # @@ -149,7 +154,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader4.py b/python/tests/reader4.py index 0824929..0bb3e3f 100755 --- a/python/tests/reader4.py +++ b/python/tests/reader4.py @@ -3,14 +3,19 @@ # this tests the basic APIs of the XmlTextReader interface # import libxml2 -import StringIO import sys +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) def tst_reader(s): - f = StringIO.StringIO(s) + f = str_io(s) input = libxml2.inputBuffer(f) reader = input.newTextReader("tst") res = "" @@ -32,14 +37,14 @@ expect="""1 (test) [None] 0 res = tst_reader("""<test><b/><c/></test>""") if res != expect: - print "Did not get the expected error message:" - print res + print("Did not get the expected error message:") + print(res) sys.exit(1) # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader5.py b/python/tests/reader5.py index fcbad61..82d0dae 100755 --- a/python/tests/reader5.py +++ b/python/tests/reader5.py @@ -4,7 +4,6 @@ # this extract the Dragon bibliography entries from the XML specification # import libxml2 -import StringIO import sys # Memory debug specific @@ -15,11 +14,11 @@ Ravi Sethi, and Jeffrey D. Ullman. <emph>Compilers: Principles, Techniques, and Tools</emph>. Reading: Addison-Wesley, 1986, rpt. corr. 1988.</bibl>""" -f = open('../../test/valid/REC-xml-19980210.xml') +f = open('../../test/valid/REC-xml-19980210.xml', 'rb') input = libxml2.inputBuffer(f) reader = input.newTextReader("REC") res="" -while reader.Read(): +while reader.Read() > 0: while reader.Name() == 'bibl': node = reader.Expand() # expand the subtree if node.xpathEval("@id = 'Aho'"): # use XPath on it @@ -28,9 +27,9 @@ while reader.Read(): break; if res != expect: - print "Error: didn't get the expected output" - print "got '%s'" % (res) - print "expected '%s'" % (expect) + print("Error: didn't get the expected output") + print("got '%s'" % (res)) + print("expected '%s'" % (expect)) # @@ -42,7 +41,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader6.py b/python/tests/reader6.py index 7a34601..ef33b18 100755 --- a/python/tests/reader6.py +++ b/python/tests/reader6.py @@ -3,8 +3,13 @@ # this tests the entities substitutions with the XmlTextReader interface # import sys -import StringIO import libxml2 +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO schema="""<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> @@ -41,7 +46,7 @@ docstr="""<foo> <item>100</item> </foo>""" -f = StringIO.StringIO(docstr) +f = str_io(docstr) input = libxml2.inputBuffer(f) reader = input.newTextReader("correct") reader.RelaxNGSetSchema(rngs) @@ -50,11 +55,11 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document" + print("Error parsing the document") sys.exit(1) if reader.IsValid() != 1: - print "Document failed to validate" + print("Document failed to validate") sys.exit(1) # @@ -84,7 +89,7 @@ def callback(ctx, str): err = err + "%s" % (str) libxml2.registerErrorHandler(callback, "") -f = StringIO.StringIO(docstr) +f = str_io(docstr) input = libxml2.inputBuffer(f) reader = input.newTextReader("error") reader.RelaxNGSetSchema(rngs) @@ -93,16 +98,16 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document" + print("Error parsing the document") sys.exit(1) if reader.IsValid() != 0: - print "Document failed to detect the validation error" + print("Document failed to detect the validation error") sys.exit(1) if err != expect: - print "Did not get the expected error message:" - print err + print("Did not get the expected error message:") + print(err) sys.exit(1) # @@ -117,7 +122,7 @@ libxml2.relaxNGCleanupTypes() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader7.py b/python/tests/reader7.py index 35a426f..c88e370 100755 --- a/python/tests/reader7.py +++ b/python/tests/reader7.py @@ -3,7 +3,6 @@ # this tests the entities substitutions with the XmlTextReader interface # import sys -import StringIO import libxml2 # Memory debug specific @@ -44,12 +43,12 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document test1" + print("Error parsing the document test1") sys.exit(1) if result != expect: - print "Unexpected result for test1" - print result + print("Unexpected result for test1") + print(result) sys.exit(1) # @@ -80,12 +79,12 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document test2" + print("Error parsing the document test2") sys.exit(1) if result != expect: - print "Unexpected result for test2" - print result + print("Unexpected result for test2") + print(result) sys.exit(1) # @@ -96,7 +95,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/reader8.py b/python/tests/reader8.py index 53b7f27..de2dcd6 100755 --- a/python/tests/reader8.py +++ b/python/tests/reader8.py @@ -3,7 +3,6 @@ # this tests the entities substitutions with the XmlTextReader interface # import sys -import StringIO import libxml2 # Memory debug specific @@ -23,7 +22,7 @@ ret = reader.Read() ret = reader.Close() if ret != 0: - print "Error closing the document test1" + print("Error closing the document test1") sys.exit(1) del reader @@ -31,7 +30,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/readererr.py b/python/tests/readererr.py index 0dad36e..c8ceba5 100644..100755 --- a/python/tests/readererr.py +++ b/python/tests/readererr.py @@ -3,8 +3,13 @@ # this tests the basic APIs of the XmlTextReader interface # import libxml2 -import StringIO import sys +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) @@ -17,7 +22,7 @@ def myErrorHandler(arg,msg,severity,locator): global err err = err + "%s (%d) %s:%d:%s" % (arg,severity,locator.BaseURI(),locator.LineNumber(),msg) -f = StringIO.StringIO("""<a xmlns="foo"><b b1="b1"/><c>content of c</a>""") +f = str_io("""<a xmlns="foo"><b b1="b1"/><c>content of c</a>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test1") reader.SetErrorHandler(myErrorHandler,"-->") @@ -25,14 +30,14 @@ while reader.Read() == 1: pass if err != expect: - print "error" - print "received %s" %(err) - print "expected %s" %(expect) + print("error") + print("received %s" %(err)) + print("expected %s" %(expect)) sys.exit(1) reader.SetErrorHandler(None,None) if reader.GetErrorHandler() != (None,None): - print "GetErrorHandler failed" + print("GetErrorHandler failed") sys.exit(1) # @@ -45,7 +50,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/readernext.py b/python/tests/readernext.py index b01a49d..fcb9ae3 100755 --- a/python/tests/readernext.py +++ b/python/tests/readernext.py @@ -4,65 +4,70 @@ # this tests the next API of the XmlTextReader interface # import libxml2 -import StringIO import sys +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) -f = StringIO.StringIO("""<a><b><c /></b><d>content of d</d></a>""") +f = str_io("""<a><b><c /></b><d>content of d</d></a>""") input = libxml2.inputBuffer(f) reader = input.newTextReader("test_next") ret = reader.Read() if ret != 1: - print "test_next: Error reading to first element" + print("test_next: Error reading to first element") sys.exit(1) if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 1 or reader.HasAttributes() != 0: - print "test_next: Error reading the first element" + print("test_next: Error reading the first element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_next: Error reading to second element" + print("test_next: Error reading to second element") sys.exit(1) if reader.Name() != "b" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 1 or reader.HasAttributes() != 0: - print "test_next: Error reading the second element" + print("test_next: Error reading the second element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_next: Error reading to third element" + print("test_next: Error reading to third element") sys.exit(1) if reader.Name() != "c" or reader.NodeType() != 1 or \ reader.HasAttributes() != 0: - print "test_next: Error reading the third element" + print("test_next: Error reading the third element") sys.exit(1) ret = reader.Read() if ret != 1: - print "test_next: Error reading to end of third element" + print("test_next: Error reading to end of third element") sys.exit(1) if reader.Name() != "b" or reader.NodeType() != 15: - print "test_next: Error reading to end of second element" + print("test_next: Error reading to end of second element") sys.exit(1) ret = reader.Next() if ret != 1: - print "test_next: Error moving to third element" + print("test_next: Error moving to third element") sys.exit(1) if reader.Name() != "d" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 1 or reader.HasAttributes() != 0: - print "test_next: Error reading third element" + print("test_next: Error reading third element") sys.exit(1) ret = reader.Next() if ret != 1: - print "test_next: Error reading to end of first element" + print("test_next: Error reading to end of first element") sys.exit(1) if reader.Name() != "a" or reader.IsEmptyElement() != 0 or \ reader.NodeType() != 15 or reader.HasAttributes() != 0: - print "test_next: Error reading the end of first element" + print("test_next: Error reading the end of first element") sys.exit(1) ret = reader.Read() if ret != 0: - print "test_next: Error reading to end of document" + print("test_next: Error reading to end of document") sys.exit(1) # @@ -75,7 +80,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/regexp.py b/python/tests/regexp.py index 4c05502..a03e459 100644..100755 --- a/python/tests/regexp.py +++ b/python/tests/regexp.py @@ -6,19 +6,19 @@ libxml2.debugMemory(1) re = libxml2.regexpCompile("a|b") if re.regexpExec("a") != 1: - print "error checking 'a'" + print("error checking 'a'") sys.exit(1) if re.regexpExec("b") != 1: - print "error checking 'b'" + print("error checking 'b'") sys.exit(1) if re.regexpExec("ab") != 0: - print "error checking 'ab'" + print("error checking 'ab'") sys.exit(1) if re.regexpExec("") != 0: - print "error checking 'ab'" + print("error checking 'ab'") sys.exit(1) if re.regexpIsDeterminist() != 1: - print "error checking determinism" + print("error checking determinism") sys.exit(1) del re @@ -26,7 +26,7 @@ del re # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/relaxng.py b/python/tests/relaxng.py index 2c83635..fa3d327 100755 --- a/python/tests/relaxng.py +++ b/python/tests/relaxng.py @@ -29,7 +29,7 @@ ctxt = rngs.relaxNGNewValidCtxt() doc = libxml2.parseDoc(instance) ret = doc.relaxNGValidateDoc(ctxt) if ret != 0: - print "error doing RelaxNG validation" + print("error doing RelaxNG validation") sys.exit(1) doc.freeDoc() @@ -41,8 +41,8 @@ libxml2.relaxNGCleanupTypes() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/resolver.py b/python/tests/resolver.py index 9f4a478..6f21f52 100755 --- a/python/tests/resolver.py +++ b/python/tests/resolver.py @@ -1,20 +1,25 @@ #!/usr/bin/python -u import sys import libxml2 -import StringIO +try: + import StringIO + str_io = StringIO.StringIO +except: + import io + str_io = io.StringIO # Memory debug specific libxml2.debugMemory(1) def myResolver(URL, ID, ctxt): - return(StringIO.StringIO("<foo/>")) + return(str_io("<foo/>")) libxml2.setEntityLoader(myResolver) doc = libxml2.parseFile("doesnotexist.xml") root = doc.children if root.name != "foo": - print "root element name error" + print("root element name error") sys.exit(1) doc.freeDoc() @@ -23,7 +28,7 @@ while i < 5000: doc = libxml2.parseFile("doesnotexist.xml") root = doc.children if root.name != "foo": - print "root element name error" + print("root element name error") sys.exit(1) doc.freeDoc() i = i + 1 @@ -32,8 +37,8 @@ while i < 5000: # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/schema.py b/python/tests/schema.py index bfa8423..8089272 100755 --- a/python/tests/schema.py +++ b/python/tests/schema.py @@ -33,7 +33,7 @@ ctxt_valid = ctxt_schema.schemaNewValidCtxt() doc = libxml2.parseDoc(instance) ret = doc.schemaValidateDoc(ctxt_valid) if ret != 0: - print "error doing schema validation" + print("error doing schema validation") sys.exit(1) doc.freeDoc() @@ -45,8 +45,8 @@ libxml2.schemaCleanupTypes() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/serialize.py b/python/tests/serialize.py index 91753e7..80b901a 100755 --- a/python/tests/serialize.py +++ b/python/tests/serialize.py @@ -13,13 +13,13 @@ str = doc.serialize() if str != """<?xml version="1.0"?> <root><foo>hello</foo></root> """: - print "error serializing XML document 1" + print("error serializing XML document 1") sys.exit(1) str = doc.serialize("iso-8859-1") if str != """<?xml version="1.0" encoding="iso-8859-1"?> <root><foo>hello</foo></root> """: - print "error serializing XML document 2" + print("error serializing XML document 2") sys.exit(1) str = doc.serialize(format=1) if str != """<?xml version="1.0"?> @@ -27,7 +27,7 @@ if str != """<?xml version="1.0"?> <foo>hello</foo> </root> """: - print "error serializing XML document 3" + print("error serializing XML document 3") sys.exit(1) str = doc.serialize("iso-8859-1", 1) if str != """<?xml version="1.0" encoding="iso-8859-1"?> @@ -35,7 +35,7 @@ if str != """<?xml version="1.0" encoding="iso-8859-1"?> <foo>hello</foo> </root> """: - print "error serializing XML document 4" + print("error serializing XML document 4") sys.exit(1) # @@ -44,23 +44,23 @@ if str != """<?xml version="1.0" encoding="iso-8859-1"?> root = doc.getRootElement() str = root.serialize() if str != """<root><foo>hello</foo></root>""": - print "error serializing XML root 1" + print("error serializing XML root 1") sys.exit(1) str = root.serialize("iso-8859-1") if str != """<root><foo>hello</foo></root>""": - print "error serializing XML root 2" + print("error serializing XML root 2") sys.exit(1) str = root.serialize(format=1) if str != """<root> <foo>hello</foo> </root>""": - print "error serializing XML root 3" + print("error serializing XML root 3") sys.exit(1) str = root.serialize("iso-8859-1", 1) if str != """<root> <foo>hello</foo> </root>""": - print "error serializing XML root 4" + print("error serializing XML root 4") sys.exit(1) doc.freeDoc() @@ -72,13 +72,13 @@ str = doc.serialize() if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html><head><title>Hello</title></head><body><p>hello</p></body></html> """: - print "error serializing HTML document 1" + print("error serializing HTML document 1") sys.exit(1) str = doc.serialize("ISO-8859-1") if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html> """: - print "error serializing HTML document 2" + print("error serializing HTML document 2") sys.exit(1) str = doc.serialize(format=1) if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> @@ -90,7 +90,7 @@ if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http <body><p>hello</p></body> </html> """: - print "error serializing HTML document 3" + print("error serializing HTML document 3") sys.exit(1) str = doc.serialize("iso-8859-1", 1) if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> @@ -102,7 +102,7 @@ if str != """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http <body><p>hello</p></body> </html> """: - print "error serializing HTML document 4" + print("error serializing HTML document 4") sys.exit(1) # @@ -112,11 +112,11 @@ doc.htmlSetMetaEncoding(None) root = doc.getRootElement() str = root.serialize() if str != """<html><head><title>Hello</title></head><body><p>hello</p></body></html>""": - print "error serializing HTML root 1" + print("error serializing HTML root 1") sys.exit(1) str = root.serialize("ISO-8859-1") if str != """<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Hello</title></head><body><p>hello</p></body></html>""": - print "error serializing HTML root 2" + print("error serializing HTML root 2") sys.exit(1) str = root.serialize(format=1) if str != """<html> @@ -126,7 +126,7 @@ if str != """<html> </head> <body><p>hello</p></body> </html>""": - print "error serializing HTML root 3" + print("error serializing HTML root 3") sys.exit(1) str = root.serialize("iso-8859-1", 1) if str != """<html> @@ -136,7 +136,7 @@ if str != """<html> </head> <body><p>hello</p></body> </html>""": - print "error serializing HTML root 4" + print("error serializing HTML root 4") sys.exit(1) doc.freeDoc() @@ -144,7 +144,7 @@ doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/sync.py b/python/tests/sync.py index 2141875..9d565db 100755 --- a/python/tests/sync.py +++ b/python/tests/sync.py @@ -50,8 +50,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -62,8 +62,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 None:endElement bar2:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -74,8 +74,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 None:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -86,8 +86,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -98,8 +98,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -110,8 +110,8 @@ ctxt=None reference = "startDocument:startElement foo None:startElement bar2 {'a': '1', 'b': '2'}:endElement bar2:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) log="" @@ -122,14 +122,14 @@ ctxt=None reference = "startDocument:startElement foo None:" if log != reference: - print "Error got: %s" % log - print "Exprected: %s" % reference + print("Error got: %s" % log) + print("Exprected: %s" % reference) sys.exit(1) # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/thread2.py b/python/tests/thread2.py index c8ac5ed..2749eb0 100755 --- a/python/tests/thread2.py +++ b/python/tests/thread2.py @@ -1,6 +1,9 @@ #!/usr/bin/python -u import string, sys, time -import thread +try: + from _thread import get_ident +except: + from thread import get_ident from threading import Thread, Lock import libxml2 @@ -31,8 +34,8 @@ def test(expectedLineNumbersDefault): # check a per thread-global if expectedLineNumbersDefault != getLineNumbersDefault(): failed = 1 - print "FAILED to obtain correct value for " \ - "lineNumbersDefault in thread %d" % thread.get_ident() + print("FAILED to obtain correct value for " \ + "lineNumbersDefault in thread %d" % get_ident()) # check ther global error handler # (which is NOT per-thread in the python bindings) try: @@ -51,7 +54,7 @@ libxml2.lineNumbersDefault(1) test(1) ec = len(eh.errors) if ec == 0: - print "FAILED: should have obtained errors" + print("FAILED: should have obtained errors") sys.exit(1) ts = [] @@ -65,7 +68,7 @@ for t in ts: t.join() if len(eh.errors) != ec+THREADS_COUNT*ec: - print "FAILED: did not obtain the correct number of errors" + print("FAILED: did not obtain the correct number of errors") sys.exit(1) # set lineNumbersDefault for future new threads @@ -80,17 +83,17 @@ for t in ts: t.join() if len(eh.errors) != ec+THREADS_COUNT*ec*2: - print "FAILED: did not obtain the correct number of errors" + print("FAILED: did not obtain the correct number of errors") sys.exit(1) if failed: - print "FAILED" + print("FAILED") sys.exit(1) # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/tst.py b/python/tests/tst.py index 9540cda..57a7318 100755 --- a/python/tests/tst.py +++ b/python/tests/tst.py @@ -7,22 +7,22 @@ libxml2.debugMemory(1) doc = libxml2.parseFile("tst.xml") if doc.name != "tst.xml": - print "doc.name failed" + print("doc.name failed") sys.exit(1) root = doc.children if root.name != "doc": - print "root.name failed" + print("root.name failed") sys.exit(1) child = root.children if child.name != "foo": - print "child.name failed" + print("child.name failed") sys.exit(1) doc.freeDoc() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/tstLastError.py b/python/tests/tstLastError.py index d26e82c..d5f9be7 100755 --- a/python/tests/tstLastError.py +++ b/python/tests/tstLastError.py @@ -17,8 +17,8 @@ class TestCase(unittest.TestCase): if libxml2.debugMemory(1) != 0: libxml2.dumpMemory() self.fail("Memory leak %d bytes" % (libxml2.debugMemory(1),)) - else: - print "OK" + else: + print("OK") def failUnlessXmlError(self,f,args,exc,domain,code,message,level,file,line): """Run function f, with arguments args and expect an exception exc; @@ -27,19 +27,19 @@ class TestCase(unittest.TestCase): # disable the default error handler libxml2.registerErrorHandler(None,None) try: - apply(f,args) + f(*args) except exc: e = libxml2.lastError() if e is None: self.fail("lastError not set") if 0: - print "domain = ",e.domain() - print "code = ",e.code() - print "message =",repr(e.message()) - print "level =",e.level() - print "file =",e.file() - print "line =",e.line() - print + print("domain = ",e.domain()) + print("code = ",e.code()) + print("message =",repr(e.message())) + print("level =",e.level()) + print("file =",e.file()) + print("line =",e.line()) + print() self.failUnlessEqual(domain,e.domain()) self.failUnlessEqual(code,e.code()) self.failUnlessEqual(message,e.message()) diff --git a/python/tests/tstURI.py b/python/tests/tstURI.py index 58b7ad8..e4d58af 100755 --- a/python/tests/tstURI.py +++ b/python/tests/tstURI.py @@ -7,35 +7,35 @@ libxml2.debugMemory(1) uri = libxml2.parseURI("http://example.org:8088/foo/bar?query=simple#fragid") if uri.scheme() != 'http': - print "Error parsing URI: wrong scheme" + print("Error parsing URI: wrong scheme") sys.exit(1) if uri.server() != 'example.org': - print "Error parsing URI: wrong server" + print("Error parsing URI: wrong server") sys.exit(1) if uri.port() != 8088: - print "Error parsing URI: wrong port" + print("Error parsing URI: wrong port") sys.exit(1) if uri.path() != '/foo/bar': - print "Error parsing URI: wrong path" + print("Error parsing URI: wrong path") sys.exit(1) if uri.query() != 'query=simple': - print "Error parsing URI: wrong query" + print("Error parsing URI: wrong query") sys.exit(1) if uri.fragment() != 'fragid': - print "Error parsing URI: wrong query" + print("Error parsing URI: wrong query") sys.exit(1) uri.setScheme("https") uri.setPort(223) uri.setFragment(None) result=uri.saveUri() if result != "https://example.org:223/foo/bar?query=simple": - print "Error modifying or saving the URI" + print("Error modifying or saving the URI") uri = None # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/tstmem.py b/python/tests/tstmem.py index 553096d..6b34cf3 100755 --- a/python/tests/tstmem.py +++ b/python/tests/tstmem.py @@ -19,7 +19,7 @@ libxml2mod.xmlSetValidErrors(ctxt._o, error, error) doc = libxml2.parseDoc(instance) ret = doc.validateDtd(ctxt, dtd) if ret != 1: - print "error doing DTD validation" + print("error doing DTD validation") sys.exit(1) doc.freeDoc() @@ -30,7 +30,7 @@ del ctxt # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/tstxpath.py b/python/tests/tstxpath.py index e47c34d..0ba5a6d 100755 --- a/python/tests/tstxpath.py +++ b/python/tests/tstxpath.py @@ -25,10 +25,10 @@ doc = libxml2.parseFile("tst.xml") ctxt = doc.xpathNewContext() res = ctxt.xpathEval("//*") if len(res) != 2: - print "xpath query: wrong node set size" + print("xpath query: wrong node set size") sys.exit(1) if res[0].name != "doc" or res[1].name != "foo": - print "xpath query: wrong node set value" + print("xpath query: wrong node set value") sys.exit(1) libxml2.registerXPathFunction(ctxt._o, "foo", None, foo) libxml2.registerXPathFunction(ctxt._o, "bar", None, bar) @@ -36,28 +36,28 @@ i = 10000 while i > 0: res = ctxt.xpathEval("foo(1)") if res != 2: - print "xpath extension failure" + print("xpath extension failure") sys.exit(1) i = i - 1 i = 10000 while i > 0: res = ctxt.xpathEval("bar(1)") if res != "3": - print "xpath extension failure got %s expecting '3'" + print("xpath extension failure got %s expecting '3'") sys.exit(1) i = i - 1 doc.freeDoc() ctxt.xpathFreeContext() if called != "foo": - print "xpath function: failed to access the context" - print "xpath function: %s" % (called) + print("xpath function: failed to access the context") + print("xpath function: %s" % (called)) sys.exit(1) #memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/validDTD.py b/python/tests/validDTD.py index 1222f9f..4b03b8e 100755 --- a/python/tests/validDTD.py +++ b/python/tests/validDTD.py @@ -11,7 +11,7 @@ class ErrorHandler: def handler(self, msg, data): if data != ARG: - raise Exception, "Error handler did not receive correct argument" + raise Exception("Error handler did not receive correct argument") self.errors.append(msg) @@ -34,7 +34,7 @@ ctxt.setValidityErrorHandler(e.handler, e.handler, ARG) doc = libxml2.parseDoc(valid) ret = doc.validateDtd(ctxt, dtd) if ret != 1 or e.errors: - print "error doing DTD validation" + print("error doing DTD validation") sys.exit(1) doc.freeDoc() @@ -42,7 +42,7 @@ doc.freeDoc() doc = libxml2.parseDoc(invalid) ret = doc.validateDtd(ctxt, dtd) if ret != 0 or not e.errors: - print "Error: document supposed to be invalid" + print("Error: document supposed to be invalid") doc.freeDoc() dtd.freeDtd() @@ -52,8 +52,8 @@ del ctxt # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/validRNG.py b/python/tests/validRNG.py index 7022efe..57f13a4 100755 --- a/python/tests/validRNG.py +++ b/python/tests/validRNG.py @@ -11,7 +11,7 @@ class ErrorHandler: def handler(self, msg, data): if data != ARG: - raise Exception, "Error handler did not receive correct argument" + raise Exception("Error handler did not receive correct argument") self.errors.append(msg) # Memory debug specific @@ -49,7 +49,7 @@ ctxt.setValidityErrorHandler(e.handler, e.handler, ARG) doc = libxml2.parseDoc(valid) ret = doc.relaxNGValidateDoc(ctxt) if ret != 0 or e.errors: - print "error doing RelaxNG validation" + print("error doing RelaxNG validation") sys.exit(1) doc.freeDoc() @@ -57,7 +57,7 @@ doc.freeDoc() doc = libxml2.parseDoc(invalid) ret = doc.relaxNGValidateDoc(ctxt) if ret == 0 or not e.errors: - print "Error: document supposed to be RelaxNG invalid" + print("Error: document supposed to be RelaxNG invalid") sys.exit(1) doc.freeDoc() @@ -69,8 +69,8 @@ libxml2.relaxNGCleanupTypes() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/validSchemas.py b/python/tests/validSchemas.py index d4d62b2..cc543f3 100755 --- a/python/tests/validSchemas.py +++ b/python/tests/validSchemas.py @@ -11,7 +11,7 @@ class ErrorHandler: def handler(self, msg, data): if data != ARG: - raise Exception, "Error handler did not receive correct argument" + raise Exception("Error handler did not receive correct argument") self.errors.append(msg) # Memory debug specific @@ -56,7 +56,7 @@ ctxt_valid.setValidityErrorHandler(e.handler, e.handler, ARG) doc = libxml2.parseDoc(valid) ret = doc.schemaValidateDoc(ctxt_valid) if ret != 0 or e.errors: - print "error doing schema validation" + print("error doing schema validation") sys.exit(1) doc.freeDoc() @@ -64,7 +64,7 @@ doc.freeDoc() doc = libxml2.parseDoc(invalid) ret = doc.schemaValidateDoc(ctxt_valid) if ret == 0 or not e.errors: - print "Error: document supposer to be schema invalid" + print("Error: document supposer to be schema invalid") sys.exit(1) doc.freeDoc() @@ -76,8 +76,8 @@ libxml2.schemaCleanupTypes() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/validate.py b/python/tests/validate.py index 0dc86f4..16c0386 100755 --- a/python/tests/validate.py +++ b/python/tests/validate.py @@ -12,14 +12,14 @@ doc = ctxt.doc() valid = ctxt.isValid() if doc.name != "valid.xml": - print "doc.name failed" + print("doc.name failed") sys.exit(1) root = doc.children if root.name != "doc": - print "root.name failed" + print("root.name failed") sys.exit(1) if valid != 1: - print "validity chec failed" + print("validity chec failed") sys.exit(1) doc.freeDoc() @@ -32,7 +32,7 @@ while i > 0: valid = ctxt.isValid() doc.freeDoc() if valid != 1: - print "validity check failed" + print("validity check failed") sys.exit(1) i = i - 1 @@ -48,14 +48,14 @@ ctxt.parseDocument() doc = ctxt.doc() valid = ctxt.isValid() if doc.name != "invalid.xml": - print "doc.name failed" + print("doc.name failed") sys.exit(1) root = doc.children if root.name != "doc": - print "root.name failed" + print("root.name failed") sys.exit(1) if valid != 0: - print "validity chec failed" + print("validity chec failed") sys.exit(1) doc.freeDoc() @@ -68,7 +68,7 @@ while i > 0: valid = ctxt.isValid() doc.freeDoc() if valid != 0: - print "validity check failed" + print("validity check failed") sys.exit(1) i = i - 1 del ctxt @@ -76,7 +76,7 @@ del ctxt # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/walker.py b/python/tests/walker.py index 3b5a62a..47f0557 100755 --- a/python/tests/walker.py +++ b/python/tests/walker.py @@ -3,7 +3,6 @@ # this tests the entities substitutions with the XmlTextReader interface # import sys -import StringIO import libxml2 # Memory debug specific @@ -45,12 +44,12 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document test1" + print("Error parsing the document test1") sys.exit(1) if result != expect: - print "Unexpected result for test1" - print result + print("Unexpected result for test1") + print(result) sys.exit(1) doc.freeDoc() @@ -85,12 +84,12 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document test2" + print("Error parsing the document test2") sys.exit(1) if result != expect: - print "Unexpected result for test2" - print result + print("Unexpected result for test2") + print(result) sys.exit(1) doc.freeDoc() @@ -123,12 +122,12 @@ while ret == 1: ret = reader.Read() if ret != 0: - print "Error parsing the document test3" + print("Error parsing the document test3") sys.exit(1) if result != expect: - print "Unexpected result for test3" - print result + print("Unexpected result for test3") + print(result) sys.exit(1) # @@ -139,7 +138,7 @@ del reader # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/xpath.py b/python/tests/xpath.py index 2e036e1..72e6c9d 100755 --- a/python/tests/xpath.py +++ b/python/tests/xpath.py @@ -11,24 +11,24 @@ libxml2.debugMemory(1) doc = libxml2.parseFile("tst.xml") if doc.name != "tst.xml": - print "doc.name error" + print("doc.name error") sys.exit(1); ctxt = doc.xpathNewContext() res = ctxt.xpathEval("//*") if len(res) != 2: - print "xpath query: wrong node set size" + print("xpath query: wrong node set size") sys.exit(1) if res[0].name != "doc" or res[1].name != "foo": - print "xpath query: wrong node set value" + print("xpath query: wrong node set value") sys.exit(1) ctxt.setContextNode(res[0]) res = ctxt.xpathEval("foo") if len(res) != 1: - print "xpath query: wrong node set size" + print("xpath query: wrong node set size") sys.exit(1) if res[0].name != "foo": - print "xpath query: wrong node set value" + print("xpath query: wrong node set value") sys.exit(1) doc.freeDoc() ctxt.xpathFreeContext() @@ -45,7 +45,7 @@ del ctxt # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/xpathext.py b/python/tests/xpathext.py index 4769626..b83d283 100755 --- a/python/tests/xpathext.py +++ b/python/tests/xpathext.py @@ -15,10 +15,10 @@ doc = libxml2.parseFile("tst.xml") ctxt = doc.xpathNewContext() res = ctxt.xpathEval("//*") if len(res) != 2: - print "xpath query: wrong node set size" + print("xpath query: wrong node set size") sys.exit(1) if res[0].name != "doc" or res[1].name != "foo": - print "xpath query: wrong node set value" + print("xpath query: wrong node set value") sys.exit(1) libxml2.registerXPathFunction(ctxt._o, "foo", None, foo) @@ -27,14 +27,14 @@ i = 10000 while i > 0: res = ctxt.xpathEval("foo(1)") if res != 2: - print "xpath extension failure" + print("xpath extension failure") sys.exit(1) i = i - 1 i = 10000 while i > 0: res = ctxt.xpathEval("bar(1)") if res != "3": - print "xpath extension failure got %s expecting '3'" + print("xpath extension failure got %s expecting '3'") sys.exit(1) i = i - 1 doc.freeDoc() @@ -43,7 +43,7 @@ ctxt.xpathFreeContext() # Memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/xpathleak.py b/python/tests/xpathleak.py index 39f49e3..33ab61c 100644..100755 --- a/python/tests/xpathleak.py +++ b/python/tests/xpathleak.py @@ -42,24 +42,24 @@ badexprs = ( for expr in badexprs: try: ctxt.xpathEval(expr) - except libxml2.xpathError, e: + except libxml2.xpathError: pass else: - print "Unexpectedly legal expression:", expr + print("Unexpectedly legal expression:", expr) ctxt.xpathFreeContext() doc.freeDoc() if err != expect: - print "error" - print "received %s" %(err) - print "expected %s" %(expect) + print("error") + print("received %s" %(err)) + print("expected %s" %(expect)) sys.exit(1) libxml2.cleanupParser() leakedbytes = libxml2.debugMemory(True) if leakedbytes == 0: - print "OK" + print("OK") else: - print "Memory leak", leakedbytes, "bytes" + print("Memory leak", leakedbytes, "bytes") # drop file to .memdump file in cwd, but won't work if not compiled in libxml2.dumpMemory() diff --git a/python/tests/xpathns.py b/python/tests/xpathns.py index e67e550..379535e 100755 --- a/python/tests/xpathns.py +++ b/python/tests/xpathns.py @@ -14,8 +14,8 @@ for n in d.xpathEval("//namespace::*"): d.freeDoc() if res != expect: - print "test5 failed: unexpected output" - print res + print("test5 failed: unexpected output") + print(res) del res del d del n @@ -23,7 +23,7 @@ del n libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/tests/xpathret.py b/python/tests/xpathret.py index 2b5576a..11c8b32 100755 --- a/python/tests/xpathret.py +++ b/python/tests/xpathret.py @@ -27,21 +27,21 @@ ctxt = doc.xpathNewContext() libxml2.registerXPathFunction(ctxt._o, "foo", None, foo) res = ctxt.xpathEval("foo('hello')") if type(res) != type([]): - print "Failed to return a nodeset" + print("Failed to return a nodeset") sys.exit(1) if len(res) != 1: - print "Unexpected nodeset size" + print("Unexpected nodeset size") sys.exit(1) node = res[0] if node.name != 'p': - print "Unexpected nodeset element result" + print("Unexpected nodeset element result") sys.exit(1) node = node.children if node.type != 'text': - print "Unexpected nodeset element children type" + print("Unexpected nodeset element children type") sys.exit(1) if node.content != 'hello': - print "Unexpected nodeset element children content" + print("Unexpected nodeset element children content") sys.exit(1) doc.freeDoc() @@ -51,7 +51,7 @@ ctxt.xpathFreeContext() #memory debug specific libxml2.cleanupParser() if libxml2.debugMemory(1) == 0: - print "OK" + print("OK") else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + print("Memory leak %d bytes" % (libxml2.debugMemory(1))) libxml2.dumpMemory() diff --git a/python/types.c b/python/types.c index 54b50de..31c909a 100644 --- a/python/types.c +++ b/python/types.c @@ -9,6 +9,83 @@ #include "libxml_wrap.h" #include <libxml/xpathInternals.h> +#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 + +#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); + if (!_PyVerify_fd(fd)) + return(NULL); + /* + * 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); + } + + /* + * 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 genrated accodingly + */ + fd = dup(fd); + if (fd == -1) + return(NULL); + res = fdopen(fd, mode); + if (res == NULL) { + close(fd); + return(NULL); + } + return(res); +} + +void libxml_PyFileRelease(FILE *f) { + if (f != NULL) + fclose(f); +} +#endif + PyObject * libxml_intWrap(int val) { @@ -17,7 +94,7 @@ libxml_intWrap(int val) #ifdef DEBUG printf("libxml_intWrap: val = %d\n", val); #endif - ret = PyInt_FromLong((long) val); + ret = PY_IMPORT_INT((long) val); return (ret); } @@ -29,7 +106,7 @@ libxml_longWrap(long val) #ifdef DEBUG printf("libxml_longWrap: val = %ld\n", val); #endif - ret = PyInt_FromLong(val); + ret = PyLong_FromLong(val); return (ret); } @@ -57,8 +134,7 @@ libxml_charPtrWrap(char *str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString(str); + ret = PY_IMPORT_STRING(str); xmlFree(str); return (ret); } @@ -75,8 +151,7 @@ libxml_charPtrConstWrap(const char *str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString(str); + ret = PY_IMPORT_STRING(str); return (ret); } @@ -92,8 +167,7 @@ libxml_xmlCharPtrWrap(xmlChar * str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString((char *) str); + ret = PY_IMPORT_STRING((char *) str); xmlFree(str); return (ret); } @@ -110,8 +184,7 @@ libxml_xmlCharPtrConstWrap(const xmlChar * str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString((char *) str); + ret = PY_IMPORT_STRING((char *) str); return (ret); } @@ -127,8 +200,7 @@ libxml_constcharPtrWrap(const char *str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString(str); + ret = PY_IMPORT_STRING(str); return (ret); } @@ -144,8 +216,7 @@ libxml_constxmlCharPtrWrap(const xmlChar * str) Py_INCREF(Py_None); return (Py_None); } - /* TODO: look at deallocation */ - ret = PyString_FromString((char *) str); + ret = PY_IMPORT_STRING((char *) str); return (ret); } @@ -162,9 +233,7 @@ libxml_xmlDocPtrWrap(xmlDocPtr doc) return (Py_None); } /* TODO: look at deallocation */ - ret = - PyCObject_FromVoidPtrAndDesc((void *) doc, (char *) "xmlDocPtr", - NULL); + ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL); return (ret); } @@ -180,9 +249,7 @@ libxml_xmlNodePtrWrap(xmlNodePtr node) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "xmlNodePtr", - NULL); + ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL); return (ret); } @@ -198,9 +265,7 @@ libxml_xmlURIPtrWrap(xmlURIPtr uri) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) uri, (char *) "xmlURIPtr", - NULL); + ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL); return (ret); } @@ -216,9 +281,7 @@ libxml_xmlNsPtrWrap(xmlNsPtr ns) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) ns, (char *) "xmlNsPtr", - NULL); + ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL); return (ret); } @@ -234,9 +297,7 @@ libxml_xmlAttrPtrWrap(xmlAttrPtr attr) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) attr, (char *) "xmlAttrPtr", - NULL); + ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL); return (ret); } @@ -252,9 +313,7 @@ libxml_xmlAttributePtrWrap(xmlAttributePtr attr) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) attr, - (char *) "xmlAttributePtr", NULL); + ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL); return (ret); } @@ -270,9 +329,7 @@ libxml_xmlElementPtrWrap(xmlElementPtr elem) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) elem, - (char *) "xmlElementPtr", NULL); + ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL); return (ret); } @@ -288,9 +345,7 @@ libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, - (char *) "xmlXPathContextPtr", NULL); + ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL); return (ret); } @@ -306,9 +361,7 @@ libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt) Py_INCREF(Py_None); return (Py_None); } - ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, - (char *) "xmlXPathParserContextPtr", - NULL); + ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL); return (ret); } @@ -325,28 +378,35 @@ libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt) return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, - (char *) "xmlParserCtxtPtr", NULL); + ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL); return (ret); } /** * libxml_xmlXPathDestructNsNode: - * cobj: xmlNsPtr namespace node - * desc: ignored string + * cap: xmlNsPtr namespace node capsule object * * This function is called if and when a namespace node returned in * an XPath node set is to be destroyed. That's the only kind of * 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 *cap, void *desc ATTRIBUTE_UNUSED) +#else static void -libxml_xmlXPathDestructNsNode(void *cobj, void *desc ATTRIBUTE_UNUSED) { +libxml_xmlXPathDestructNsNode(PyObject *cap) +#endif +{ #ifdef DEBUG - fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cobj); + fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cap); +#endif +#if PY_VERSION_HEX < 0x02070000 + xmlXPathNodeSetFreeNs((xmlNsPtr) cap); +#else + xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr")); #endif - xmlXPathNodeSetFreeNs((xmlNsPtr) cobj); } PyObject * @@ -400,8 +460,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) for (i = 0; i < obj->nodesetval->nodeNr; i++) { node = obj->nodesetval->nodeTab[i]; if (node->type == XML_NAMESPACE_DECL) { - PyObject *ns = - PyCObject_FromVoidPtrAndDesc((void *) node, + PyObject *ns = PyCapsule_New((void *) node, (char *) "xmlNsPtr", libxml_xmlXPathDestructNsNode); PyList_SetItem(ret, i, ns); @@ -414,13 +473,13 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) } break; case XPATH_BOOLEAN: - ret = PyInt_FromLong((long) obj->boolval); + ret = PY_IMPORT_INT((long) obj->boolval); break; case XPATH_NUMBER: ret = PyFloat_FromDouble(obj->floatval); break; case XPATH_STRING: - ret = PyString_FromString((char *) obj->stringval); + ret = PY_IMPORT_STRING((char *) obj->stringval); break; case XPATH_POINT: { @@ -429,7 +488,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) PyObject *tuple; node = libxml_xmlNodePtrWrap(obj->user); - indexIntoNode = PyInt_FromLong((long) obj->index); + indexIntoNode = PY_IMPORT_INT((long) obj->index); tuple = PyTuple_New(2); PyTuple_SetItem(tuple, 0, node); @@ -453,7 +512,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) list = PyList_New(1); node = libxml_xmlNodePtrWrap(obj->user); - indexIntoNode = PyInt_FromLong((long) obj->index); + indexIntoNode = PY_IMPORT_INT((long) obj->index); tuple = PyTuple_New(2); PyTuple_SetItem(tuple, 0, node); @@ -471,7 +530,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) list = PyList_New(2); node = libxml_xmlNodePtrWrap(obj->user); - indexIntoNode = PyInt_FromLong((long) obj->index); + indexIntoNode = PY_IMPORT_INT((long) obj->index); tuple = PyTuple_New(2); PyTuple_SetItem(tuple, 0, node); @@ -480,7 +539,7 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) PyList_SetItem(list, 0, tuple); node = libxml_xmlNodePtrWrap(obj->user2); - indexIntoNode = PyInt_FromLong((long) obj->index2); + indexIntoNode = PY_IMPORT_INT((long) obj->index2); tuple = PyTuple_New(2); PyTuple_SetItem(tuple, 0, node); @@ -545,14 +604,14 @@ 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 PyInt_Check(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) { @@ -563,15 +622,37 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) ret = xmlXPathNewBoolean(0); } #endif - } else if PyString_Check - (obj) { + } else if PyBytes_Check (obj) { xmlChar *str; - str = xmlStrndup((const xmlChar *) PyString_AS_STRING(obj), - PyString_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; + size_t size; + + /* tmp doesn't need to be deallocated */ + tmp = PyUnicode_AsUTF8AndSize(obj, &size); + str = xmlStrndup(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,28 +666,18 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) continue; cur = NULL; - if (PyCObject_Check(node)) { + if (PyCapsule_CheckExact(node)) { #ifdef DEBUG - printf("Got a CObject\n"); + printf("Got a Capsule\n"); #endif cur = PyxmlNode_Get(node); - } 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); - } - } - } + } 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"); @@ -622,7 +693,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj) printf("Unable to convert Python Object to XPath"); #endif } - Py_DECREF(obj); return (ret); } @@ -630,7 +700,7 @@ PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid) { PyObject *ret; - + #ifdef DEBUG printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid); #endif @@ -640,7 +710,7 @@ libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid) } ret = - PyCObject_FromVoidPtrAndDesc((void *) valid, + PyCapsule_New((void *) valid, (char *) "xmlValidCtxtPtr", NULL); return (ret); @@ -659,7 +729,7 @@ libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) catal, + PyCapsule_New((void *) catal, (char *) "xmlCatalogPtr", NULL); return (ret); } @@ -677,7 +747,7 @@ libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) buffer, + PyCapsule_New((void *) buffer, (char *) "xmlOutputBufferPtr", NULL); return (ret); } @@ -695,7 +765,7 @@ libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) buffer, + PyCapsule_New((void *) buffer, (char *) "xmlParserInputBufferPtr", NULL); return (ret); } @@ -714,7 +784,7 @@ libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) regexp, + PyCapsule_New((void *) regexp, (char *) "xmlRegexpPtr", NULL); return (ret); } @@ -734,7 +804,7 @@ libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) reader, + PyCapsule_New((void *) reader, (char *) "xmlTextReaderPtr", NULL); return (ret); } @@ -752,7 +822,7 @@ libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) locator, + PyCapsule_New((void *) locator, (char *) "xmlTextReaderLocatorPtr", NULL); return (ret); } @@ -772,7 +842,7 @@ libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, + PyCapsule_New((void *) ctxt, (char *) "xmlRelaxNGPtr", NULL); return (ret); } @@ -790,7 +860,7 @@ libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, + PyCapsule_New((void *) ctxt, (char *) "xmlRelaxNGParserCtxtPtr", NULL); return (ret); } @@ -807,7 +877,7 @@ libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) valid, + PyCapsule_New((void *) valid, (char *) "xmlRelaxNGValidCtxtPtr", NULL); return (ret); } @@ -825,7 +895,7 @@ libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, + PyCapsule_New((void *) ctxt, (char *) "xmlSchemaPtr", NULL); return (ret); } @@ -843,7 +913,7 @@ libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt) return (Py_None); } ret = - PyCObject_FromVoidPtrAndDesc((void *) ctxt, + PyCapsule_New((void *) ctxt, (char *) "xmlSchemaParserCtxtPtr", NULL); return (ret); @@ -863,7 +933,7 @@ libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid) } ret = - PyCObject_FromVoidPtrAndDesc((void *) valid, + PyCapsule_New((void *) valid, (char *) "xmlSchemaValidCtxtPtr", NULL); return (ret); @@ -882,8 +952,6 @@ libxml_xmlErrorPtrWrap(xmlErrorPtr error) Py_INCREF(Py_None); return (Py_None); } - ret = - PyCObject_FromVoidPtrAndDesc((void *) error, - (char *) "xmlErrorPtr", NULL); + ret = PyCapsule_New((void *) error, (char *) "xmlErrorPtr", NULL); return (ret); } |