From 0e9b73b8d1072030eea212a5ae242632cce9d967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Tue, 17 Oct 2023 14:43:27 +0200 Subject: [PATCH] Import from Fedora python-lxml @ 55f5648 Resolves: RHEL-17739 --- .fmf/version | 1 + .gitignore | 64 + 380.patch | 24 + ...ion-of-ISO-Schematron-files-optional.patch | 116 ++ ...-failing-test-test_html_prefix_nsmap.patch | 34 + ...4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch | 402 ++++ ci.fmf | 1 + ...0cc1cb0cedf8019184aaca805d2a649cd8de.patch | 1088 +++++++++++ gating.yaml | 8 + get-lxml-source.sh | 28 + plans/etree-fromstring.py | 7 + plans/smoke.fmf | 12 + python-lxml.spec | 1728 +++++++++++++++++ sources | 1 + 14 files changed, 3514 insertions(+) create mode 100644 .fmf/version create mode 100644 380.patch create mode 100644 Make-the-validation-of-ISO-Schematron-files-optional.patch create mode 100644 Skip-failing-test-test_html_prefix_nsmap.patch create mode 100644 a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch create mode 100644 ci.fmf create mode 100644 dcbc0cc1cb0cedf8019184aaca805d2a649cd8de.patch create mode 100644 gating.yaml create mode 100755 get-lxml-source.sh create mode 100644 plans/etree-fromstring.py create mode 100644 plans/smoke.fmf create mode 100644 python-lxml.spec create mode 100644 sources diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore index e69de29..b381b1f 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,64 @@ +lxml-2.2.7.tar.gz +lxml-2.2.7.tar.gz.asc +/lxml-2.2.8.tar.gz +/lxml-2.2.8.tar.gz.asc +/lxml-2.3.tar.gz +/lxml-2.3.tar.gz.asc +/lxml-2.3.1.tar.gz +/lxml-2.3.1.tar.gz.asc +/lxml-2.3.2.tar.gz +/lxml-2.3.2.tar.gz.asc +/lxml-2.3.3.tar.gz +/lxml-2.3.3.tar.gz.asc +/lxml-2.3.5.tar.gz +/lxml-2.3.5.tar.gz.asc +/lxml-3.0.tar.gz +/lxml-3.0.tar.gz.asc +/lxml-3.0.tgz +/lxml-3.0.tgz.asc +/lxml-3.0.1.tgz +/lxml-3.0.1.tgz.asc +/lxml-3.1.0.tgz +/lxml-3.1.0.tgz.asc +/lxml-3.2.0.tgz +/lxml-3.2.0.tgz.asc +/lxml-3.2.1.tgz +/lxml-3.2.1.tgz.asc +/lxml-3.2.3.tgz +/lxml-3.2.3.tgz.asc +/lxml-3.2.4.tgz +/lxml-3.2.4.tgz.asc +/lxml-3.3.0.tgz +/lxml-3.3.0.tgz.asc +/lxml-3.3.2.tgz +/lxml-3.3.2.tgz.asc +/lxml-3.3.3.tgz +/lxml-3.3.3.tgz.asc +/lxml-3.3.5.tgz +/lxml-3.3.5.tgz.asc +/lxml-3.3.6.tgz +/lxml-3.3.6.tgz.asc +/lxml-3.4.4.tgz +/lxml-3.4.4.tgz.asc +/lxml-3.6.4.tar.gz +/lxml-3.7.0.tar.gz +/lxml-3.7.1.tgz +/lxml-3.7.2.tgz +/lxml-3.8.0.tgz +/lxml-4.0.0.tgz +/lxml-4.1.1.tgz +/lxml-4.2.1.tgz +/lxml-4.2.3.tgz +/lxml-4.2.4.tgz +/lxml-4.2.5.tgz +/lxml-4.4.0.tgz +/lxml-4.4.1.tgz +/lxml-4.5.1.tgz +/lxml-4.6.2.tar.gz +/lxml-4.6.3.tar.gz +/lxml-4.7.1.tar.gz +/lxml-4.9.1.tar.gz +/lxml-4.9.2.tar.gz +/lxml-4.9.2-no-isoschematron.tar.gz +/lxml-4.9.2-no-isoschematron-rng.tar.gz +/lxml-4.9.3-no-isoschematron-rng.tar.gz diff --git a/380.patch b/380.patch new file mode 100644 index 0000000..daac445 --- /dev/null +++ b/380.patch @@ -0,0 +1,24 @@ +From d18f2f22218ea0e0b5327b5a2bda789afdf16e41 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Fri, 14 Jul 2023 12:18:25 +0200 +Subject: [PATCH] Skip test_isoschematron.test_schematron_invalid_schema_empty + without the RNG file + +The expected SchematronParseError only happens when validate_schema is true. +--- + src/lxml/tests/test_isoschematron.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/lxml/tests/test_isoschematron.py b/src/lxml/tests/test_isoschematron.py +index 6d2aa3fb6..900f257c3 100644 +--- a/src/lxml/tests/test_isoschematron.py ++++ b/src/lxml/tests/test_isoschematron.py +@@ -55,6 +55,8 @@ def test_schematron_empty_pattern(self): + schema = isoschematron.Schematron(schema) + self.assertTrue(schema) + ++ @unittest.skipIf(not isoschematron.schematron_schema_valid_supported, ++ 'SchematronParseError is risen only when validate_schema is true') + def test_schematron_invalid_schema_empty(self): + schema = self.parse('''\ + diff --git a/Make-the-validation-of-ISO-Schematron-files-optional.patch b/Make-the-validation-of-ISO-Schematron-files-optional.patch new file mode 100644 index 0000000..3bc8132 --- /dev/null +++ b/Make-the-validation-of-ISO-Schematron-files-optional.patch @@ -0,0 +1,116 @@ +From a500f721e3b34018f0a86af275427663dc337b5a Mon Sep 17 00:00:00 2001 +From: Stefan Behnel +Date: Wed, 12 Jul 2023 16:59:07 +0200 +Subject: [PATCH] Make the validation of ISO-Schematron files optional in lxml, + depending on the availability of the RNG validation file. Some lxml + distributions discard the validation schema file due to licensing issues. + +See https://bugs.launchpad.net/lxml/+bug/2024343 +--- + CHANGES.txt | 11 +++++++++++ + doc/validation.txt | 9 +++++++++ + src/lxml/isoschematron/__init__.py | 24 +++++++++++++++++++----- + 3 files changed, 39 insertions(+), 5 deletions(-) + +diff --git a/CHANGES.txt b/CHANGES.txt +index 24052db..e68ee9a 100644 +--- a/CHANGES.txt ++++ b/CHANGES.txt +@@ -2,6 +2,17 @@ + lxml changelog + ============== + ++4.9.3+ ++====== ++ ++* LP#2024343: The validation of the schema file itself is now optional in the ++ ISO-Schematron implementation. This was done because some lxml distributions ++ discard the RNG validation schema file due to licensing issues. The validation ++ can now always be disabled with ``Schematron(..., validate_schema=False)``. ++ It is enabled by default if available and disabled otherwise. The module ++ constant ``lxml.isoschematron.schematron_schema_valid_supported`` can be used ++ to detect whether schema file validation is available. ++ + 4.9.3 (2023-07-05) + ================== + +diff --git a/doc/validation.txt b/doc/validation.txt +index af9d007..27c0ccd 100644 +--- a/doc/validation.txt ++++ b/doc/validation.txt +@@ -615,6 +615,15 @@ The usage of validation phases is a unique feature of ISO-Schematron and can be + a very powerful tool e.g. for establishing validation stages or to provide + different validators for different "validation audiences". + ++Note: Some lxml distributions exclude the validation schema file due to licensing issues. ++Since lxml 4.9.2-8, the validation of the user provided schema can be disabled with ++``Schematron(..., validate_schema=False)``. ++It is enabled by default if available and disabled otherwise. Previous versions of ++lxml always had it enabled and failed at import time if the file was not available. ++Thus, some distributions chose to remove the entire ISO-Schematron support. ++The module constant ``lxml.isoschematron.schematron_schema_valid_supported`` can be used ++since lxml 4.9.2-8 to detect whether schema file validation is available. ++ + (Pre-ISO-Schematron) + -------------------- + +diff --git a/src/lxml/isoschematron/__init__.py b/src/lxml/isoschematron/__init__.py +index 5967b10..2846a66 100644 +--- a/src/lxml/isoschematron/__init__.py ++++ b/src/lxml/isoschematron/__init__.py +@@ -61,10 +61,16 @@ iso_svrl_for_xslt1 = _etree.XSLT(_etree.parse( + svrl_validation_errors = _etree.XPath( + '//svrl:failed-assert', namespaces={'svrl': SVRL_NS}) + +- + # RelaxNG validator for schematron schemas +-schematron_schema_valid = _etree.RelaxNG( +- file=os.path.join(_resources_dir, 'rng', 'iso-schematron.rng')) ++schematron_schema_valid_supported = False ++try: ++ schematron_schema_valid = _etree.RelaxNG( ++ file=os.path.join(_resources_dir, 'rng', 'iso-schematron.rng')) ++ schematron_schema_valid_supported = True ++except _etree.RelaxNGParseError: ++ # Some distributions delete the file due to licensing issues. ++ def schematron_schema_valid(arg): ++ raise NotImplementedError("Validating the ISO schematron requires iso-schematron.rng") + + + def stylesheet_params(**kwargs): +@@ -153,6 +159,13 @@ class Schematron(_etree._Validator): + report document gets stored and can be accessed as the ``validation_report`` + property. + ++ If ``validate_schema`` is set to False, the validation of the schema file ++ itself is disabled. Validation happens by default after building the full ++ schema, unless the schema validation file cannot be found at import time, ++ in which case the validation gets disabled. Some lxml distributions exclude ++ this file due to licensing issues. ISO-Schematron validation can then still ++ be used normally, but the schemas themselves cannot be validated. ++ + Here is a usage example:: + + >>> from lxml import etree +@@ -234,7 +247,8 @@ class Schematron(_etree._Validator): + def __init__(self, etree=None, file=None, include=True, expand=True, + include_params={}, expand_params={}, compile_params={}, + store_schematron=False, store_xslt=False, store_report=False, +- phase=None, error_finder=ASSERTS_ONLY): ++ phase=None, error_finder=ASSERTS_ONLY, ++ validate_schema=schematron_schema_valid_supported): + super(Schematron, self).__init__() + + self._store_report = store_report +@@ -273,7 +287,7 @@ class Schematron(_etree._Validator): + schematron = self._include(schematron, **include_params) + if expand: + schematron = self._expand(schematron, **expand_params) +- if not schematron_schema_valid(schematron): ++ if validate_schema and not schematron_schema_valid(schematron): + raise _etree.SchematronParseError( + "invalid schematron schema: %s" % + schematron_schema_valid.error_log) +-- +2.40.1 + diff --git a/Skip-failing-test-test_html_prefix_nsmap.patch b/Skip-failing-test-test_html_prefix_nsmap.patch new file mode 100644 index 0000000..7d936e3 --- /dev/null +++ b/Skip-failing-test-test_html_prefix_nsmap.patch @@ -0,0 +1,34 @@ +From 91729cf581f764c3321f644206568f18d0fc92f4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= +Date: Thu, 18 May 2023 08:00:48 +0200 +Subject: [PATCH] Skip failing test test_html_prefix_nsmap + +Upstream issue: https://bugs.launchpad.net/lxml/+bug/2016939 +--- + src/lxml/tests/test_etree.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py +index 0339796..1994a7f 100644 +--- a/src/lxml/tests/test_etree.py ++++ b/src/lxml/tests/test_etree.py +@@ -27,6 +27,8 @@ from .common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_d + from .common_imports import canonicalize, _str, _bytes + from .common_imports import SimpleFSPath + ++from unittest import skip ++ + print(""" + TESTED VERSION: %s""" % etree.__version__ + """ + Python: %r""" % (sys.version_info,) + """ +@@ -3067,6 +3069,7 @@ class ETreeOnlyTestCase(HelperTestCase): + self.assertEqual(re, e.nsmap) + self.assertEqual(r, s.nsmap) + ++ @skip + def test_html_prefix_nsmap(self): + etree = self.etree + el = etree.HTML('aa').find('.//page-description') +-- +2.40.1 + diff --git a/a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch b/a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch new file mode 100644 index 0000000..bd02346 --- /dev/null +++ b/a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch @@ -0,0 +1,402 @@ +From a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76 Mon Sep 17 00:00:00 2001 +From: Stefan Behnel +Date: Fri, 23 Dec 2022 10:46:32 +0100 +Subject: [PATCH] Use "noexcept" modifiers for callback functions and fix some + exception value declaration bugs found by Cython 3.0. + +--- + src/lxml/extensions.pxi | 6 +++--- + src/lxml/includes/tree.pxd | 10 +++++----- + src/lxml/includes/xmlerror.pxd | 4 ++-- + src/lxml/includes/xmlparser.pxd | 24 ++++++++++++------------ + src/lxml/parser.pxi | 10 +++++----- + src/lxml/saxparser.pxi | 26 +++++++++++++------------- + src/lxml/serializer.pxi | 4 ++-- + src/lxml/xmlerror.pxi | 14 +++++++------- + src/lxml/xpath.pxi | 2 +- + 9 files changed, 50 insertions(+), 50 deletions(-) + +diff --git a/src/lxml/extensions.pxi b/src/lxml/extensions.pxi +index 35a321b7a..80e53d7b5 100644 +--- a/src/lxml/extensions.pxi ++++ b/src/lxml/extensions.pxi +@@ -393,7 +393,7 @@ cdef tuple LIBXML2_XPATH_ERROR_MESSAGES = ( + b"?? Unknown error ??\n", + ) + +-cdef void _forwardXPathError(void* c_ctxt, xmlerror.xmlError* c_error) with gil: ++cdef void _forwardXPathError(void* c_ctxt, xmlerror.xmlError* c_error) noexcept with gil: + cdef xmlerror.xmlError error + cdef int xpath_code + if c_error.message is not NULL: +@@ -414,7 +414,7 @@ cdef void _forwardXPathError(void* c_ctxt, xmlerror.xmlError* c_error) with gil: + + (<_BaseContext>c_ctxt)._error_log._receive(&error) + +-cdef void _receiveXPathError(void* c_context, xmlerror.xmlError* error) nogil: ++cdef void _receiveXPathError(void* c_context, xmlerror.xmlError* error) noexcept nogil: + if not __DEBUG: + return + if c_context is NULL: +@@ -851,7 +851,7 @@ cdef void _extension_function_call(_BaseContext context, function, + # lookup the function by name and call it + + cdef void _xpath_function_call(xpath.xmlXPathParserContext* ctxt, +- int nargs) with gil: ++ int nargs) noexcept with gil: + cdef _BaseContext context + cdef xpath.xmlXPathContext* rctxt = ctxt.context + context = <_BaseContext> rctxt.userData +diff --git a/src/lxml/includes/tree.pxd b/src/lxml/includes/tree.pxd +index 03d558a33..312537cbd 100644 +--- a/src/lxml/includes/tree.pxd ++++ b/src/lxml/includes/tree.pxd +@@ -65,7 +65,7 @@ cdef extern from "libxml/chvalid.h" nogil: + + cdef extern from "libxml/hash.h": + ctypedef struct xmlHashTable +- ctypedef void (*xmlHashScanner)(void* payload, void* data, const_xmlChar* name) # may require GIL! ++ ctypedef void (*xmlHashScanner)(void* payload, void* data, const_xmlChar* name) noexcept # may require GIL! + void xmlHashScan(xmlHashTable* table, xmlHashScanner f, void* data) nogil + void* xmlHashLookup(xmlHashTable* table, const_xmlChar* name) nogil + ctypedef void (*xmlHashDeallocator)(void *payload, xmlChar *name) +@@ -411,12 +411,12 @@ cdef extern from "libxml/xmlIO.h": + cdef int xmlOutputBufferClose(xmlOutputBuffer* out) nogil + + ctypedef int (*xmlInputReadCallback)(void* context, +- char* buffer, int len) nogil +- ctypedef int (*xmlInputCloseCallback)(void* context) nogil ++ char* buffer, int len) except -1 nogil ++ ctypedef int (*xmlInputCloseCallback)(void* context) except -1 nogil + + ctypedef int (*xmlOutputWriteCallback)(void* context, +- char* buffer, int len) +- ctypedef int (*xmlOutputCloseCallback)(void* context) ++ char* buffer, int len) except -1 ++ ctypedef int (*xmlOutputCloseCallback)(void* context) except -1 + + cdef xmlOutputBuffer* xmlAllocOutputBuffer( + xmlCharEncodingHandler* encoder) nogil +diff --git a/src/lxml/includes/xmlerror.pxd b/src/lxml/includes/xmlerror.pxd +index c5ac6a0aa..6967378b7 100644 +--- a/src/lxml/includes/xmlerror.pxd ++++ b/src/lxml/includes/xmlerror.pxd +@@ -838,9 +838,9 @@ cdef extern from "libxml/xmlerror.h" nogil: + int int2 + void* node + +- ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...) ++ ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...) noexcept + ctypedef void (*xmlStructuredErrorFunc)(void* userData, +- xmlError* error) ++ xmlError* error) noexcept + + cdef void xmlSetGenericErrorFunc( + void* ctxt, xmlGenericErrorFunc func) +diff --git a/src/lxml/includes/xmlparser.pxd b/src/lxml/includes/xmlparser.pxd +index 9f3056248..c94212cee 100644 +--- a/src/lxml/includes/xmlparser.pxd ++++ b/src/lxml/includes/xmlparser.pxd +@@ -15,37 +15,37 @@ cdef extern from "libxml/parser.h" nogil: + const_xmlChar** namespaces, + int nb_attributes, + int nb_defaulted, +- const_xmlChar** attributes) ++ const_xmlChar** attributes) noexcept + + ctypedef void (*endElementNsSAX2Func)(void* ctx, + const_xmlChar* localname, + const_xmlChar* prefix, +- const_xmlChar* URI) ++ const_xmlChar* URI) noexcept + +- ctypedef void (*startElementSAXFunc)(void* ctx, const_xmlChar* name, const_xmlChar** atts) ++ ctypedef void (*startElementSAXFunc)(void* ctx, const_xmlChar* name, const_xmlChar** atts) noexcept + +- ctypedef void (*endElementSAXFunc)(void* ctx, const_xmlChar* name) ++ ctypedef void (*endElementSAXFunc)(void* ctx, const_xmlChar* name) noexcept + +- ctypedef void (*charactersSAXFunc)(void* ctx, const_xmlChar* ch, int len) ++ ctypedef void (*charactersSAXFunc)(void* ctx, const_xmlChar* ch, int len) noexcept + +- ctypedef void (*cdataBlockSAXFunc)(void* ctx, const_xmlChar* value, int len) ++ ctypedef void (*cdataBlockSAXFunc)(void* ctx, const_xmlChar* value, int len) noexcept + +- ctypedef void (*commentSAXFunc)(void* ctx, const_xmlChar* value) ++ ctypedef void (*commentSAXFunc)(void* ctx, const_xmlChar* value) noexcept + + ctypedef void (*processingInstructionSAXFunc)(void* ctx, + const_xmlChar* target, +- const_xmlChar* data) ++ const_xmlChar* data) noexcept + + ctypedef void (*internalSubsetSAXFunc)(void* ctx, + const_xmlChar* name, + const_xmlChar* externalID, +- const_xmlChar* systemID) ++ const_xmlChar* systemID) noexcept + +- ctypedef void (*endDocumentSAXFunc)(void* ctx) ++ ctypedef void (*endDocumentSAXFunc)(void* ctx) noexcept + +- ctypedef void (*startDocumentSAXFunc)(void* ctx) ++ ctypedef void (*startDocumentSAXFunc)(void* ctx) noexcept + +- ctypedef void (*referenceSAXFunc)(void * ctx, const_xmlChar* name) ++ ctypedef void (*referenceSAXFunc)(void * ctx, const_xmlChar* name) noexcept + + cdef int XML_SAX2_MAGIC + +diff --git a/src/lxml/parser.pxi b/src/lxml/parser.pxi +index f0c8c6b64..e1e9da9f0 100644 +--- a/src/lxml/parser.pxi ++++ b/src/lxml/parser.pxi +@@ -402,10 +402,10 @@ cdef class _FileReaderContext: + finally: + return c_byte_count # swallow any exceptions + +-cdef int _readFilelikeParser(void* ctxt, char* c_buffer, int c_size) with gil: ++cdef int _readFilelikeParser(void* ctxt, char* c_buffer, int c_size) except -1 with gil: + return (<_FileReaderContext>ctxt).copyToBuffer(c_buffer, c_size) + +-cdef int _readFileParser(void* ctxt, char* c_buffer, int c_size) nogil: ++cdef int _readFileParser(void* ctxt, char* c_buffer, int c_size) except -1 nogil: + return stdio.fread(c_buffer, 1, c_size, ctxt) + + ############################################################ +@@ -626,10 +626,10 @@ cdef _initParserContext(_ParserContext context, + if c_ctxt is not NULL: + context._initParserContext(c_ctxt) + +-cdef void _forwardParserError(xmlparser.xmlParserCtxt* _parser_context, xmlerror.xmlError* error) with gil: ++cdef void _forwardParserError(xmlparser.xmlParserCtxt* _parser_context, xmlerror.xmlError* error) noexcept with gil: + (<_ParserContext>_parser_context._private)._error_log._receive(error) + +-cdef void _receiveParserError(void* c_context, xmlerror.xmlError* error) nogil: ++cdef void _receiveParserError(void* c_context, xmlerror.xmlError* error) noexcept nogil: + if __DEBUG: + if c_context is NULL or (c_context)._private is NULL: + _forwardError(NULL, error) +@@ -1207,7 +1207,7 @@ cdef class _BaseParser: + context.cleanup() + + +-cdef void _initSaxDocument(void* ctxt) with gil: ++cdef void _initSaxDocument(void* ctxt) noexcept with gil: + xmlparser.xmlSAX2StartDocument(ctxt) + c_ctxt = ctxt + c_doc = c_ctxt.myDoc +diff --git a/src/lxml/saxparser.pxi b/src/lxml/saxparser.pxi +index 49e72beaf..1737f0801 100644 +--- a/src/lxml/saxparser.pxi ++++ b/src/lxml/saxparser.pxi +@@ -294,7 +294,7 @@ cdef void _handleSaxStart( + const_xmlChar* c_namespace, int c_nb_namespaces, + const_xmlChar** c_namespaces, + int c_nb_attributes, int c_nb_defaulted, +- const_xmlChar** c_attributes) with gil: ++ const_xmlChar** c_attributes) noexcept with gil: + cdef int i + cdef size_t c_len + c_ctxt = ctxt +@@ -336,7 +336,7 @@ cdef void _handleSaxTargetStart( + const_xmlChar* c_namespace, int c_nb_namespaces, + const_xmlChar** c_namespaces, + int c_nb_attributes, int c_nb_defaulted, +- const_xmlChar** c_attributes) with gil: ++ const_xmlChar** c_attributes) noexcept with gil: + cdef int i + cdef size_t c_len + c_ctxt = ctxt +@@ -407,7 +407,7 @@ cdef void _handleSaxTargetStart( + + + cdef void _handleSaxStartNoNs(void* ctxt, const_xmlChar* c_name, +- const_xmlChar** c_attributes) with gil: ++ const_xmlChar** c_attributes) noexcept with gil: + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: + return +@@ -426,7 +426,7 @@ cdef void _handleSaxStartNoNs(void* ctxt, const_xmlChar* c_name, + + + cdef void _handleSaxTargetStartNoNs(void* ctxt, const_xmlChar* c_name, +- const_xmlChar** c_attributes) with gil: ++ const_xmlChar** c_attributes) noexcept with gil: + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: + return +@@ -483,7 +483,7 @@ cdef int _pushSaxStartEvent(_SaxParserContext context, + + cdef void _handleSaxEnd(void* ctxt, const_xmlChar* c_localname, + const_xmlChar* c_prefix, +- const_xmlChar* c_namespace) with gil: ++ const_xmlChar* c_namespace) noexcept with gil: + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: + return +@@ -506,7 +506,7 @@ cdef void _handleSaxEnd(void* ctxt, const_xmlChar* c_localname, + return # swallow any further exceptions + + +-cdef void _handleSaxEndNoNs(void* ctxt, const_xmlChar* c_name) with gil: ++cdef void _handleSaxEndNoNs(void* ctxt, const_xmlChar* c_name) noexcept with gil: + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: + return +@@ -558,7 +558,7 @@ cdef int _pushSaxEndEvent(_SaxParserContext context, + return 0 + + +-cdef void _handleSaxData(void* ctxt, const_xmlChar* c_data, int data_len) with gil: ++cdef void _handleSaxData(void* ctxt, const_xmlChar* c_data, int data_len) noexcept with gil: + # can only be called if parsing with a target + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +@@ -575,7 +575,7 @@ cdef void _handleSaxData(void* ctxt, const_xmlChar* c_data, int data_len) with g + + cdef void _handleSaxTargetDoctype(void* ctxt, const_xmlChar* c_name, + const_xmlChar* c_public, +- const_xmlChar* c_system) with gil: ++ const_xmlChar* c_system) noexcept with gil: + # can only be called if parsing with a target + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +@@ -592,7 +592,7 @@ cdef void _handleSaxTargetDoctype(void* ctxt, const_xmlChar* c_name, + return # swallow any further exceptions + + +-cdef void _handleSaxStartDocument(void* ctxt) with gil: ++cdef void _handleSaxStartDocument(void* ctxt) noexcept with gil: + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: + return +@@ -608,7 +608,7 @@ cdef void _handleSaxStartDocument(void* ctxt) with gil: + + + cdef void _handleSaxTargetPI(void* ctxt, const_xmlChar* c_target, +- const_xmlChar* c_data) with gil: ++ const_xmlChar* c_data) noexcept with gil: + # can only be called if parsing with a target + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +@@ -627,7 +627,7 @@ cdef void _handleSaxTargetPI(void* ctxt, const_xmlChar* c_target, + + + cdef void _handleSaxPIEvent(void* ctxt, const_xmlChar* target, +- const_xmlChar* data) with gil: ++ const_xmlChar* data) noexcept with gil: + # can only be called when collecting pi events + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +@@ -645,7 +645,7 @@ cdef void _handleSaxPIEvent(void* ctxt, const_xmlChar* target, + return # swallow any further exceptions + + +-cdef void _handleSaxTargetComment(void* ctxt, const_xmlChar* c_data) with gil: ++cdef void _handleSaxTargetComment(void* ctxt, const_xmlChar* c_data) noexcept with gil: + # can only be called if parsing with a target + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +@@ -661,7 +661,7 @@ cdef void _handleSaxTargetComment(void* ctxt, const_xmlChar* c_data) with gil: + return # swallow any further exceptions + + +-cdef void _handleSaxComment(void* ctxt, const_xmlChar* text) with gil: ++cdef void _handleSaxComment(void* ctxt, const_xmlChar* text) noexcept with gil: + # can only be called when collecting comment events + c_ctxt = ctxt + if c_ctxt._private is NULL or c_ctxt.disableSAX: +diff --git a/src/lxml/serializer.pxi b/src/lxml/serializer.pxi +index 79a02829e..e1c76e1ba 100644 +--- a/src/lxml/serializer.pxi ++++ b/src/lxml/serializer.pxi +@@ -699,10 +699,10 @@ cdef class _FilelikeWriter: + finally: + return retval # and swallow any further exceptions + +-cdef int _writeFilelikeWriter(void* ctxt, char* c_buffer, int length): ++cdef int _writeFilelikeWriter(void* ctxt, char* c_buffer, int length) except -1: + return (<_FilelikeWriter>ctxt).write(c_buffer, length) + +-cdef int _closeFilelikeWriter(void* ctxt): ++cdef int _closeFilelikeWriter(void* ctxt) except -1: + return (<_FilelikeWriter>ctxt).close() + + cdef _tofilelike(f, _Element element, encoding, doctype, method, +diff --git a/src/lxml/xmlerror.pxi b/src/lxml/xmlerror.pxi +index 1b50444fb..793e1d923 100644 +--- a/src/lxml/xmlerror.pxi ++++ b/src/lxml/xmlerror.pxi +@@ -634,7 +634,7 @@ def use_global_python_log(PyErrorLog log not None): + + + # local log functions: forward error to logger object +-cdef void _forwardError(void* c_log_handler, xmlerror.xmlError* error) with gil: ++cdef void _forwardError(void* c_log_handler, xmlerror.xmlError* error) noexcept with gil: + cdef _BaseErrorLog log_handler + if c_log_handler is not NULL: + log_handler = <_BaseErrorLog>c_log_handler +@@ -645,27 +645,27 @@ cdef void _forwardError(void* c_log_handler, xmlerror.xmlError* error) with gil: + log_handler._receive(error) + + +-cdef void _receiveError(void* c_log_handler, xmlerror.xmlError* error) nogil: ++cdef void _receiveError(void* c_log_handler, xmlerror.xmlError* error) noexcept nogil: + # no Python objects here, may be called without thread context ! + if __DEBUG: + _forwardError(c_log_handler, error) + + +-cdef void _receiveXSLTError(void* c_log_handler, char* msg, ...) nogil: ++cdef void _receiveXSLTError(void* c_log_handler, char* msg, ...) noexcept nogil: + # no Python objects here, may be called without thread context ! + cdef cvarargs.va_list args + cvarargs.va_start(args, msg) + _receiveGenericError(c_log_handler, xmlerror.XML_FROM_XSLT, msg, args) + cvarargs.va_end(args) + +-cdef void _receiveRelaxNGParseError(void* c_log_handler, char* msg, ...) nogil: ++cdef void _receiveRelaxNGParseError(void* c_log_handler, char* msg, ...) noexcept nogil: + # no Python objects here, may be called without thread context ! + cdef cvarargs.va_list args + cvarargs.va_start(args, msg) + _receiveGenericError(c_log_handler, xmlerror.XML_FROM_RELAXNGP, msg, args) + cvarargs.va_end(args) + +-cdef void _receiveRelaxNGValidationError(void* c_log_handler, char* msg, ...) nogil: ++cdef void _receiveRelaxNGValidationError(void* c_log_handler, char* msg, ...) noexcept nogil: + # no Python objects here, may be called without thread context ! + cdef cvarargs.va_list args + cvarargs.va_start(args, msg) +@@ -673,7 +673,7 @@ cdef void _receiveRelaxNGValidationError(void* c_log_handler, char* msg, ...) no + cvarargs.va_end(args) + + # dummy function: no log output at all +-cdef void _nullGenericErrorFunc(void* ctxt, char* msg, ...) nogil: ++cdef void _nullGenericErrorFunc(void* ctxt, char* msg, ...) noexcept nogil: + pass + + +@@ -694,7 +694,7 @@ cdef void _connectGenericErrorLog(log, int c_domain=-1): + + + cdef void _receiveGenericError(void* c_log_handler, int c_domain, +- char* msg, cvarargs.va_list args) nogil: ++ char* msg, cvarargs.va_list args) noexcept nogil: + # no Python objects here, may be called without thread context ! + cdef xmlerror.xmlError c_error + cdef char* c_text +diff --git a/src/lxml/xpath.pxi b/src/lxml/xpath.pxi +index a7cae4bff..704338e89 100644 +--- a/src/lxml/xpath.pxi ++++ b/src/lxml/xpath.pxi +@@ -99,7 +99,7 @@ cdef class _XPathContext(_BaseContext): + + + cdef void _registerExsltFunctionsForNamespaces( +- void* _c_href, void* _ctxt, const_xmlChar* c_prefix): ++ void* _c_href, void* _ctxt, const_xmlChar* c_prefix) noexcept: + c_href = _c_href + ctxt = _ctxt + diff --git a/ci.fmf b/ci.fmf new file mode 100644 index 0000000..c5aa0e0 --- /dev/null +++ b/ci.fmf @@ -0,0 +1 @@ +resultsdb-testcase: separate diff --git a/dcbc0cc1cb0cedf8019184aaca805d2a649cd8de.patch b/dcbc0cc1cb0cedf8019184aaca805d2a649cd8de.patch new file mode 100644 index 0000000..8de9737 --- /dev/null +++ b/dcbc0cc1cb0cedf8019184aaca805d2a649cd8de.patch @@ -0,0 +1,1088 @@ +From dcbc0cc1cb0cedf8019184aaca805d2a649cd8de Mon Sep 17 00:00:00 2001 +From: Stefan Behnel +Date: Thu, 15 Dec 2022 11:38:42 +0100 +Subject: [PATCH] Use generic 'nogil' block markers in pxd declarations where + possible, except for a few callback declarations that may be used for regular + GIL functions. + +--- + src/lxml/includes/c14n.pxd | 9 +- + src/lxml/includes/htmlparser.pxd | 26 ++-- + src/lxml/includes/relaxng.pxd | 22 +-- + src/lxml/includes/schematron.pxd | 16 +- + src/lxml/includes/tree.pxd | 260 +++++++++++++++---------------- + src/lxml/includes/uri.pxd | 2 +- + src/lxml/includes/xinclude.pxd | 20 +-- + src/lxml/includes/xmlerror.pxd | 12 +- + src/lxml/includes/xmlparser.pxd | 67 ++++---- + src/lxml/includes/xmlschema.pxd | 2 +- + src/lxml/includes/xpath.pxd | 73 ++++----- + src/lxml/includes/xslt.pxd | 85 +++++----- + 12 files changed, 297 insertions(+), 297 deletions(-) + +diff --git a/src/lxml/includes/c14n.pxd b/src/lxml/includes/c14n.pxd +index d075e90e2..8b1f3c4c5 100644 +--- a/src/lxml/includes/c14n.pxd ++++ b/src/lxml/includes/c14n.pxd +@@ -1,13 +1,13 @@ + from lxml.includes.tree cimport xmlDoc, xmlOutputBuffer, xmlChar + from lxml.includes.xpath cimport xmlNodeSet + +-cdef extern from "libxml/c14n.h": ++cdef extern from "libxml/c14n.h" nogil: + cdef int xmlC14NDocDumpMemory(xmlDoc* doc, + xmlNodeSet* nodes, + int exclusive, + xmlChar** inclusive_ns_prefixes, + int with_comments, +- xmlChar** doc_txt_ptr) nogil ++ xmlChar** doc_txt_ptr) + + cdef int xmlC14NDocSave(xmlDoc* doc, + xmlNodeSet* nodes, +@@ -15,12 +15,11 @@ cdef extern from "libxml/c14n.h": + xmlChar** inclusive_ns_prefixes, + int with_comments, + char* filename, +- int compression) nogil ++ int compression) + + cdef int xmlC14NDocSaveTo(xmlDoc* doc, + xmlNodeSet* nodes, + int exclusive, + xmlChar** inclusive_ns_prefixes, + int with_comments, +- xmlOutputBuffer* buffer) nogil +- ++ xmlOutputBuffer* buffer) +diff --git a/src/lxml/includes/htmlparser.pxd b/src/lxml/includes/htmlparser.pxd +index 145a69a06..31dcc406c 100644 +--- a/src/lxml/includes/htmlparser.pxd ++++ b/src/lxml/includes/htmlparser.pxd +@@ -4,7 +4,7 @@ from lxml.includes.tree cimport xmlDoc + from lxml.includes.tree cimport xmlInputReadCallback, xmlInputCloseCallback + from lxml.includes.xmlparser cimport xmlParserCtxt, xmlSAXHandler, xmlSAXHandlerV1 + +-cdef extern from "libxml/HTMLparser.h": ++cdef extern from "libxml/HTMLparser.h" nogil: + ctypedef enum htmlParserOption: + HTML_PARSE_NOERROR # suppress error reports + HTML_PARSE_NOWARNING # suppress warning reports +@@ -24,33 +24,33 @@ cdef extern from "libxml/HTMLparser.h": + xmlSAXHandlerV1 htmlDefaultSAXHandler + + cdef xmlParserCtxt* htmlCreateMemoryParserCtxt( +- char* buffer, int size) nogil ++ char* buffer, int size) + cdef xmlParserCtxt* htmlCreateFileParserCtxt( +- char* filename, char* encoding) nogil ++ char* filename, char* encoding) + cdef xmlParserCtxt* htmlCreatePushParserCtxt(xmlSAXHandler* sax, + void* user_data, + char* chunk, int size, +- char* filename, int enc) nogil +- cdef void htmlFreeParserCtxt(xmlParserCtxt* ctxt) nogil +- cdef void htmlCtxtReset(xmlParserCtxt* ctxt) nogil +- cdef int htmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) nogil +- cdef int htmlParseDocument(xmlParserCtxt* ctxt) nogil ++ char* filename, int enc) ++ cdef void htmlFreeParserCtxt(xmlParserCtxt* ctxt) ++ cdef void htmlCtxtReset(xmlParserCtxt* ctxt) ++ cdef int htmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) ++ cdef int htmlParseDocument(xmlParserCtxt* ctxt) + cdef int htmlParseChunk(xmlParserCtxt* ctxt, +- char* chunk, int size, int terminate) nogil ++ char* chunk, int size, int terminate) + + cdef xmlDoc* htmlCtxtReadFile(xmlParserCtxt* ctxt, + char* filename, const_char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* htmlCtxtReadDoc(xmlParserCtxt* ctxt, + char* buffer, char* URL, const_char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* htmlCtxtReadIO(xmlParserCtxt* ctxt, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void* ioctx, + char* URL, const_char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* htmlCtxtReadMemory(xmlParserCtxt* ctxt, + char* buffer, int size, + char* filename, const_char* encoding, +- int options) nogil ++ int options) +diff --git a/src/lxml/includes/relaxng.pxd b/src/lxml/includes/relaxng.pxd +index 28e9212d2..5ac96711e 100644 +--- a/src/lxml/includes/relaxng.pxd ++++ b/src/lxml/includes/relaxng.pxd +@@ -1,7 +1,7 @@ + from lxml.includes.tree cimport xmlDoc + from lxml.includes.xmlerror cimport xmlStructuredErrorFunc + +-cdef extern from "libxml/relaxng.h": ++cdef extern from "libxml/relaxng.h" nogil: + ctypedef struct xmlRelaxNG + ctypedef struct xmlRelaxNGParserCtxt + +@@ -49,16 +49,16 @@ cdef extern from "libxml/relaxng.h": + XML_RELAXNG_ERR_ELEMWRONG = 38 + XML_RELAXNG_ERR_TEXTWRONG = 39 + +- cdef xmlRelaxNGValidCtxt* xmlRelaxNGNewValidCtxt(xmlRelaxNG* schema) nogil +- cdef int xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxt* ctxt, xmlDoc* doc) nogil +- cdef xmlRelaxNG* xmlRelaxNGParse(xmlRelaxNGParserCtxt* ctxt) nogil +- cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewParserCtxt(char* URL) nogil +- cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewDocParserCtxt(xmlDoc* doc) nogil +- cdef void xmlRelaxNGFree(xmlRelaxNG* schema) nogil +- cdef void xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxt* ctxt) nogil +- cdef void xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxt* ctxt) nogil ++ cdef xmlRelaxNGValidCtxt* xmlRelaxNGNewValidCtxt(xmlRelaxNG* schema) ++ cdef int xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxt* ctxt, xmlDoc* doc) ++ cdef xmlRelaxNG* xmlRelaxNGParse(xmlRelaxNGParserCtxt* ctxt) ++ cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewParserCtxt(char* URL) ++ cdef xmlRelaxNGParserCtxt* xmlRelaxNGNewDocParserCtxt(xmlDoc* doc) ++ cdef void xmlRelaxNGFree(xmlRelaxNG* schema) ++ cdef void xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxt* ctxt) ++ cdef void xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxt* ctxt) + + cdef void xmlRelaxNGSetValidStructuredErrors( +- xmlRelaxNGValidCtxt* ctxt, xmlStructuredErrorFunc serror, void *ctx) nogil ++ xmlRelaxNGValidCtxt* ctxt, xmlStructuredErrorFunc serror, void *ctx) + cdef void xmlRelaxNGSetParserStructuredErrors( +- xmlRelaxNGParserCtxt* ctxt, xmlStructuredErrorFunc serror, void *ctx) nogil ++ xmlRelaxNGParserCtxt* ctxt, xmlStructuredErrorFunc serror, void *ctx) +diff --git a/src/lxml/includes/schematron.pxd b/src/lxml/includes/schematron.pxd +index f8e325284..181248afd 100644 +--- a/src/lxml/includes/schematron.pxd ++++ b/src/lxml/includes/schematron.pxd +@@ -1,7 +1,7 @@ + from lxml.includes cimport xmlerror + from lxml.includes.tree cimport xmlDoc + +-cdef extern from "libxml/schematron.h": ++cdef extern from "libxml/schematron.h" nogil: + ctypedef struct xmlSchematron + ctypedef struct xmlSchematronParserCtxt + ctypedef struct xmlSchematronValidCtxt +@@ -16,19 +16,19 @@ cdef extern from "libxml/schematron.h": + XML_SCHEMATRON_OUT_IO = 1024 # output to I/O mechanism + + cdef xmlSchematronParserCtxt* xmlSchematronNewDocParserCtxt( +- xmlDoc* doc) nogil ++ xmlDoc* doc) + cdef xmlSchematronParserCtxt* xmlSchematronNewParserCtxt( + char* filename) nogil + cdef xmlSchematronValidCtxt* xmlSchematronNewValidCtxt( +- xmlSchematron* schema, int options) nogil ++ xmlSchematron* schema, int options) + +- cdef xmlSchematron* xmlSchematronParse(xmlSchematronParserCtxt* ctxt) nogil ++ cdef xmlSchematron* xmlSchematronParse(xmlSchematronParserCtxt* ctxt) + cdef int xmlSchematronValidateDoc(xmlSchematronValidCtxt* ctxt, +- xmlDoc* instance) nogil ++ xmlDoc* instance) + +- cdef void xmlSchematronFreeParserCtxt(xmlSchematronParserCtxt* ctxt) nogil +- cdef void xmlSchematronFreeValidCtxt(xmlSchematronValidCtxt* ctxt) nogil +- cdef void xmlSchematronFree(xmlSchematron* schema) nogil ++ cdef void xmlSchematronFreeParserCtxt(xmlSchematronParserCtxt* ctxt) ++ cdef void xmlSchematronFreeValidCtxt(xmlSchematronValidCtxt* ctxt) ++ cdef void xmlSchematronFree(xmlSchematron* schema) + cdef void xmlSchematronSetValidStructuredErrors( + xmlSchematronValidCtxt* ctxt, + xmlerror.xmlStructuredErrorFunc error_func, void *data) +diff --git a/src/lxml/includes/tree.pxd b/src/lxml/includes/tree.pxd +index 010af8090..03d558a33 100644 +--- a/src/lxml/includes/tree.pxd ++++ b/src/lxml/includes/tree.pxd +@@ -9,19 +9,19 @@ cdef extern from "libxml/xmlversion.h": + cdef const_char* xmlParserVersion + cdef int LIBXML_VERSION + +-cdef extern from "libxml/xmlstring.h": ++cdef extern from "libxml/xmlstring.h" nogil: + ctypedef unsigned char xmlChar + ctypedef const xmlChar const_xmlChar "const xmlChar" +- cdef int xmlStrlen(const_xmlChar* str) nogil +- cdef xmlChar* xmlStrdup(const_xmlChar* cur) nogil +- cdef int xmlStrncmp(const_xmlChar* str1, const_xmlChar* str2, int length) nogil +- cdef int xmlStrcmp(const_xmlChar* str1, const_xmlChar* str2) nogil +- cdef int xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) nogil +- cdef const_xmlChar* xmlStrstr(const_xmlChar* str1, const_xmlChar* str2) nogil +- cdef const_xmlChar* xmlStrchr(const_xmlChar* str1, xmlChar ch) nogil ++ cdef int xmlStrlen(const_xmlChar* str) ++ cdef xmlChar* xmlStrdup(const_xmlChar* cur) ++ cdef int xmlStrncmp(const_xmlChar* str1, const_xmlChar* str2, int length) ++ cdef int xmlStrcmp(const_xmlChar* str1, const_xmlChar* str2) ++ cdef int xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) ++ cdef const_xmlChar* xmlStrstr(const_xmlChar* str1, const_xmlChar* str2) ++ cdef const_xmlChar* xmlStrchr(const_xmlChar* str1, xmlChar ch) + cdef const_xmlChar* _xcstr "(const xmlChar*)PyBytes_AS_STRING" (object s) + +-cdef extern from "libxml/encoding.h": ++cdef extern from "libxml/encoding.h" nogil: + ctypedef enum xmlCharEncoding: + XML_CHAR_ENCODING_ERROR = -1 # No char encoding detected + XML_CHAR_ENCODING_NONE = 0 # No char encoding detected +@@ -49,19 +49,19 @@ cdef extern from "libxml/encoding.h": + XML_CHAR_ENCODING_ASCII = 22 # pure ASCII + + ctypedef struct xmlCharEncodingHandler +- cdef xmlCharEncodingHandler* xmlFindCharEncodingHandler(char* name) nogil ++ cdef xmlCharEncodingHandler* xmlFindCharEncodingHandler(char* name) + cdef xmlCharEncodingHandler* xmlGetCharEncodingHandler( +- xmlCharEncoding enc) nogil +- cdef int xmlCharEncCloseFunc(xmlCharEncodingHandler* handler) nogil +- cdef xmlCharEncoding xmlDetectCharEncoding(const_xmlChar* text, int len) nogil +- cdef const_char* xmlGetCharEncodingName(xmlCharEncoding enc) nogil +- cdef xmlCharEncoding xmlParseCharEncoding(char* name) nogil ++ xmlCharEncoding enc) ++ cdef int xmlCharEncCloseFunc(xmlCharEncodingHandler* handler) ++ cdef xmlCharEncoding xmlDetectCharEncoding(const_xmlChar* text, int len) ++ cdef const_char* xmlGetCharEncodingName(xmlCharEncoding enc) ++ cdef xmlCharEncoding xmlParseCharEncoding(char* name) + ctypedef int (*xmlCharEncodingOutputFunc)( + unsigned char *out_buf, int *outlen, const_uchar *in_buf, int *inlen) + +-cdef extern from "libxml/chvalid.h": +- cdef int xmlIsChar_ch(char c) nogil +- cdef int xmlIsCharQ(int ch) nogil ++cdef extern from "libxml/chvalid.h" nogil: ++ cdef int xmlIsChar_ch(char c) ++ cdef int xmlIsCharQ(int ch) + + cdef extern from "libxml/hash.h": + ctypedef struct xmlHashTable +@@ -69,20 +69,20 @@ cdef extern from "libxml/hash.h": + void xmlHashScan(xmlHashTable* table, xmlHashScanner f, void* data) nogil + void* xmlHashLookup(xmlHashTable* table, const_xmlChar* name) nogil + ctypedef void (*xmlHashDeallocator)(void *payload, xmlChar *name) +- cdef xmlHashTable* xmlHashCreate(int size) +- cdef xmlHashTable* xmlHashCreateDict(int size, xmlDict *dict) +- cdef int xmlHashSize(xmlHashTable* table) +- cdef void xmlHashFree(xmlHashTable* table, xmlHashDeallocator f) ++ cdef xmlHashTable* xmlHashCreate(int size) nogil ++ cdef xmlHashTable* xmlHashCreateDict(int size, xmlDict *dict) nogil ++ cdef int xmlHashSize(xmlHashTable* table) nogil ++ cdef void xmlHashFree(xmlHashTable* table, xmlHashDeallocator f) nogil + +-cdef extern from *: # actually "libxml/dict.h" ++cdef extern from * nogil: # actually "libxml/dict.h" + # libxml/dict.h appears to be broken to include in C + ctypedef struct xmlDict +- cdef const_xmlChar* xmlDictLookup(xmlDict* dict, const_xmlChar* name, int len) nogil +- cdef const_xmlChar* xmlDictExists(xmlDict* dict, const_xmlChar* name, int len) nogil +- cdef int xmlDictOwns(xmlDict* dict, const_xmlChar* name) nogil +- cdef size_t xmlDictSize(xmlDict* dict) nogil ++ cdef const_xmlChar* xmlDictLookup(xmlDict* dict, const_xmlChar* name, int len) ++ cdef const_xmlChar* xmlDictExists(xmlDict* dict, const_xmlChar* name, int len) ++ cdef int xmlDictOwns(xmlDict* dict, const_xmlChar* name) ++ cdef size_t xmlDictSize(xmlDict* dict) + +-cdef extern from "libxml/tree.h": ++cdef extern from "libxml/tree.h" nogil: + ctypedef struct xmlDoc + ctypedef struct xmlAttr + ctypedef struct xmlNotationTable +@@ -305,100 +305,100 @@ cdef extern from "libxml/tree.h": + + const_xmlChar* XML_XML_NAMESPACE + +- cdef void xmlFreeDoc(xmlDoc* cur) nogil +- cdef void xmlFreeDtd(xmlDtd* cur) nogil +- cdef void xmlFreeNode(xmlNode* cur) nogil +- cdef void xmlFreeNsList(xmlNs* ns) nogil +- cdef void xmlFreeNs(xmlNs* ns) nogil +- cdef void xmlFree(void* buf) nogil ++ cdef void xmlFreeDoc(xmlDoc* cur) ++ cdef void xmlFreeDtd(xmlDtd* cur) ++ cdef void xmlFreeNode(xmlNode* cur) ++ cdef void xmlFreeNsList(xmlNs* ns) ++ cdef void xmlFreeNs(xmlNs* ns) ++ cdef void xmlFree(void* buf) + +- cdef xmlNode* xmlNewNode(xmlNs* ns, const_xmlChar* name) nogil +- cdef xmlNode* xmlNewDocText(xmlDoc* doc, const_xmlChar* content) nogil +- cdef xmlNode* xmlNewDocComment(xmlDoc* doc, const_xmlChar* content) nogil +- cdef xmlNode* xmlNewDocPI(xmlDoc* doc, const_xmlChar* name, const_xmlChar* content) nogil +- cdef xmlNode* xmlNewReference(xmlDoc* doc, const_xmlChar* name) nogil +- cdef xmlNode* xmlNewCDataBlock(xmlDoc* doc, const_xmlChar* text, int len) nogil +- cdef xmlNs* xmlNewNs(xmlNode* node, const_xmlChar* href, const_xmlChar* prefix) nogil +- cdef xmlNode* xmlAddChild(xmlNode* parent, xmlNode* cur) nogil +- cdef xmlNode* xmlReplaceNode(xmlNode* old, xmlNode* cur) nogil +- cdef xmlNode* xmlAddPrevSibling(xmlNode* cur, xmlNode* elem) nogil +- cdef xmlNode* xmlAddNextSibling(xmlNode* cur, xmlNode* elem) nogil ++ cdef xmlNode* xmlNewNode(xmlNs* ns, const_xmlChar* name) ++ cdef xmlNode* xmlNewDocText(xmlDoc* doc, const_xmlChar* content) ++ cdef xmlNode* xmlNewDocComment(xmlDoc* doc, const_xmlChar* content) ++ cdef xmlNode* xmlNewDocPI(xmlDoc* doc, const_xmlChar* name, const_xmlChar* content) ++ cdef xmlNode* xmlNewReference(xmlDoc* doc, const_xmlChar* name) ++ cdef xmlNode* xmlNewCDataBlock(xmlDoc* doc, const_xmlChar* text, int len) ++ cdef xmlNs* xmlNewNs(xmlNode* node, const_xmlChar* href, const_xmlChar* prefix) ++ cdef xmlNode* xmlAddChild(xmlNode* parent, xmlNode* cur) ++ cdef xmlNode* xmlReplaceNode(xmlNode* old, xmlNode* cur) ++ cdef xmlNode* xmlAddPrevSibling(xmlNode* cur, xmlNode* elem) ++ cdef xmlNode* xmlAddNextSibling(xmlNode* cur, xmlNode* elem) + cdef xmlNode* xmlNewDocNode(xmlDoc* doc, xmlNs* ns, +- const_xmlChar* name, const_xmlChar* content) nogil +- cdef xmlDoc* xmlNewDoc(const_xmlChar* version) nogil +- cdef xmlAttr* xmlNewProp(xmlNode* node, const_xmlChar* name, const_xmlChar* value) nogil ++ const_xmlChar* name, const_xmlChar* content) ++ cdef xmlDoc* xmlNewDoc(const_xmlChar* version) ++ cdef xmlAttr* xmlNewProp(xmlNode* node, const_xmlChar* name, const_xmlChar* value) + cdef xmlAttr* xmlNewNsProp(xmlNode* node, xmlNs* ns, +- const_xmlChar* name, const_xmlChar* value) nogil +- cdef xmlChar* xmlGetNoNsProp(xmlNode* node, const_xmlChar* name) nogil +- cdef xmlChar* xmlGetNsProp(xmlNode* node, const_xmlChar* name, const_xmlChar* nameSpace) nogil +- cdef void xmlSetNs(xmlNode* node, xmlNs* ns) nogil +- cdef xmlAttr* xmlSetProp(xmlNode* node, const_xmlChar* name, const_xmlChar* value) nogil ++ const_xmlChar* name, const_xmlChar* value) ++ cdef xmlChar* xmlGetNoNsProp(xmlNode* node, const_xmlChar* name) ++ cdef xmlChar* xmlGetNsProp(xmlNode* node, const_xmlChar* name, const_xmlChar* nameSpace) ++ cdef void xmlSetNs(xmlNode* node, xmlNs* ns) ++ cdef xmlAttr* xmlSetProp(xmlNode* node, const_xmlChar* name, const_xmlChar* value) + cdef xmlAttr* xmlSetNsProp(xmlNode* node, xmlNs* ns, +- const_xmlChar* name, const_xmlChar* value) nogil +- cdef int xmlRemoveID(xmlDoc* doc, xmlAttr* cur) nogil +- cdef int xmlRemoveProp(xmlAttr* cur) nogil +- cdef void xmlFreePropList(xmlAttr* cur) nogil +- cdef xmlChar* xmlGetNodePath(xmlNode* node) nogil +- cdef void xmlDocDumpMemory(xmlDoc* cur, char** mem, int* size) nogil ++ const_xmlChar* name, const_xmlChar* value) ++ cdef int xmlRemoveID(xmlDoc* doc, xmlAttr* cur) ++ cdef int xmlRemoveProp(xmlAttr* cur) ++ cdef void xmlFreePropList(xmlAttr* cur) ++ cdef xmlChar* xmlGetNodePath(xmlNode* node) ++ cdef void xmlDocDumpMemory(xmlDoc* cur, char** mem, int* size) + cdef void xmlDocDumpMemoryEnc(xmlDoc* cur, char** mem, int* size, +- char* encoding) nogil ++ char* encoding) + cdef int xmlSaveFileTo(xmlOutputBuffer* out, xmlDoc* cur, +- char* encoding) nogil +- +- cdef void xmlUnlinkNode(xmlNode* cur) nogil +- cdef xmlNode* xmlDocSetRootElement(xmlDoc* doc, xmlNode* root) nogil +- cdef xmlNode* xmlDocGetRootElement(xmlDoc* doc) nogil +- cdef void xmlSetTreeDoc(xmlNode* tree, xmlDoc* doc) nogil +- cdef xmlAttr* xmlHasProp(xmlNode* node, const_xmlChar* name) nogil +- cdef xmlAttr* xmlHasNsProp(xmlNode* node, const_xmlChar* name, const_xmlChar* nameSpace) nogil +- cdef xmlChar* xmlNodeGetContent(xmlNode* cur) nogil +- cdef int xmlNodeBufGetContent(xmlBuffer* buffer, xmlNode* cur) nogil +- cdef xmlNs* xmlSearchNs(xmlDoc* doc, xmlNode* node, const_xmlChar* prefix) nogil +- cdef xmlNs* xmlSearchNsByHref(xmlDoc* doc, xmlNode* node, const_xmlChar* href) nogil +- cdef int xmlIsBlankNode(xmlNode* node) nogil +- cdef long xmlGetLineNo(xmlNode* node) nogil +- cdef void xmlElemDump(stdio.FILE* f, xmlDoc* doc, xmlNode* cur) nogil ++ char* encoding) ++ ++ cdef void xmlUnlinkNode(xmlNode* cur) ++ cdef xmlNode* xmlDocSetRootElement(xmlDoc* doc, xmlNode* root) ++ cdef xmlNode* xmlDocGetRootElement(xmlDoc* doc) ++ cdef void xmlSetTreeDoc(xmlNode* tree, xmlDoc* doc) ++ cdef xmlAttr* xmlHasProp(xmlNode* node, const_xmlChar* name) ++ cdef xmlAttr* xmlHasNsProp(xmlNode* node, const_xmlChar* name, const_xmlChar* nameSpace) ++ cdef xmlChar* xmlNodeGetContent(xmlNode* cur) ++ cdef int xmlNodeBufGetContent(xmlBuffer* buffer, xmlNode* cur) ++ cdef xmlNs* xmlSearchNs(xmlDoc* doc, xmlNode* node, const_xmlChar* prefix) ++ cdef xmlNs* xmlSearchNsByHref(xmlDoc* doc, xmlNode* node, const_xmlChar* href) ++ cdef int xmlIsBlankNode(xmlNode* node) ++ cdef long xmlGetLineNo(xmlNode* node) ++ cdef void xmlElemDump(stdio.FILE* f, xmlDoc* doc, xmlNode* cur) + cdef void xmlNodeDumpOutput(xmlOutputBuffer* buf, + xmlDoc* doc, xmlNode* cur, int level, +- int format, const_char* encoding) nogil ++ int format, const_char* encoding) + cdef void xmlBufAttrSerializeTxtContent(xmlOutputBuffer *buf, xmlDoc *doc, +- xmlAttr *attr, const_xmlChar *string) nogil +- cdef void xmlNodeSetName(xmlNode* cur, const_xmlChar* name) nogil +- cdef void xmlNodeSetContent(xmlNode* cur, const_xmlChar* content) nogil +- cdef xmlDtd* xmlCopyDtd(xmlDtd* dtd) nogil +- cdef xmlDoc* xmlCopyDoc(xmlDoc* doc, int recursive) nogil +- cdef xmlNode* xmlCopyNode(xmlNode* node, int extended) nogil +- cdef xmlNode* xmlDocCopyNode(xmlNode* node, xmlDoc* doc, int extended) nogil +- cdef int xmlReconciliateNs(xmlDoc* doc, xmlNode* tree) nogil +- cdef xmlNs* xmlNewReconciliedNs(xmlDoc* doc, xmlNode* tree, xmlNs* ns) nogil +- cdef xmlBuffer* xmlBufferCreate() nogil +- cdef void xmlBufferWriteChar(xmlBuffer* buf, char* string) nogil +- cdef void xmlBufferFree(xmlBuffer* buf) nogil +- cdef const_xmlChar* xmlBufferContent(xmlBuffer* buf) nogil +- cdef int xmlBufferLength(xmlBuffer* buf) nogil +- cdef const_xmlChar* xmlBufContent(xmlBuf* buf) nogil # new in libxml2 2.9 +- cdef size_t xmlBufUse(xmlBuf* buf) nogil # new in libxml2 2.9 +- cdef int xmlKeepBlanksDefault(int val) nogil +- cdef xmlChar* xmlNodeGetBase(xmlDoc* doc, xmlNode* node) nogil ++ xmlAttr *attr, const_xmlChar *string) ++ cdef void xmlNodeSetName(xmlNode* cur, const_xmlChar* name) ++ cdef void xmlNodeSetContent(xmlNode* cur, const_xmlChar* content) ++ cdef xmlDtd* xmlCopyDtd(xmlDtd* dtd) ++ cdef xmlDoc* xmlCopyDoc(xmlDoc* doc, int recursive) ++ cdef xmlNode* xmlCopyNode(xmlNode* node, int extended) ++ cdef xmlNode* xmlDocCopyNode(xmlNode* node, xmlDoc* doc, int extended) ++ cdef int xmlReconciliateNs(xmlDoc* doc, xmlNode* tree) ++ cdef xmlNs* xmlNewReconciliedNs(xmlDoc* doc, xmlNode* tree, xmlNs* ns) ++ cdef xmlBuffer* xmlBufferCreate() ++ cdef void xmlBufferWriteChar(xmlBuffer* buf, char* string) ++ cdef void xmlBufferFree(xmlBuffer* buf) ++ cdef const_xmlChar* xmlBufferContent(xmlBuffer* buf) ++ cdef int xmlBufferLength(xmlBuffer* buf) ++ cdef const_xmlChar* xmlBufContent(xmlBuf* buf) # new in libxml2 2.9 ++ cdef size_t xmlBufUse(xmlBuf* buf) # new in libxml2 2.9 ++ cdef int xmlKeepBlanksDefault(int val) ++ cdef xmlChar* xmlNodeGetBase(xmlDoc* doc, xmlNode* node) + cdef xmlDtd* xmlCreateIntSubset(xmlDoc* doc, const_xmlChar* name, +- const_xmlChar* ExternalID, const_xmlChar* SystemID) nogil +- cdef void xmlNodeSetBase(xmlNode* node, const_xmlChar* uri) nogil +- cdef int xmlValidateNCName(const_xmlChar* value, int space) nogil ++ const_xmlChar* ExternalID, const_xmlChar* SystemID) ++ cdef void xmlNodeSetBase(xmlNode* node, const_xmlChar* uri) ++ cdef int xmlValidateNCName(const_xmlChar* value, int space) + +-cdef extern from "libxml/uri.h": +- cdef const_xmlChar* xmlBuildURI(const_xmlChar* href, const_xmlChar* base) nogil ++cdef extern from "libxml/uri.h" nogil: ++ cdef const_xmlChar* xmlBuildURI(const_xmlChar* href, const_xmlChar* base) + +-cdef extern from "libxml/HTMLtree.h": ++cdef extern from "libxml/HTMLtree.h" nogil: + cdef void htmlNodeDumpFormatOutput(xmlOutputBuffer* buf, + xmlDoc* doc, xmlNode* cur, +- char* encoding, int format) nogil +- cdef xmlDoc* htmlNewDoc(const_xmlChar* uri, const_xmlChar* externalID) nogil ++ char* encoding, int format) ++ cdef xmlDoc* htmlNewDoc(const_xmlChar* uri, const_xmlChar* externalID) + +-cdef extern from "libxml/valid.h": +- cdef xmlAttr* xmlGetID(xmlDoc* doc, const_xmlChar* ID) nogil ++cdef extern from "libxml/valid.h" nogil: ++ cdef xmlAttr* xmlGetID(xmlDoc* doc, const_xmlChar* ID) + cdef void xmlDumpNotationTable(xmlBuffer* buffer, +- xmlNotationTable* table) nogil +- cdef int xmlValidateNameValue(const_xmlChar* value) nogil ++ xmlNotationTable* table) ++ cdef int xmlValidateNameValue(const_xmlChar* value) + + cdef extern from "libxml/xmlIO.h": + cdef int xmlOutputBufferWrite(xmlOutputBuffer* out, +@@ -411,8 +411,8 @@ cdef extern from "libxml/xmlIO.h": + cdef int xmlOutputBufferClose(xmlOutputBuffer* out) nogil + + ctypedef int (*xmlInputReadCallback)(void* context, +- char* buffer, int len) +- ctypedef int (*xmlInputCloseCallback)(void* context) ++ char* buffer, int len) nogil ++ ctypedef int (*xmlInputCloseCallback)(void* context) nogil + + ctypedef int (*xmlOutputWriteCallback)(void* context, + char* buffer, int len) +@@ -430,7 +430,7 @@ cdef extern from "libxml/xmlIO.h": + cdef xmlOutputBuffer* xmlOutputBufferCreateFilename( + char* URI, xmlCharEncodingHandler* encoder, int compression) nogil + +-cdef extern from "libxml/xmlsave.h": ++cdef extern from "libxml/xmlsave.h" nogil: + ctypedef struct xmlSaveCtxt + + ctypedef enum xmlSaveOption: +@@ -443,20 +443,20 @@ cdef extern from "libxml/xmlsave.h": + XML_SAVE_AS_HTML = 64 # force HTML serialization on XML doc (2.7.2) + + cdef xmlSaveCtxt* xmlSaveToFilename(char* filename, char* encoding, +- int options) nogil ++ int options) + cdef xmlSaveCtxt* xmlSaveToBuffer(xmlBuffer* buffer, char* encoding, +- int options) nogil # libxml2 2.6.23 +- cdef long xmlSaveDoc(xmlSaveCtxt* ctxt, xmlDoc* doc) nogil +- cdef long xmlSaveTree(xmlSaveCtxt* ctxt, xmlNode* node) nogil +- cdef int xmlSaveClose(xmlSaveCtxt* ctxt) nogil +- cdef int xmlSaveFlush(xmlSaveCtxt* ctxt) nogil +- cdef int xmlSaveSetAttrEscape(xmlSaveCtxt* ctxt, void* escape_func) nogil +- cdef int xmlSaveSetEscape(xmlSaveCtxt* ctxt, void* escape_func) nogil +- +-cdef extern from "libxml/globals.h": +- cdef int xmlThrDefKeepBlanksDefaultValue(int onoff) nogil +- cdef int xmlThrDefLineNumbersDefaultValue(int onoff) nogil +- cdef int xmlThrDefIndentTreeOutput(int onoff) nogil ++ int options) # libxml2 2.6.23 ++ cdef long xmlSaveDoc(xmlSaveCtxt* ctxt, xmlDoc* doc) ++ cdef long xmlSaveTree(xmlSaveCtxt* ctxt, xmlNode* node) ++ cdef int xmlSaveClose(xmlSaveCtxt* ctxt) ++ cdef int xmlSaveFlush(xmlSaveCtxt* ctxt) ++ cdef int xmlSaveSetAttrEscape(xmlSaveCtxt* ctxt, void* escape_func) ++ cdef int xmlSaveSetEscape(xmlSaveCtxt* ctxt, void* escape_func) ++ ++cdef extern from "libxml/globals.h" nogil: ++ cdef int xmlThrDefKeepBlanksDefaultValue(int onoff) ++ cdef int xmlThrDefLineNumbersDefaultValue(int onoff) ++ cdef int xmlThrDefIndentTreeOutput(int onoff) + + cdef extern from "libxml/xmlmemory.h" nogil: + cdef void* xmlMalloc(size_t size) +@@ -466,15 +466,15 @@ cdef extern from "libxml/xmlmemory.h" nogil: + cdef void xmlMemDisplayLast(stdio.FILE* file, long num_bytes) + cdef void xmlMemShow(stdio.FILE* file, int count) + +-cdef extern from "etree_defs.h": +- cdef bint _isElement(xmlNode* node) nogil +- cdef bint _isElementOrXInclude(xmlNode* node) nogil +- cdef const_xmlChar* _getNs(xmlNode* node) nogil ++cdef extern from "etree_defs.h" nogil: ++ cdef bint _isElement(xmlNode* node) ++ cdef bint _isElementOrXInclude(xmlNode* node) ++ cdef const_xmlChar* _getNs(xmlNode* node) + cdef void BEGIN_FOR_EACH_ELEMENT_FROM(xmlNode* tree_top, + xmlNode* start_node, +- bint inclusive) nogil +- cdef void END_FOR_EACH_ELEMENT_FROM(xmlNode* start_node) nogil ++ bint inclusive) ++ cdef void END_FOR_EACH_ELEMENT_FROM(xmlNode* start_node) + cdef void BEGIN_FOR_EACH_FROM(xmlNode* tree_top, + xmlNode* start_node, +- bint inclusive) nogil +- cdef void END_FOR_EACH_FROM(xmlNode* start_node) nogil ++ bint inclusive) ++ cdef void END_FOR_EACH_FROM(xmlNode* start_node) +diff --git a/src/lxml/includes/uri.pxd b/src/lxml/includes/uri.pxd +index 2b6bb79f3..f886a54b9 100644 +--- a/src/lxml/includes/uri.pxd ++++ b/src/lxml/includes/uri.pxd +@@ -1,4 +1,4 @@ +-cdef extern from "libxml/uri.h": ++cdef extern from "libxml/uri.h" nogil: + ctypedef struct xmlURI + + cdef xmlURI* xmlParseURI(char* str) +diff --git a/src/lxml/includes/xinclude.pxd b/src/lxml/includes/xinclude.pxd +index 4232d3e43..68267175a 100644 +--- a/src/lxml/includes/xinclude.pxd ++++ b/src/lxml/includes/xinclude.pxd +@@ -1,22 +1,22 @@ + from lxml.includes.tree cimport xmlDoc, xmlNode + +-cdef extern from "libxml/xinclude.h": ++cdef extern from "libxml/xinclude.h" nogil: + + ctypedef struct xmlXIncludeCtxt + +- cdef int xmlXIncludeProcess(xmlDoc* doc) nogil +- cdef int xmlXIncludeProcessFlags(xmlDoc* doc, int parser_opts) nogil +- cdef int xmlXIncludeProcessTree(xmlNode* doc) nogil +- cdef int xmlXIncludeProcessTreeFlags(xmlNode* doc, int parser_opts) nogil ++ cdef int xmlXIncludeProcess(xmlDoc* doc) ++ cdef int xmlXIncludeProcessFlags(xmlDoc* doc, int parser_opts) ++ cdef int xmlXIncludeProcessTree(xmlNode* doc) ++ cdef int xmlXIncludeProcessTreeFlags(xmlNode* doc, int parser_opts) + + # libxml2 >= 2.7.4 + cdef int xmlXIncludeProcessTreeFlagsData( +- xmlNode* doc, int parser_opts, void* data) nogil ++ xmlNode* doc, int parser_opts, void* data) + +- cdef xmlXIncludeCtxt* xmlXIncludeNewContext(xmlDoc* doc) nogil +- cdef int xmlXIncludeProcessNode(xmlXIncludeCtxt* ctxt, xmlNode* node) nogil +- cdef int xmlXIncludeSetFlags(xmlXIncludeCtxt* ctxt, int flags) nogil ++ cdef xmlXIncludeCtxt* xmlXIncludeNewContext(xmlDoc* doc) ++ cdef int xmlXIncludeProcessNode(xmlXIncludeCtxt* ctxt, xmlNode* node) ++ cdef int xmlXIncludeSetFlags(xmlXIncludeCtxt* ctxt, int flags) + + # libxml2 >= 2.6.27 + cdef int xmlXIncludeProcessFlagsData( +- xmlDoc* doc, int flags, void* data) nogil ++ xmlDoc* doc, int flags, void* data) +diff --git a/src/lxml/includes/xmlerror.pxd b/src/lxml/includes/xmlerror.pxd +index 13c8f3782..c5ac6a0aa 100644 +--- a/src/lxml/includes/xmlerror.pxd ++++ b/src/lxml/includes/xmlerror.pxd +@@ -823,7 +823,7 @@ cdef extern from "libxml/xmlerror.h": + XML_RELAXNG_ERR_TEXTWRONG = 39 + # --- END: GENERATED CONSTANTS --- + +-cdef extern from "libxml/xmlerror.h": ++cdef extern from "libxml/xmlerror.h" nogil: + ctypedef struct xmlError: + int domain + int code +@@ -838,15 +838,15 @@ cdef extern from "libxml/xmlerror.h": + int int2 + void* node + +- ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...) nogil ++ ctypedef void (*xmlGenericErrorFunc)(void* ctxt, char* msg, ...) + ctypedef void (*xmlStructuredErrorFunc)(void* userData, +- xmlError* error) nogil ++ xmlError* error) + + cdef void xmlSetGenericErrorFunc( +- void* ctxt, xmlGenericErrorFunc func) nogil ++ void* ctxt, xmlGenericErrorFunc func) + cdef void xmlSetStructuredErrorFunc( +- void* ctxt, xmlStructuredErrorFunc func) nogil ++ void* ctxt, xmlStructuredErrorFunc func) + +-cdef extern from "libxml/globals.h": ++cdef extern from "libxml/globals.h" nogil: + cdef xmlStructuredErrorFunc xmlStructuredError + cdef void* xmlStructuredErrorContext +diff --git a/src/lxml/includes/xmlparser.pxd b/src/lxml/includes/xmlparser.pxd +index 45acfc846..9f3056248 100644 +--- a/src/lxml/includes/xmlparser.pxd ++++ b/src/lxml/includes/xmlparser.pxd +@@ -6,7 +6,7 @@ from lxml.includes.tree cimport xmlInputReadCallback, xmlInputCloseCallback + from lxml.includes.xmlerror cimport xmlError, xmlStructuredErrorFunc + + +-cdef extern from "libxml/parser.h": ++cdef extern from "libxml/parser.h" nogil: + ctypedef void (*startElementNsSAX2Func)(void* ctx, + const_xmlChar* localname, + const_xmlChar* prefix, +@@ -49,7 +49,7 @@ cdef extern from "libxml/parser.h": + + cdef int XML_SAX2_MAGIC + +-cdef extern from "libxml/tree.h": ++cdef extern from "libxml/tree.h" nogil: + ctypedef struct xmlParserInput: + int line + int length +@@ -93,12 +93,12 @@ cdef extern from "libxml/xmlIO.h" nogil: + cdef xmlParserInputBuffer* xmlAllocParserInputBuffer(int enc) + + +-cdef extern from "libxml/parser.h": ++cdef extern from "libxml/parser.h" nogil: + +- cdef xmlDict* xmlDictCreate() nogil +- cdef xmlDict* xmlDictCreateSub(xmlDict* subdict) nogil +- cdef void xmlDictFree(xmlDict* sub) nogil +- cdef int xmlDictReference(xmlDict* dict) nogil ++ cdef xmlDict* xmlDictCreate() ++ cdef xmlDict* xmlDictCreateSub(xmlDict* subdict) ++ cdef void xmlDictFree(xmlDict* sub) ++ cdef int xmlDictReference(xmlDict* dict) + + cdef int XML_COMPLETE_ATTRS # SAX option for adding DTD default attributes + cdef int XML_SKIP_IDS # SAX option for not building an XML ID dict +@@ -181,36 +181,36 @@ cdef extern from "libxml/parser.h": + # libxml2 2.9.0+ only: + XML_PARSE_BIG_LINES = 4194304 # Store big lines numbers in text PSVI field + +- cdef void xmlInitParser() nogil +- cdef void xmlCleanupParser() nogil ++ cdef void xmlInitParser() ++ cdef void xmlCleanupParser() + +- cdef int xmlLineNumbersDefault(int onoff) nogil +- cdef xmlParserCtxt* xmlNewParserCtxt() nogil ++ cdef int xmlLineNumbersDefault(int onoff) ++ cdef xmlParserCtxt* xmlNewParserCtxt() + cdef xmlParserInput* xmlNewIOInputStream(xmlParserCtxt* ctxt, + xmlParserInputBuffer* input, +- int enc) nogil +- cdef int xmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) nogil +- cdef void xmlFreeParserCtxt(xmlParserCtxt* ctxt) nogil +- cdef void xmlCtxtReset(xmlParserCtxt* ctxt) nogil +- cdef void xmlClearParserCtxt(xmlParserCtxt* ctxt) nogil ++ int enc) ++ cdef int xmlCtxtUseOptions(xmlParserCtxt* ctxt, int options) ++ cdef void xmlFreeParserCtxt(xmlParserCtxt* ctxt) ++ cdef void xmlCtxtReset(xmlParserCtxt* ctxt) ++ cdef void xmlClearParserCtxt(xmlParserCtxt* ctxt) + cdef int xmlParseChunk(xmlParserCtxt* ctxt, +- char* chunk, int size, int terminate) nogil ++ char* chunk, int size, int terminate) + cdef xmlDoc* xmlCtxtReadDoc(xmlParserCtxt* ctxt, + char* cur, char* URL, char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* xmlCtxtReadFile(xmlParserCtxt* ctxt, + char* filename, char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* xmlCtxtReadIO(xmlParserCtxt* ctxt, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void* ioctx, + char* URL, char* encoding, +- int options) nogil ++ int options) + cdef xmlDoc* xmlCtxtReadMemory(xmlParserCtxt* ctxt, + char* buffer, int size, + char* filename, const_char* encoding, +- int options) nogil ++ int options) + + # iterparse: + +@@ -218,33 +218,34 @@ cdef extern from "libxml/parser.h": + void* user_data, + char* chunk, + int size, +- char* filename) nogil ++ char* filename) + + cdef int xmlCtxtResetPush(xmlParserCtxt* ctxt, + char* chunk, + int size, + char* filename, +- char* encoding) nogil ++ char* encoding) + + # entity loaders: + + ctypedef xmlParserInput* (*xmlExternalEntityLoader)( +- const_char * URL, const_char * ID, xmlParserCtxt* context) nogil +- cdef xmlExternalEntityLoader xmlGetExternalEntityLoader() nogil +- cdef void xmlSetExternalEntityLoader(xmlExternalEntityLoader f) nogil ++ const_char * URL, const_char * ID, xmlParserCtxt* context) ++ cdef xmlExternalEntityLoader xmlGetExternalEntityLoader() ++ cdef void xmlSetExternalEntityLoader(xmlExternalEntityLoader f) + + # DTDs: + +- cdef xmlDtd* xmlParseDTD(const_xmlChar* ExternalID, const_xmlChar* SystemID) nogil ++ cdef xmlDtd* xmlParseDTD(const_xmlChar* ExternalID, const_xmlChar* SystemID) + cdef xmlDtd* xmlIOParseDTD(xmlSAXHandler* sax, + xmlParserInputBuffer* input, +- int enc) nogil ++ int enc) + +-cdef extern from "libxml/parserInternals.h": ++ ++cdef extern from "libxml/parserInternals.h" nogil: + cdef xmlParserInput* xmlNewInputStream(xmlParserCtxt* ctxt) + cdef xmlParserInput* xmlNewStringInputStream(xmlParserCtxt* ctxt, +- char* buffer) nogil ++ char* buffer) + cdef xmlParserInput* xmlNewInputFromFile(xmlParserCtxt* ctxt, +- char* filename) nogil +- cdef void xmlFreeInputStream(xmlParserInput* input) nogil +- cdef int xmlSwitchEncoding(xmlParserCtxt* ctxt, int enc) nogil ++ char* filename) ++ cdef void xmlFreeInputStream(xmlParserInput* input) ++ cdef int xmlSwitchEncoding(xmlParserCtxt* ctxt, int enc) +diff --git a/src/lxml/includes/xmlschema.pxd b/src/lxml/includes/xmlschema.pxd +index 8e93cc570..067411113 100644 +--- a/src/lxml/includes/xmlschema.pxd ++++ b/src/lxml/includes/xmlschema.pxd +@@ -2,7 +2,7 @@ from lxml.includes.tree cimport xmlDoc + from lxml.includes.xmlparser cimport xmlSAXHandler + from lxml.includes.xmlerror cimport xmlStructuredErrorFunc + +-cdef extern from "libxml/xmlschemas.h": ++cdef extern from "libxml/xmlschemas.h" nogil: + ctypedef struct xmlSchema + ctypedef struct xmlSchemaParserCtxt + +diff --git a/src/lxml/includes/xpath.pxd b/src/lxml/includes/xpath.pxd +index d01735b68..22069eb7c 100644 +--- a/src/lxml/includes/xpath.pxd ++++ b/src/lxml/includes/xpath.pxd +@@ -4,7 +4,8 @@ from lxml.includes cimport xmlerror + from libc.string cimport const_char + from lxml.includes.tree cimport xmlChar, const_xmlChar + +-cdef extern from "libxml/xpath.h": ++ ++cdef extern from "libxml/xpath.h" nogil: + ctypedef enum xmlXPathObjectType: + XPATH_UNDEFINED = 0 + XPATH_NODESET = 1 +@@ -73,63 +74,63 @@ cdef extern from "libxml/xpath.h": + + ctypedef struct xmlXPathCompExpr + +- ctypedef void (*xmlXPathFunction)(xmlXPathParserContext* ctxt, int nargs) nogil ++ ctypedef void (*xmlXPathFunction)(xmlXPathParserContext* ctxt, int nargs) + ctypedef xmlXPathFunction (*xmlXPathFuncLookupFunc)(void* ctxt, + const_xmlChar* name, +- const_xmlChar* ns_uri) nogil ++ const_xmlChar* ns_uri) + +- cdef xmlXPathContext* xmlXPathNewContext(tree.xmlDoc* doc) nogil ++ cdef xmlXPathContext* xmlXPathNewContext(tree.xmlDoc* doc) + cdef xmlXPathObject* xmlXPathEvalExpression(const_xmlChar* str, +- xmlXPathContext* ctxt) nogil ++ xmlXPathContext* ctxt) + cdef xmlXPathObject* xmlXPathCompiledEval(xmlXPathCompExpr* comp, +- xmlXPathContext* ctxt) nogil +- cdef xmlXPathCompExpr* xmlXPathCompile(const_xmlChar* str) nogil ++ xmlXPathContext* ctxt) ++ cdef xmlXPathCompExpr* xmlXPathCompile(const_xmlChar* str) + cdef xmlXPathCompExpr* xmlXPathCtxtCompile(xmlXPathContext* ctxt, +- const_xmlChar* str) nogil +- cdef void xmlXPathFreeContext(xmlXPathContext* ctxt) nogil +- cdef void xmlXPathFreeCompExpr(xmlXPathCompExpr* comp) nogil +- cdef void xmlXPathFreeObject(xmlXPathObject* obj) nogil ++ const_xmlChar* str) ++ cdef void xmlXPathFreeContext(xmlXPathContext* ctxt) ++ cdef void xmlXPathFreeCompExpr(xmlXPathCompExpr* comp) ++ cdef void xmlXPathFreeObject(xmlXPathObject* obj) + cdef int xmlXPathRegisterNs(xmlXPathContext* ctxt, +- const_xmlChar* prefix, const_xmlChar* ns_uri) nogil ++ const_xmlChar* prefix, const_xmlChar* ns_uri) + +- cdef xmlNodeSet* xmlXPathNodeSetCreate(tree.xmlNode* val) nogil +- cdef void xmlXPathFreeNodeSet(xmlNodeSet* val) nogil ++ cdef xmlNodeSet* xmlXPathNodeSetCreate(tree.xmlNode* val) ++ cdef void xmlXPathFreeNodeSet(xmlNodeSet* val) + + +-cdef extern from "libxml/xpathInternals.h": ++cdef extern from "libxml/xpathInternals.h" nogil: + cdef int xmlXPathRegisterFunc(xmlXPathContext* ctxt, + const_xmlChar* name, +- xmlXPathFunction f) nogil ++ xmlXPathFunction f) + cdef int xmlXPathRegisterFuncNS(xmlXPathContext* ctxt, + const_xmlChar* name, + const_xmlChar* ns_uri, +- xmlXPathFunction f) nogil ++ xmlXPathFunction f) + cdef void xmlXPathRegisterFuncLookup(xmlXPathContext *ctxt, + xmlXPathFuncLookupFunc f, +- void *funcCtxt) nogil ++ void *funcCtxt) + cdef int xmlXPathRegisterVariable(xmlXPathContext *ctxt, + const_xmlChar* name, +- xmlXPathObject* value) nogil ++ xmlXPathObject* value) + cdef int xmlXPathRegisterVariableNS(xmlXPathContext *ctxt, + const_xmlChar* name, + const_xmlChar* ns_uri, +- xmlXPathObject* value) nogil +- cdef void xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt) nogil +- cdef void xmlXPathRegisteredNsCleanup(xmlXPathContext *ctxt) nogil +- cdef xmlXPathObject* valuePop (xmlXPathParserContext *ctxt) nogil +- cdef int valuePush(xmlXPathParserContext* ctxt, xmlXPathObject *value) nogil ++ xmlXPathObject* value) ++ cdef void xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt) ++ cdef void xmlXPathRegisteredNsCleanup(xmlXPathContext *ctxt) ++ cdef xmlXPathObject* valuePop (xmlXPathParserContext *ctxt) ++ cdef int valuePush(xmlXPathParserContext* ctxt, xmlXPathObject *value) + +- cdef xmlXPathObject* xmlXPathNewCString(const_char *val) nogil +- cdef xmlXPathObject* xmlXPathWrapCString(const_char * val) nogil +- cdef xmlXPathObject* xmlXPathNewString(const_xmlChar *val) nogil +- cdef xmlXPathObject* xmlXPathWrapString(const_xmlChar * val) nogil +- cdef xmlXPathObject* xmlXPathNewFloat(double val) nogil +- cdef xmlXPathObject* xmlXPathNewBoolean(int val) nogil +- cdef xmlXPathObject* xmlXPathNewNodeSet(tree.xmlNode* val) nogil +- cdef xmlXPathObject* xmlXPathNewValueTree(tree.xmlNode* val) nogil ++ cdef xmlXPathObject* xmlXPathNewCString(const_char *val) ++ cdef xmlXPathObject* xmlXPathWrapCString(const_char * val) ++ cdef xmlXPathObject* xmlXPathNewString(const_xmlChar *val) ++ cdef xmlXPathObject* xmlXPathWrapString(const_xmlChar * val) ++ cdef xmlXPathObject* xmlXPathNewFloat(double val) ++ cdef xmlXPathObject* xmlXPathNewBoolean(int val) ++ cdef xmlXPathObject* xmlXPathNewNodeSet(tree.xmlNode* val) ++ cdef xmlXPathObject* xmlXPathNewValueTree(tree.xmlNode* val) + cdef void xmlXPathNodeSetAdd(xmlNodeSet* cur, +- tree.xmlNode* val) nogil ++ tree.xmlNode* val) + cdef void xmlXPathNodeSetAddUnique(xmlNodeSet* cur, +- tree.xmlNode* val) nogil +- cdef xmlXPathObject* xmlXPathWrapNodeSet(xmlNodeSet* val) nogil +- cdef void xmlXPathErr(xmlXPathParserContext* ctxt, int error) nogil ++ tree.xmlNode* val) ++ cdef xmlXPathObject* xmlXPathWrapNodeSet(xmlNodeSet* val) ++ cdef void xmlXPathErr(xmlXPathParserContext* ctxt, int error) +diff --git a/src/lxml/includes/xslt.pxd b/src/lxml/includes/xslt.pxd +index 101fb7e78..05d2d4b9b 100644 +--- a/src/lxml/includes/xslt.pxd ++++ b/src/lxml/includes/xslt.pxd +@@ -11,7 +11,7 @@ cdef extern from "libxslt/xslt.h": + cdef extern from "libxslt/xsltconfig.h": + cdef int LIBXSLT_VERSION + +-cdef extern from "libxslt/xsltInternals.h": ++cdef extern from "libxslt/xsltInternals.h" nogil: + ctypedef enum xsltTransformState: + XSLT_STATE_OK # 0 + XSLT_STATE_ERROR # 1 +@@ -42,35 +42,35 @@ cdef extern from "libxslt/xsltInternals.h": + + ctypedef struct xsltTemplate + +- cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc) nogil +- cdef void xsltFreeStylesheet(xsltStylesheet* sheet) nogil ++ cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc) ++ cdef void xsltFreeStylesheet(xsltStylesheet* sheet) + +-cdef extern from "libxslt/imports.h": ++cdef extern from "libxslt/imports.h" nogil: + # actually defined in "etree_defs.h" + cdef void LXML_GET_XSLT_ENCODING(const_xmlChar* result_var, xsltStylesheet* style) + +-cdef extern from "libxslt/extensions.h": ++cdef extern from "libxslt/extensions.h" nogil: + ctypedef void (*xsltTransformFunction)(xsltTransformContext* ctxt, + xmlNode* context_node, + xmlNode* inst, +- void* precomp_unused) nogil ++ void* precomp_unused) + + cdef int xsltRegisterExtFunction(xsltTransformContext* ctxt, + const_xmlChar* name, + const_xmlChar* URI, +- xmlXPathFunction function) nogil ++ xmlXPathFunction function) + cdef int xsltRegisterExtModuleFunction(const_xmlChar* name, const_xmlChar* URI, +- xmlXPathFunction function) nogil ++ xmlXPathFunction function) + cdef int xsltUnregisterExtModuleFunction(const_xmlChar* name, const_xmlChar* URI) + cdef xmlXPathFunction xsltExtModuleFunctionLookup( +- const_xmlChar* name, const_xmlChar* URI) nogil ++ const_xmlChar* name, const_xmlChar* URI) + cdef int xsltRegisterExtPrefix(xsltStylesheet* style, +- const_xmlChar* prefix, const_xmlChar* URI) nogil ++ const_xmlChar* prefix, const_xmlChar* URI) + cdef int xsltRegisterExtElement(xsltTransformContext* ctxt, + const_xmlChar* name, const_xmlChar* URI, +- xsltTransformFunction function) nogil ++ xsltTransformFunction function) + +-cdef extern from "libxslt/documents.h": ++cdef extern from "libxslt/documents.h" nogil: + ctypedef enum xsltLoadType: + XSLT_LOAD_START + XSLT_LOAD_STYLESHEET +@@ -79,48 +79,48 @@ cdef extern from "libxslt/documents.h": + ctypedef xmlDoc* (*xsltDocLoaderFunc)(const_xmlChar* URI, xmlDict* dict, + int options, + void* ctxt, +- xsltLoadType type) nogil ++ xsltLoadType type) + cdef xsltDocLoaderFunc xsltDocDefaultLoader +- cdef void xsltSetLoaderFunc(xsltDocLoaderFunc f) nogil ++ cdef void xsltSetLoaderFunc(xsltDocLoaderFunc f) + +-cdef extern from "libxslt/transform.h": ++cdef extern from "libxslt/transform.h" nogil: + cdef xmlDoc* xsltApplyStylesheet(xsltStylesheet* style, xmlDoc* doc, +- const_char** params) nogil ++ const_char** params) + cdef xmlDoc* xsltApplyStylesheetUser(xsltStylesheet* style, xmlDoc* doc, + const_char** params, const_char* output, + void* profile, +- xsltTransformContext* context) nogil ++ xsltTransformContext* context) + cdef void xsltProcessOneNode(xsltTransformContext* ctxt, + xmlNode* contextNode, +- xsltStackElem* params) nogil ++ xsltStackElem* params) + cdef xsltTransformContext* xsltNewTransformContext(xsltStylesheet* style, +- xmlDoc* doc) nogil +- cdef void xsltFreeTransformContext(xsltTransformContext* context) nogil ++ xmlDoc* doc) ++ cdef void xsltFreeTransformContext(xsltTransformContext* context) + cdef void xsltApplyOneTemplate(xsltTransformContext* ctxt, + xmlNode* contextNode, xmlNode* list, + xsltTemplate* templ, +- xsltStackElem* params) nogil ++ xsltStackElem* params) + + +-cdef extern from "libxslt/xsltutils.h": ++cdef extern from "libxslt/xsltutils.h" nogil: + cdef int xsltSaveResultToString(xmlChar** doc_txt_ptr, + int* doc_txt_len, + xmlDoc* result, +- xsltStylesheet* style) nogil ++ xsltStylesheet* style) + cdef int xsltSaveResultToFilename(const_char *URL, + xmlDoc* result, + xsltStylesheet* style, +- int compression) nogil ++ int compression) + cdef int xsltSaveResultTo(xmlOutputBuffer* buf, + xmlDoc* result, +- xsltStylesheet* style) nogil ++ xsltStylesheet* style) + cdef xmlGenericErrorFunc xsltGenericError + cdef void *xsltGenericErrorContext + cdef void xsltSetGenericErrorFunc( +- void* ctxt, void (*handler)(void* ctxt, char* msg, ...)) nogil ++ void* ctxt, void (*handler)(void* ctxt, char* msg, ...) nogil) + cdef void xsltSetTransformErrorFunc( + xsltTransformContext*, void* ctxt, +- void (*handler)(void* ctxt, char* msg, ...) nogil) nogil ++ void (*handler)(void* ctxt, char* msg, ...) nogil) + cdef void xsltTransformError(xsltTransformContext* ctxt, + xsltStylesheet* style, + xmlNode* node, char* msg, ...) +@@ -128,7 +128,7 @@ cdef extern from "libxslt/xsltutils.h": + xsltTransformContext* ctxt, int options) + + +-cdef extern from "libxslt/security.h": ++cdef extern from "libxslt/security.h" nogil: + ctypedef struct xsltSecurityPrefs + ctypedef enum xsltSecurityOption: + XSLT_SECPREF_READ_FILE = 1 +@@ -139,44 +139,44 @@ cdef extern from "libxslt/security.h": + + ctypedef int (*xsltSecurityCheck)(xsltSecurityPrefs* sec, + xsltTransformContext* ctxt, +- char* value) nogil ++ char* value) + +- cdef xsltSecurityPrefs* xsltNewSecurityPrefs() nogil +- cdef void xsltFreeSecurityPrefs(xsltSecurityPrefs* sec) nogil ++ cdef xsltSecurityPrefs* xsltNewSecurityPrefs() ++ cdef void xsltFreeSecurityPrefs(xsltSecurityPrefs* sec) + cdef int xsltSecurityForbid(xsltSecurityPrefs* sec, + xsltTransformContext* ctxt, +- char* value) nogil ++ char* value) + cdef int xsltSecurityAllow(xsltSecurityPrefs* sec, + xsltTransformContext* ctxt, +- char* value) nogil ++ char* value) + cdef int xsltSetSecurityPrefs(xsltSecurityPrefs* sec, + xsltSecurityOption option, +- xsltSecurityCheck func) nogil ++ xsltSecurityCheck func) + cdef xsltSecurityCheck xsltGetSecurityPrefs( + xsltSecurityPrefs* sec, +- xsltSecurityOption option) nogil ++ xsltSecurityOption option) + cdef int xsltSetCtxtSecurityPrefs(xsltSecurityPrefs* sec, +- xsltTransformContext* ctxt) nogil +- cdef xmlDoc* xsltGetProfileInformation(xsltTransformContext* ctxt) nogil ++ xsltTransformContext* ctxt) ++ cdef xmlDoc* xsltGetProfileInformation(xsltTransformContext* ctxt) + +-cdef extern from "libxslt/variables.h": ++cdef extern from "libxslt/variables.h" nogil: + cdef int xsltQuoteUserParams(xsltTransformContext* ctxt, + const_char** params) + cdef int xsltQuoteOneUserParam(xsltTransformContext* ctxt, + const_xmlChar* name, + const_xmlChar* value) + +-cdef extern from "libxslt/extra.h": ++cdef extern from "libxslt/extra.h" nogil: + const_xmlChar* XSLT_LIBXSLT_NAMESPACE + const_xmlChar* XSLT_XALAN_NAMESPACE + const_xmlChar* XSLT_SAXON_NAMESPACE + const_xmlChar* XSLT_XT_NAMESPACE + + cdef xmlXPathFunction xsltFunctionNodeSet +- cdef void xsltRegisterAllExtras() nogil ++ cdef void xsltRegisterAllExtras() + +-cdef extern from "libexslt/exslt.h": +- cdef void exsltRegisterAll() nogil ++cdef extern from "libexslt/exslt.h" nogil: ++ cdef void exsltRegisterAll() + + # libexslt 1.1.25+ + const_xmlChar* EXSLT_DATE_NAMESPACE +@@ -188,4 +188,3 @@ cdef extern from "libexslt/exslt.h": + cdef int exsltSetsXpathCtxtRegister(xmlXPathContext* ctxt, const_xmlChar* prefix) + cdef int exsltMathXpathCtxtRegister(xmlXPathContext* ctxt, const_xmlChar* prefix) + cdef int exsltStrXpathCtxtRegister(xmlXPathContext* ctxt, const_xmlChar* prefix) +- diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..8653363 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,8 @@ +--- !Policy +product_versions: + - fedora-* +decision_contexts: + - bodhi_update_push_testing + - bodhi_update_push_stable +rules: + - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/smoke.functional} diff --git a/get-lxml-source.sh b/get-lxml-source.sh new file mode 100755 index 0000000..ae069f1 --- /dev/null +++ b/get-lxml-source.sh @@ -0,0 +1,28 @@ +#! /bin/bash -ex + +# Download a release of lxml (if missing) and remove the isoschematron module from it + +version=$1 + +if [ -z "${version}" ]; then + echo "Usage: $0 VERSION" >& 2 + echo "" >& 2 + echo "example: $0 4.9.2" >& 2 + exit 1 +fi + +versionedname=lxml-${version} +orig_archive=${versionedname}.tar.gz +new_archive=${versionedname}-no-isoschematron-rng.tar.gz + +if [ ! -e ${orig_archive} ]; then + wget -N https://files.pythonhosted.org/packages/source/l/lxml/${orig_archive} +fi + +deleted_directory=lxml-${version}/src/lxml/isoschematron/resources/rng + +# tar --delete does not operate on compressed archives, so do +# gz decompression explicitly +gzip --decompress ${orig_archive} +tar -v --delete -f ${orig_archive//.gz} ${deleted_directory} +gzip -cf ${orig_archive//.gz} > ${new_archive} diff --git a/plans/etree-fromstring.py b/plans/etree-fromstring.py new file mode 100644 index 0000000..b400cc0 --- /dev/null +++ b/plans/etree-fromstring.py @@ -0,0 +1,7 @@ +import lxml.etree as et +s = 'ac' +x = et.fromstring(s) +t = x.find('bar').text +print(t) +if t != 'abc': + raise Exception() diff --git a/plans/smoke.fmf b/plans/smoke.fmf new file mode 100644 index 0000000..908e08d --- /dev/null +++ b/plans/smoke.fmf @@ -0,0 +1,12 @@ +summary: Basic smoke test +discover: + how: shell + tests: + - name: /smoke/import-python-module + test: | + python3 -c 'import importlib as il; print(il.import_module("lxml"))' + - name: /smoke/etree-fromstring + test: | + python3 plans/etree-fromstring.py +execute: + how: tmt diff --git a/python-lxml.spec b/python-lxml.spec new file mode 100644 index 0000000..c25bc4d --- /dev/null +++ b/python-lxml.spec @@ -0,0 +1,1728 @@ +Name: python-lxml +Version: 4.9.3 +Release: 2%{?dist} +Summary: XML processing library combining libxml2/libxslt with the ElementTree API + +# The lxml project is licensed under BSD-3-Clause +# Some code is derived from ElementTree and cElementTree +# thus using the MIT-CMU elementtree license +# .xsl schematron files are under the MIT license +License: BSD-3-Clause AND MIT-CMU AND MIT +URL: https://github.com/lxml/lxml + +# We use the get-lxml-source.sh script to generate the tarball +# without the isoschematron RNG validation file under a problematic license. +# See: https://gitlab.com/fedora/legal/fedora-license-data/-/issues/154 +Source0: lxml-%{version}-no-isoschematron-rng.tar.gz +Source1: get-lxml-source.sh + +# Make the validation of ISO-Schematron files optional in lxml, +# depending on the availability of the RNG validation file +# Rebased from https://github.com/lxml/lxml/commit/4bfab2c821961fb4c5ed8a04e329778c9b09a1df +# Will be included in lxml 5.0 +Patch: Make-the-validation-of-ISO-Schematron-files-optional.patch +# Skip test_isoschematron.test_schematron_invalid_schema_empty without the RNG file +Patch: https://github.com/lxml/lxml/pull/380.patch + +# Upstream issue: https://bugs.launchpad.net/lxml/+bug/2016939 +Patch: Skip-failing-test-test_html_prefix_nsmap.patch + +# Cython 3 support backported from future lxml 5.0 +Patch: https://github.com/lxml/lxml/commit/dcbc0cc1cb0cedf8019184aaca805d2a649cd8de.patch +Patch: https://github.com/lxml/lxml/commit/a03a4b3c6b906d33c5ef1a15f3d5ca5fff600c76.patch + +BuildRequires: gcc +BuildRequires: libxml2-devel +BuildRequires: libxslt-devel +BuildRequires: python3-devel + +# Some of the extras create a build dependency loop. +# - [cssselect] Requires cssselect BuildRequires lxml +# - [html5] Requires html5lib BuildRequires lxml +# - [htmlsoup] Requires beautifulsoup4 Requires lxml +# Hence we provide a bcond to disable the extras altogether. +# By default, the extras are disabled in RHEL, to avoid dependencies. +%bcond extras %{undefined rhel} + +%global _description \ +lxml is a Pythonic, mature binding for the libxml2 and libxslt libraries. It\ +provides safe and convenient access to these libraries using the ElementTree It\ +extends the ElementTree API significantly to offer support for XPath, RelaxNG,\ +XML Schema, XSLT, C14N and much more. + +%description %{_description} + +%package -n python3-lxml +Summary: %{summary} +%if %{with extras} +Suggests: python3-lxml+cssselect +Suggests: python3-lxml+html5 +Suggests: python3-lxml+htmlsoup +%endif + +%description -n python3-lxml %{_description} + +Python 3 version. + +%if %{with extras} +%pyproject_extras_subpkg -n python3-lxml cssselect html5 htmlsoup +%endif + +%prep +%autosetup -n lxml-%{version} -p1 +# Don't run html5lib tests --without extras +%{!?without_extras:rm src/lxml/html/tests/test_html5parser.py} + +%generate_buildrequires +%pyproject_buildrequires -x source%{?with_extras:,cssselect,html5,htmlsoup} +# Remove pregenerated Cython C sources +# We need to do this after %%pyproject_buildrequires because setup.py errors +# without Cython and without the .c files. +find -type f -name '*.c' -print -delete >&2 + +%build +export WITH_CYTHON=true +%pyproject_wheel + +%install +%pyproject_install +%pyproject_save_files lxml + +%check +# The tests assume inplace build, so we copy the built library to source-dir. +# If not done that, Python can either import the tests or the extension modules, but not both. +cp -a build/lib.%{python3_platform}-*/* src/ +# The options are: verbose, unit, functional +%{python3} test.py -vuf + +%files -n python3-lxml -f %{pyproject_files} +%license doc/licenses/BSD.txt doc/licenses/elementtree.txt +%doc README.rst + +%changelog +* Fri Jul 28 2023 Miro Hrončok - 4.9.3-2 +- Fix build with Cython 3 + +* Fri Jul 21 2023 Lumír Balhar - 4.9.3-1 +- Update to 4.9.3 (rhbz#2219811) + +* Fri Jul 21 2023 Fedora Release Engineering - 4.9.2-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Fri Jul 14 2023 Miro Hrončok - 4.9.2-8 +- Bring back the isoschematron submodule, + but without the validation of the schema file itself + +* Fri Jun 16 2023 Python Maint - 4.9.2-7 +- Rebuilt for Python 3.12 + +* Tue Jun 13 2023 Python Maint - 4.9.2-6 +- Bootstrap for Python 3.12 + +* Wed May 31 2023 Miro Hrončok - 4.9.2-5 +- Remove the isoschematron submodule + +* Tue May 30 2023 Yaakov Selkowitz - 4.9.2-4 +- Disable extra subpackages in RHEL builds + +* Mon May 29 2023 Tomáš Hrnčiar - 4.9.2-3 +- Skip failing test to avoid FTBFS + +* Fri Jan 20 2023 Fedora Release Engineering - 4.9.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Wed Dec 14 2022 Lumír Balhar - 4.9.2-1 +- Update to 4.9.2 (rhbz#2153063) + +* Wed Sep 14 2022 Charalampos Stratakis - 4.9.1-1 +- Update to 4.9.1 +- Fix for CVE-2022-2309 +- Resolves: rhbz#2107571, rhbz#2110131 + +* Wed Aug 31 2022 Miro Hrončok - 4.7.1-6 +- Use SPDX license identifiers +- The schematron files are not Zlib licensed, but MIT +- Package the lxml[cssselect], lxml[html5] and lxml[htmlsoup] extras + +* Fri Jul 22 2022 Fedora Release Engineering - 4.7.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jun 22 2022 Charalampos Stratakis - 4.7.1-4 +- Fix FTBFS with setuptools >= 62.1 +- Resolves: rhbz#2097102 + +* Mon Jun 13 2022 Python Maint - 4.7.1-3 +- Rebuilt for Python 3.11 + +* Fri Jan 21 2022 Fedora Release Engineering - 4.7.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Thu Jan 06 2022 Charalampos Stratakis - 4.7.1-1 +- Update to 4.7.1 +- Fixes CVE-2021-43818 +- Resolves: rhbz#2031686, rhbz#2032572 + +* Fri Nov 26 2021 Miro Hrončok - 4.6.3-5 +- Run the tests during build +- Resolves: rhbz#2026941 + +* Fri Jul 23 2021 Fedora Release Engineering - 4.6.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Thu Jun 03 2021 Charalampos Stratakis - 4.6.3-3 +- Update the license information + +* Wed Jun 02 2021 Python Maint - 4.6.3-2 +- Rebuilt for Python 3.10 + +* Thu May 20 2021 Charalampos Stratakis - 4.6.3-1 +- Update to 4.6.3 +- Fixes CVE-2021-28957 +- Fixes: rhbz#1941773 +- Fixes: rhbz#1941535 + +* Wed Jan 27 2021 Fedora Release Engineering - 4.6.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Dec 01 2020 Miro Hrončok - 4.6.2-1 +- Update to 4.6.2 +- Fixes CVE-2020-27783 and another vulnerability in the HTML Cleaner +- Fixes: rhbz#1855415 +- Fixes: rhbz#1901634 + +* Wed Jul 29 2020 Fedora Release Engineering - 4.5.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jun 01 2020 Igor Raits - 4.5.1-1 +- Update to 4.5.1 + +* Fri May 22 2020 Miro Hrončok - 4.4.1-5 +- Rebuilt for Python 3.9 + +* Thu Jan 30 2020 Fedora Release Engineering - 4.4.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Nov 20 2019 Miro Hrončok - 4.4.1-3 +- Subpackage python2-lxml has been removed + See https://fedoraproject.org/wiki/Changes/Mass_Python_2_Package_Removal + +* Sat Sep 07 2019 Igor Gnatenko - 4.4.1-2 +- Generate C files using py3 Cython + +* Sat Sep 07 2019 Igor Gnatenko - 4.4.1-1 +- Update to 4.4.1 + +* Fri Aug 16 2019 Miro Hrončok - 4.4.0-2 +- Rebuilt for Python 3.8 + +* Sat Aug 03 2019 Igor Gnatenko - 4.4.0-1 +- Update to 4.4.0 + +* Fri Jul 26 2019 Fedora Release Engineering - 4.2.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sat Feb 02 2019 Fedora Release Engineering - 4.2.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Dec 18 2018 Igor Gnatenko - 4.2.5-1 +- Update to 4.2.5 + +* Sun Sep 02 2018 Igor Gnatenko - 4.2.4-1 +- Update to 4.2.4 + +* Sat Jul 14 2018 Fedora Release Engineering - 4.2.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Sat Jul 07 2018 Igor Gnatenko - 4.2.3-1 +- Update to 4.2.3 + +* Sun Jun 17 2018 Miro Hrončok - 4.2.1-2 +- Rebuilt for Python 3.7 + +* Wed Apr 25 2018 Igor Gnatenko - 4.2.1-1 +- Update to 4.2.1 + +* Fri Feb 09 2018 Fedora Release Engineering - 4.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sun Nov 05 2017 Igor Gnatenko - 4.1.1-1 +- Update to 4.1.1 + +* Tue Oct 10 2017 Mikolaj Izdebski - 4.0.0-2 +- Conditionally allow building without Cython + +* Thu Oct 05 2017 Igor Gnatenko - 4.0.0-1 +- Update to 4.0.0 + +* Sat Aug 12 2017 Kevin Fenzi - 3.8.0-1 +- Update to 3.8.0. Fixes bug #1458529 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.7.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.7.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 3.7.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 09 2017 Fabio Alessandro Locati - 3.7.2-1 +- Update to 3.7.2 + +* Sun Dec 25 2016 Fabio Alessandro Locati - 3.7.1-1 +- Update to 3.7.1 + +* Tue Dec 13 2016 Stratakis Charalampos - 3.7.0-2 +- Rebuild for Python 3.6 + +* Sun Dec 11 2016 Fabio Alessandro Locati - 3.7.0-1 +- Update to 3.7.0 + +* Thu Sep 08 2016 Fabio Alessandro Locati - 3.6.4-1 +- Update to 3.6.4 + +* Tue Jul 19 2016 Fedora Release Engineering - 3.4.4-5 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Thu Feb 04 2016 Fedora Release Engineering - 3.4.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 21 2016 Dan Horák - 3.4.4-3 +- fix conditional + +* Fri Nov 06 2015 Robert Kuska - 3.4.4-2 +- Rebuilt for Python3.5 rebuild + +* Fri Aug 28 2015 Peter Robinson 3.4.4-1 +- Update to 3.4.4 +- Use %%license, cleanup spec + +* Thu Jun 18 2015 Fedora Release Engineering - 3.3.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Aug 29 2014 Jeffrey C. Ollie - 3.3.6-1 +- 3.3.6 (2014-08-28) +- ================== +- +- Bugs fixed +- ---------- +- +- * Prevent tree cycle creation when adding Elements as siblings. +- +- * LP#1361948: crash when deallocating Element siblings without parent. +- +- * LP#1354652: crash when traversing internally loaded documents in XSLT +- extension functions. + +* Sun Aug 17 2014 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 3.3.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed May 14 2014 Bohuslav Kabrda - 3.3.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Changes/Python_3.4 + +* Mon Apr 28 2014 Jeffrey Ollie - 3.3.5-1 +- 3.3.5 (2014-04-18) +- ================== +- +- Bugs fixed +- ---------- +- +- * HTML cleaning could fail to strip javascript links that mix control +- characters into the link scheme. + +* Mon Apr 28 2014 Jeffrey Ollie - 3.3.4-1 +- 3.3.4 (2014-04-03) +- ================== +- +- Features added +- -------------- +- +- * Source line numbers above 65535 are available on Elements when +- using libxml2 2.9 or later. +- +- Bugs fixed +- ---------- +- +- * lxml.html.fragment_fromstring() failed for bytes input in Py3. + +* Wed Mar 26 2014 Jeffrey Ollie - 3.3.3-4 +- Fix macro definition + +* Wed Mar 26 2014 Jeffrey Ollie - 3.3.3-3 +- Add python3-cssselect to correct package + +* Mon Mar 24 2014 Jeffrey Ollie - 3.3.3-3 +- python3-cssselect is not available on F19 + +* Mon Mar 24 2014 Jeffrey Ollie - 3.3.3-2 +- BZ#1075070 add requires and buildrequires for cssselect + +* Tue Mar 11 2014 Jeffrey Ollie - 3.3.3-1 +- 3.3.3 (2014-03-04) +- ================== +- +- Bugs fixed +- ---------- +- +- * LP#1287118: Crash when using Element subtypes with ``__slots__``. +- +- Other changes +- ------------- +- +- * The internal classes ``_LogEntry`` and ``_Attrib`` can no longer be +- subclassed from Python code. + +* Tue Mar 11 2014 Alexander Todorov - 3.3.2-2 +- Add check section #1075070 + +* Fri Feb 28 2014 Jeffrey Ollie - 3.3.2-1 +- 3.3.2 (2014-02-26) +- ================== +- +- Bugs fixed +- ---------- +- +- * The properties ``resolvers`` and ``version``, as well as the methods +- ``set_element_class_lookup()`` and ``makeelement()``, were lost from +- ``iterparse`` objects. +- +- * LP#1222132: instances of ``XMLSchema``, ``Schematron`` and ``RelaxNG`` +- did not clear their local ``error_log`` before running a validation. +- +- * LP#1238500: lxml.doctestcompare mixed up "expected" and "actual" in +- attribute values. +- +- * Some file I/O tests were failing in MS-Windows due to incorrect temp +- file usage. Initial patch by Gabi Davar. +- +- * LP#910014: duplicate IDs in a document were not reported by DTD +- validation. +- +- * LP#1185332: ``tostring(method="html")`` did not use HTML serialisation +- semantics for trailing tail text. Initial patch by Sylvain Viollon. +- +- * LP#1281139: ``.attrib`` value of Comments lost its mutation methods +- in 3.3.0. Even though it is empty and immutable, it should still +- provide the same interface as that returned for Elements. + +* Fri Feb 28 2014 Jeffrey Ollie - 3.3.2-1 +- 3.3.1 (2014-02-12) +- ================== +- +- Bugs fixed +- ---------- +- +- * LP#1014290: HTML documents parsed with ``parser.feed()`` failed to find +- elements during tag iteration. +- +- * LP#1273709: Building in PyPy failed due to missing support for +- ``PyUnicode_Compare()`` and ``PyByteArray_*()`` in PyPy's C-API. +- +- * LP#1274413: Compilation in MSVC failed due to missing "stdint.h" standard +- header file. +- +- * LP#1274118: iterparse() failed to parse BOM prefixed files. + +* Mon Jan 27 2014 Jeffrey Ollie - 3.3.0-2 +- Update Cython requirement to >= 0.20 + +* Mon Jan 27 2014 Jeffrey Ollie - 3.3.0-1 +- 3.3.0 (2014-01-26) +- ================== +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * The heuristic that distinguishes file paths from URLs was tightened +- to produce less false negatives. +- +- Other changes +- ------------- +- +- +- 3.3.0beta5 (2014-01-18) +- ======================= +- +- Features added +- -------------- +- +- * The PEP 393 unicode parsing support gained a fallback for wchar strings +- which might still be somewhat common on Windows systems. +- +- Bugs fixed +- ---------- +- +- * Several error handling problems were fixed throughout the code base that +- could previously lead to exceptions being silently swallowed or not +- properly reported. +- +- * The C-API function ``appendChild()`` is now deprecated as it does not +- propagate exceptions (its return type is ``void``). The new function +- ``appendChildToElement()`` was added as a safe replacement. +- +- * Passing a string into ``fromstringlist()`` raises an exception instead of +- parsing the string character by character. +- +- Other changes +- ------------- +- +- * Document cleanup code was simplified using the new GC features in +- Cython 0.20. +- +- +- 3.3.0beta4 (2014-01-12) +- ======================= +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * The (empty) value returned by the ``attrib`` property of Entity and +- Comment objects was mutable. +- +- * Element class lookup wasn't available for the new pull parsers or when +- using a custom parser target. +- +- * Setting Element attributes on instantiation with both the ``attrib`` +- argument and keyword arguments could modify the mapping passed as +- ``attrib``. +- +- * LP#1266171: DTDs instantiated from internal/external subsets (i.e. +- through the docinfo property) lost their attribute declarations. +- +- Other changes +- ------------- +- +- * Built with Cython 0.20pre (gitrev 012ae82eb) to prepare support for +- Python 3.4. +- +- +- 3.3.0beta3 (2014-01-02) +- ======================= +- +- Features added +- -------------- +- +- * Unicode string parsing was optimised for Python 3.3 (PEP 393). +- +- Bugs fixed +- ---------- +- +- * HTML parsing of Unicode strings could misdecode the input on some +- platforms. +- +- * Crash in xmlfile() when closing open elements out of order in an error +- case. +- +- Other changes +- ------------- +- +- +- 3.3.0beta2 (2013-12-20) +- ======================= +- +- Features added +- -------------- +- +- * ``iterparse()`` supports the ``recover`` option. +- +- Bugs fixed +- ---------- +- +- * Crash in ``iterparse()`` for HTML parsing. +- +- * Crash in target parsing with attributes. +- +- Other changes +- ------------- +- +- * The safety check in the read-only tree implementation (e.g. used by +- ``PythonElementClassLookup``) raises a more appropriate +- ``ReferenceError`` for illegal access after tree disposal instead of +- an ``AssertionError``. This should only impact test code that +- specifically checks the original behaviour. +- +- +- 3.3.0beta1 (2013-12-12) +- ======================= +- +- Features added +- -------------- +- +- * New option ``handle_failures`` in ``make_links_absolute()`` and +- ``resolve_base_href()`` (lxml.html) that enables ignoring or +- discarding links that fail to parse as URLs. +- +- * New parser classes ``XMLPullParser`` and ``HTMLPullParser`` for +- incremental parsing, as implemented for ElementTree in Python 3.4. +- +- * ``iterparse()`` enables recovery mode by default for HTML parsing +- (``html=True``). +- +- Bugs fixed +- ---------- +- +- * LP#1255132: crash when trying to run validation over non-Element (e.g. +- comment or PI). +- +- * Error messages in the log and in exception messages that originated +- from libxml2 could accidentally be picked up from preceding warnings +- instead of the actual error. +- +- * The ``ElementMaker`` in lxml.objectify did not accept a dict as +- argument for adding attributes to the element it's building. This +- works as in lxml.builder now. +- +- * LP#1228881: ``repr(XSLTAccessControl)`` failed in Python 3. +- +- * Raise ``ValueError`` when trying to append an Element to itself or +- to one of its own descendants, instead of running into an infinite +- loop. +- +- * LP#1206077: htmldiff discarded whitespace from the output. +- +- * Compressed plain-text serialisation to file-like objects was broken. +- +- * lxml.html.formfill: Fix textarea form filling. +- The textarea used to be cleared before the new content was set, +- which removed the name attribute. +- +- Other changes +- ------------- +- +- * Some basic API classes use freelists internally for faster +- instantiation. This can speed up some ``iterparse()`` scenarios, +- for example. +- +- * ``iterparse()`` was rewritten to use the new ``*PullParser`` +- classes internally instead of being a parser itself. + +* Mon Nov 11 2013 Jeffrey Ollie - 3.2.4-1 +- 3.2.4 (2013-11-07) +- ================== +- +- Bugs fixed +- ---------- +- +- * Memory leak when creating an XPath evaluator in a thread. +- +- * LP#1228881: ``repr(XSLTAccessControl)`` failed in Python 3. +- +- * Raise ``ValueError`` when trying to append an Element to itself or +- to one of its own descendants. +- +- * LP#1206077: htmldiff discarded whitespace from the output. +- +- * Compressed plain-text serialisation to file-like objects was broken. + +* Wed Sep 18 2013 Jeffrey Ollie - 3.2.3-2 +- Add requirement for on python-cssselect for the python2 version + +* Sun Jul 28 2013 Jeffrey Ollie - 3.2.3-1 +- and here's a version 3.2.3. The last release accidentally lost the ability +- to work on Python 2.4. There are no other changes over 3.2.2. +- +- 3.2.2 (2013-07-28) +- ================== +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * LP#1185701: spurious XMLSyntaxError after finishing iterparse(). +- +- * Crash in lxml.objectify during xsi annotation. +- +- Other changes +- ------------- +- +- * Return values of user provided element class lookup methods are now +- validated against the type of the XML node they represent to prevent +- API class mismatches. + +* Sun May 12 2013 Jeffrey Ollie - 3.2.1-1 +- 3.2.1 (2013-05-11) +- ================== +- +- Features added +- -------------- +- +- * The methods ``apply_templates()`` and ``process_children()`` of XSLT +- extension elements have gained two new boolean options ``elements_only`` +- and ``remove_blank_text`` that discard either all strings or +- whitespace-only strings from the result list. +- +- Bugs fixed +- ---------- +- +- * When moving Elements to another tree, the namespace cleanup mechanism +- no longer drops namespace prefixes from attributes for which it finds +- a default namespace declaration, to prevent them from appearing as +- unnamespaced attributes after serialisation. +- +- * Returning non-type objects from a custom class lookup method could lead +- to a crash. +- +- * Instantiating and using subtypes of Comments and ProcessingInstructions +- crashed. + +* Fri May 10 2013 Jeffrey Ollie - 3.2.0-1 +- 3.2.0 (2013-04-28) +- ================== +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * LP#690319: Leading whitespace could change the behaviour of the string +- parsing functions in ``lxml.html``. +- +- * LP#599318: The string parsing functions in ``lxml.html`` are more robust +- in the face of uncommon HTML content like framesets or missing body tags. +- Patch by Stefan Seelmann. +- +- * LP#712941: I/O errors while trying to access files with paths that +- contain non-ASCII characters could raise ``UnicodeDecodeError`` instead +- of properly reporting the ``IOError``. +- +- * LP#673205: Parsing from in-memory strings disabled network access in the +- default parser and made subsequent attempts to parse from a URL fail. +- +- * LP#971754: lxml.html.clean appends 'nofollow' to 'rel' attributes instead +- of overwriting the current value. +- +- * LP#715687: lxml.html.clean no longer discards scripts that are explicitly +- allowed by the user provided whitelist. Patch by Christine Koppelt. +- +- 3.1.2 (2013-04-12) +- ================== +- +- Bugs fixed +- ---------- +- +- * LP#1136509: Passing attributes through the namespace-unaware API of +- the sax bridge (i.e. the ``handler.startElement()`` method) failed +- with a ``TypeError``. Patch by Mike Bayer. +- +- * LP#1123074: Fix serialisation error in XSLT output when converting +- the result tree to a Unicode string. +- +- * GH#105: Replace illegal usage of ``xmlBufLength()`` in libxml2 2.9.0 +- by properly exported API function ``xmlBufUse()``. +- +- 3.1.1 (2013-03-29) +- ================== +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * LP#1160386: Write access to ``lxml.html.FormElement.fields`` raised +- an AttributeError in Py3. +- +- * Illegal memory access during cleanup in incremental xmlfile writer. +- +- Other changes +- ------------- +- +- * The externally useless class ``lxml.etree._BaseParser`` was removed +- from the module dict. + +* Fri Mar 8 2013 Jeffrey Ollie - 3.1.0-1 +- 3.1.0 (2013-02-10) +- ================== +- +- Features added +- -------------- +- +- * GH#89: lxml.html.clean allows overriding the set of attributes that it +- considers 'safe'. Patch by Francis Devereux. +- +- Bugs fixed +- ---------- +- +- * LP#1104370: ``copy.copy(el.attrib)`` raised an exception. It now returns +- a copy of the attributes as a plain Python dict. +- +- * GH#95: When used with namespace prefixes, the ``el.find*()`` methods +- always used the first namespace mapping that was provided for each +- path expression instead of using the one that was actually passed +- in for the current run. +- +- * LP#1092521, GH#91: Fix undefined C symbol in Python runtimes compiled +- without threading support. Patch by Ulrich Seidl. +- +- Other changes +- ------------- +- +- +- 3.1beta1 (2012-12-21) +- ===================== +- +- Features added +- -------------- +- +- * New build-time option ``--with-unicode-strings`` for Python 2 that +- makes the API always return Unicode strings for names and text +- instead of byte strings for plain ASCII content. +- +- * New incremental XML file writing API ``etree.xmlfile()``. +- +- * E factory in lxml.objectify is callable to simplify the creation of +- tags with non-identifier names without having to resort to getattr(). +- +- Bugs fixed +- ---------- +- +- * When starting from a non-namespaced element in lxml.objectify, searching +- for a child without explicitly specifying a namespace incorrectly found +- namespaced elements with the requested local name, instead of restricting +- the search to non-namespaced children. +- +- * GH#85: Deprecation warnings were fixed for Python 3.x. +- +- * GH#33: lxml.html.fromstring() failed to accept bytes input in Py3. +- +- * LP#1080792: Static build of libxml2 2.9.0 failed due to missing file. +- +- Other changes +- ------------- +- +- * The externally useless class ``_ObjectifyElementMakerCaller`` was +- removed from the module API of lxml.objectify. +- +- * LP#1075622: lxml.builder is faster for adding text to elements with +- many children. Patch by Anders Hammarquist. + +* Thu Feb 14 2013 Fedora Release Engineering - 3.0.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Oct 15 2012 Jeffrey Ollie - 3.0.1-1 +- 3.0.1 (2012-10-14) +- Bugs fixed +- +- * LP#1065924: Element proxies could disappear during garbage collection +- in PyPy without proper cleanup. +- * GH#71: Failure to work with libxml2 2.6.x. +- * LP#1065139: static MacOS-X build failed in Py3. + +* Wed Oct 10 2012 Jeffrey Ollie - 3.0-1 +- 3.0 (2012-10-08) +- ================ +- +- Features added +- -------------- +- +- Bugs fixed +- ---------- +- +- * End-of-file handling was incorrect in iterparse() when reading from +- a low-level C file stream and failed in libxml2 2.9.0 due to its +- improved consistency checks. +- +- Other changes +- ------------- +- +- * The build no longer uses Cython by default unless the generated C files +- are missing. To use Cython, pass the option "--with-cython". To ignore +- the fatal build error when Cython is required but not available (e.g. to +- run special setup.py commands that do not actually run a build), pass +- "--without-cython". +- +- +- 3.0beta1 (2012-09-26) +- ===================== +- +- Features added +- -------------- +- +- * Python level access to (optional) libxml2 memory debugging features +- to simplify debugging of memory leaks etc. +- +- Bugs fixed +- ---------- +- +- * Fix a memory leak in XPath by switching to Cython 0.17.1. +- +- * Some tests were adapted to work with PyPy. +- +- Other changes +- ------------- +- +- * The code was adapted to work with the upcoming libxml2 2.9.0 release. +- +- +- 3.0alpha2 (2012-08-23) +- ====================== +- +- Features added +- -------------- +- +- * The .iter() method of elements now accepts tag arguments like "{*}name" +- to search for elements with a given local name in any namespace. With +- this addition, all combinations of wildcards now work as expected: +- "{ns}name", "{}name", "{*}name", "{ns}*", "{}*" and "{*}*". Note that +- "name" is equivalent to "{}name", but "*" is "{*}*". The same change +- applies to the .getiterator(), .itersiblings(), .iterancestors(), +- .iterdescendants(), .iterchildren() and .itertext() methods, the +- strip_attributes(), strip_elements() and strip_tags() functions as well +- as the iterparse() function. +- +- * C14N allows specifying the inclusive prefixes to be promoted to +- top-level during exclusive serialisation. +- +- Bugs fixed +- ---------- +- +- * Passing long Unicode strings into the feed() parser interface failed to +- read the entire string. +- +- Other changes +- ------------- +- +- +- 3.0alpha1 (2012-07-31) +- ====================== +- +- Features added +- -------------- +- +- * Initial support for building in PyPy (through cpyext). +- +- * DTD objects gained an API that allows read access to their +- declarations. +- +- * xpathgrep.py gained support for parsing line-by-line (e.g. +- from grep output) and for surrounding the output with a new root +- tag. +- +- * E-factory in lxml.builder accepts subtypes of known data +- types (such as string subtypes) when building elements around them. +- +- * Tree iteration and iterparse() with a selective tag +- argument supports passing a set of tags. Tree nodes will be +- returned by the iterators if they match any of the tags. +- +- Bugs fixed +- ---------- +- +- * The .find*() methods in lxml.objectify no longer use XPath +- internally, which makes them faster in many cases (especially when +- short circuiting after a single or couple of elements) and fixes +- some behavioural differences compared to lxml.etree. Note that +- this means that they no longer support arbitrary XPath expressions +- but only the subset that the ElementPath language supports. +- The previous implementation was also redundant with the normal +- XPath support, which can be used as a replacement. +- +- * el.find('*') could accidentally return a comment or processing +- instruction that happened to be in the wrong spot. (Same for the +- other .find*() methods.) +- +- * The error logging is less intrusive and avoids a global setup where +- possible. +- +- * Fixed undefined names in html5lib parser. +- +- * xpathgrep.py did not work in Python 3. +- +- * Element.attrib.update() did not accept an attrib of +- another Element as parameter. +- +- * For subtypes of ElementBase that make the .text or .tail +- properties immutable (as in objectify, for example), inserting text +- when creating Elements through the E-Factory feature of the class +- constructor would fail with an exception, stating that the text +- cannot be modified. +- +- Other changes +- -------------- +- +- * The code base was overhauled to properly use 'const' where the API +- of libxml2 and libxslt requests it. This also has an impact on the +- public C-API of lxml itself, as defined in etreepublic.pxd, as +- well as the provided declarations in the lxml/includes/ directory. +- Code that uses these declarations may have to be adapted. On the +- plus side, this fixes several C compiler warnings, also for user +- code, thus making it easier to spot real problems again. +- +- * The functionality of "lxml.cssselect" was moved into a separate PyPI +- package called "cssselect". To continue using it, you must install +- that package separately. The "lxml.cssselect" module is still +- available and provides the same interface, provided the "cssselect" +- package can be imported at runtime. +- +- * Element attributes passed in as an attrib dict or as keyword +- arguments are now sorted by (namespaced) name before being created +- to make their order predictable for serialisation and iteration. +- Note that adding or deleting attributes afterwards does not take +- that order into account, i.e. setting a new attribute appends it +- after the existing ones. +- +- * Several classes that are for internal use only were removed +- from the lxml.etree module dict: +- _InputDocument, _ResolverRegistry, _ResolverContext, _BaseContext, +- _ExsltRegExp, _IterparseContext, _TempStore, _ExceptionContext, +- __ContentOnlyElement, _AttribIterator, _NamespaceRegistry, +- _ClassNamespaceRegistry, _FunctionNamespaceRegistry, +- _XPathFunctionNamespaceRegistry, _ParserDictionaryContext, +- _FileReaderContext, _ParserContext, _PythonSaxParserTarget, +- _TargetParserContext, _ReadOnlyProxy, _ReadOnlyPIProxy, +- _ReadOnlyEntityProxy, _ReadOnlyElementProxy, _OpaqueNodeWrapper, +- _OpaqueDocumentWrapper, _ModifyContentOnlyProxy, +- _ModifyContentOnlyPIProxy, _ModifyContentOnlyEntityProxy, +- _AppendOnlyElementProxy, _SaxParserContext, _FilelikeWriter, +- _ParserSchemaValidationContext, _XPathContext, +- _XSLTResolverContext, _XSLTContext, _XSLTQuotedStringParam +- +- * Several internal classes can no longer be inherited from: +- _InputDocument, _ResolverRegistry, _ExsltRegExp, _ElementUnicodeResult, +- _IterparseContext, _TempStore, _AttribIterator, _ClassNamespaceRegistry, +- _XPathFunctionNamespaceRegistry, _ParserDictionaryContext, +- _FileReaderContext, _PythonSaxParserTarget, _TargetParserContext, +- _ReadOnlyPIProxy, _ReadOnlyEntityProxy, _OpaqueDocumentWrapper, +- _ModifyContentOnlyPIProxy, _ModifyContentOnlyEntityProxy, +- _AppendOnlyElementProxy, _FilelikeWriter, _ParserSchemaValidationContext, +- _XPathContext, _XSLTResolverContext, _XSLTContext, +- _XSLTQuotedStringParam, _XSLTResultTree, _XSLTProcessingInstruction + +* Thu Sep 27 2012 Jeffrey Ollie - 2.3.5-1 +- Bugs fixed +- +- * Crash when merging text nodes in element.remove(). +- * Crash in sax/target parser when reporting empty doctype. + +* Thu Sep 27 2012 Jeffrey Ollie - 2.3.4-1 +- Bugs fixed +- +- * Crash when building an nsmap (Element property) with empty namespace +- URIs. +- * Crash due to race condition when errors (or user messages) occur during +- threaded XSLT processing (or compilation). +- * XSLT stylesheet compilation could ignore compilation errors. + +* Sat Aug 04 2012 David Malcolm - 2.3.3-4 +- rebuild for https://fedoraproject.org/wiki/Features/Python_3.3 + +* Fri Aug 3 2012 David Malcolm - 2.3.3-3 +- remove rhel logic from with_python3 conditional + +* Sat Jul 21 2012 Fedora Release Engineering - 2.3.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jan 5 2012 Jeffrey C. Ollie - 2.3.3-1 +- 2.3.3 (2012-01-04) +- Features added +- +- * lxml.html.tostring() gained new serialisation options with_tail and +- doctype. +- +- Bugs fixed +- +- * Fixed a crash when using iterparse() for HTML parsing and requesting +- start events. +- * Fixed parsing of more selectors in cssselect. Whitespace before pseudo- +- elements and pseudo-classes is significant as it is a descendant +- combinator. "E :pseudo" should parse the same as "E *:pseudo", not +- "E:pseudo". Patch by Simon Sapin. +- * lxml.html.diff no longer raises an exception when hitting 'img' tags +- without 'src' attribute. + +* Mon Nov 14 2011 Jeffrey C. Ollie - 2.3.2-1 +- 2.3.2 (2011-11-11) +- Features added +- +- * lxml.objectify.deannotate() has a new boolean option +- cleanup_namespaces to remove the objectify namespace declarations +- (and generally clean up the namespace declarations) after removing +- the type annotations. +- * lxml.objectify gained its own SubElement() function as a copy of +- etree.SubElement to avoid an otherwise redundant import of +- lxml.etree on the user side. +- +- Bugs fixed +- +- * Fixed the "descendant" bug in cssselect a second time (after a first +- fix in lxml 2.3.1). The previous change resulted in a serious +- performance regression for the XPath based evaluation of the +- translated expression. Note that this breaks the usage of some +- of the generated XPath expressions as XSLT location paths that +- previously worked in 2.3.1. +- * Fixed parsing of some selectors in cssselect. Whitespace after +- combinators ">", "+" and "~" is now correctly ignored. Previously +- it was parsed as a descendant combinator. For example, "div> .foo" +- was parsed the same as "div>* .foo" instead of "div>.foo". Patch by +- Simon Sapin. + +* Sun Sep 25 2011 Jeffrey C. Ollie - 2.3.1-1 +- Features added +- -------------- +- +- * New option kill_tags in lxml.html.clean to remove specific +- tags and their content (i.e. their whole subtree). +- +- * pi.get() and pi.attrib on processing instructions to parse +- pseudo-attributes from the text content of processing instructions. +- +- * lxml.get_include() returns a list of include paths that can be +- used to compile external C code against lxml.etree. This is +- specifically required for statically linked lxml builds when code +- needs to compile against the exact same header file versions as lxml +- itself. +- +- * Resolver.resolve_file() takes an additional option +- close_file that configures if the file(-like) object will be +- closed after reading or not. By default, the file will be closed, +- as the user is not expected to keep a reference to it. +- +- Bugs fixed +- ---------- +- +- * HTML cleaning didn't remove 'data:' links. +- +- * The html5lib parser integration now uses the 'official' +- implementation in html5lib itself, which makes it work with newer +- releases of the library. +- +- * In lxml.sax, endElementNS() could incorrectly reject a plain +- tag name when the corresponding start event inferred the same plain +- tag name to be in the default namespace. +- +- * When an open file-like object is passed into parse() or +- iterparse(), the parser will no longer close it after use. This +- reverts a change in lxml 2.3 where all files would be closed. It is +- the users responsibility to properly close the file(-like) object, +- also in error cases. +- +- * Assertion error in lxml.html.cleaner when discarding top-level elements. +- +- * In lxml.cssselect, use the xpath 'A//B' (short for +- 'A/descendant-or-self::node()/B') instead of 'A/descendant::B' for the +- css descendant selector ('A B'). This makes a few edge cases to be +- consistent with the selector behavior in WebKit and Firefox, and makes +- more css expressions valid location paths (for use in xsl:template +- match). +- +- * In lxml.html, non-selected