aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi')
-rw-r--r--.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi180
1 files changed, 180 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi b/.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi
new file mode 100644
index 00000000..37c29957
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/lxml/parsertarget.pxi
@@ -0,0 +1,180 @@
+# Parser target context (ET target interface)
+
+cdef object inspect_getargspec
+try:
+ from inspect import getfullargspec as inspect_getargspec
+except ImportError:
+ from inspect import getargspec as inspect_getargspec
+
+
+class _TargetParserResult(Exception):
+ # Admittedly, this is somewhat ugly, but it's the easiest way
+ # to push the Python level parser result through the parser
+ # machinery towards the API level functions
+ def __init__(self, result):
+ self.result = result
+
+
+@cython.final
+@cython.internal
+cdef class _PythonSaxParserTarget(_SaxParserTarget):
+ cdef object _target_start
+ cdef object _target_end
+ cdef object _target_data
+ cdef object _target_start_ns
+ cdef object _target_end_ns
+ cdef object _target_doctype
+ cdef object _target_pi
+ cdef object _target_comment
+ cdef bint _start_takes_nsmap
+
+ def __cinit__(self, target):
+ cdef int event_filter
+ event_filter = 0
+ self._start_takes_nsmap = 0
+ try:
+ self._target_start = target.start
+ if self._target_start is not None:
+ event_filter |= SAX_EVENT_START
+ except AttributeError:
+ pass
+ else:
+ try:
+ arguments = inspect_getargspec(self._target_start)
+ if len(arguments[0]) > 3 or arguments[1] is not None:
+ self._start_takes_nsmap = 1
+ except TypeError:
+ pass
+ try:
+ self._target_end = target.end
+ if self._target_end is not None:
+ event_filter |= SAX_EVENT_END
+ except AttributeError:
+ pass
+ try:
+ self._target_start_ns = target.start_ns
+ if self._target_start_ns is not None:
+ event_filter |= SAX_EVENT_START_NS
+ except AttributeError:
+ pass
+ try:
+ self._target_end_ns = target.end_ns
+ if self._target_end_ns is not None:
+ event_filter |= SAX_EVENT_END_NS
+ except AttributeError:
+ pass
+ try:
+ self._target_data = target.data
+ if self._target_data is not None:
+ event_filter |= SAX_EVENT_DATA
+ except AttributeError:
+ pass
+ try:
+ self._target_doctype = target.doctype
+ if self._target_doctype is not None:
+ event_filter |= SAX_EVENT_DOCTYPE
+ except AttributeError:
+ pass
+ try:
+ self._target_pi = target.pi
+ if self._target_pi is not None:
+ event_filter |= SAX_EVENT_PI
+ except AttributeError:
+ pass
+ try:
+ self._target_comment = target.comment
+ if self._target_comment is not None:
+ event_filter |= SAX_EVENT_COMMENT
+ except AttributeError:
+ pass
+ self._sax_event_filter = event_filter
+
+ cdef _handleSaxStart(self, tag, attrib, nsmap):
+ if self._start_takes_nsmap:
+ return self._target_start(tag, attrib, nsmap)
+ else:
+ return self._target_start(tag, attrib)
+
+ cdef _handleSaxEnd(self, tag):
+ return self._target_end(tag)
+
+ cdef _handleSaxStartNs(self, prefix, uri):
+ return self._target_start_ns(prefix, uri)
+
+ cdef _handleSaxEndNs(self, prefix):
+ return self._target_end_ns(prefix)
+
+ cdef int _handleSaxData(self, data) except -1:
+ self._target_data(data)
+
+ cdef int _handleSaxDoctype(self, root_tag, public_id, system_id) except -1:
+ self._target_doctype(root_tag, public_id, system_id)
+
+ cdef _handleSaxPi(self, target, data):
+ return self._target_pi(target, data)
+
+ cdef _handleSaxComment(self, comment):
+ return self._target_comment(comment)
+
+
+@cython.final
+@cython.internal
+@cython.no_gc_clear # Required because parent class uses it - Cython bug.
+cdef class _TargetParserContext(_SaxParserContext):
+ """This class maps SAX2 events to the ET parser target interface.
+ """
+ cdef object _python_target
+ cdef int _setTarget(self, target) except -1:
+ self._python_target = target
+ if not isinstance(target, _SaxParserTarget) or \
+ hasattr(target, '__dict__'):
+ target = _PythonSaxParserTarget(target)
+ self._setSaxParserTarget(target)
+ return 0
+
+ cdef _ParserContext _copy(self):
+ cdef _TargetParserContext context
+ context = _ParserContext._copy(self)
+ context._setTarget(self._python_target)
+ return context
+
+ cdef void _cleanupTargetParserContext(self, xmlDoc* result) noexcept:
+ if self._c_ctxt.myDoc is not NULL:
+ if self._c_ctxt.myDoc is not result and \
+ self._c_ctxt.myDoc._private is NULL:
+ # no _Document proxy => orphen
+ tree.xmlFreeDoc(self._c_ctxt.myDoc)
+ self._c_ctxt.myDoc = NULL
+
+ cdef object _handleParseResult(self, _BaseParser parser, xmlDoc* result,
+ filename):
+ cdef bint recover
+ recover = parser._parse_options & xmlparser.XML_PARSE_RECOVER
+ try:
+ if self._has_raised():
+ self._cleanupTargetParserContext(result)
+ self._raise_if_stored()
+ if not self._c_ctxt.wellFormed and not recover:
+ _raiseParseError(self._c_ctxt, filename, self._error_log)
+ except:
+ self._python_target.close()
+ raise
+ return self._python_target.close()
+
+ cdef xmlDoc* _handleParseResultDoc(self, _BaseParser parser,
+ xmlDoc* result, filename) except NULL:
+ cdef bint recover
+ recover = parser._parse_options & xmlparser.XML_PARSE_RECOVER
+ if result is not NULL and result._private is NULL:
+ # no _Document proxy => orphen
+ tree.xmlFreeDoc(result)
+ try:
+ self._cleanupTargetParserContext(result)
+ self._raise_if_stored()
+ if not self._c_ctxt.wellFormed and not recover:
+ _raiseParseError(self._c_ctxt, filename, self._error_log)
+ except:
+ self._python_target.close()
+ raise
+ parse_result = self._python_target.close()
+ raise _TargetParserResult(parse_result)