aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/lxml/docloader.pxi
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/lxml/docloader.pxi')
-rw-r--r--.venv/lib/python3.12/site-packages/lxml/docloader.pxi178
1 files changed, 178 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/lxml/docloader.pxi b/.venv/lib/python3.12/site-packages/lxml/docloader.pxi
new file mode 100644
index 00000000..7b38f438
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/lxml/docloader.pxi
@@ -0,0 +1,178 @@
+# Custom resolver API
+
+ctypedef enum _InputDocumentDataType:
+ PARSER_DATA_INVALID
+ PARSER_DATA_EMPTY
+ PARSER_DATA_STRING
+ PARSER_DATA_FILENAME
+ PARSER_DATA_FILE
+
+@cython.final
+@cython.internal
+cdef class _InputDocument:
+ cdef _InputDocumentDataType _type
+ cdef bytes _data_bytes
+ cdef object _filename
+ cdef object _file
+ cdef bint _close_file
+
+ def __cinit__(self):
+ self._type = PARSER_DATA_INVALID
+
+
+cdef class Resolver:
+ "This is the base class of all resolvers."
+ def resolve(self, system_url, public_id, context):
+ """resolve(self, system_url, public_id, context)
+
+ Override this method to resolve an external source by
+ ``system_url`` and ``public_id``. The third argument is an
+ opaque context object.
+
+ Return the result of one of the ``resolve_*()`` methods.
+ """
+ return None
+
+ def resolve_empty(self, context):
+ """resolve_empty(self, context)
+
+ Return an empty input document.
+
+ Pass context as parameter.
+ """
+ cdef _InputDocument doc_ref
+ doc_ref = _InputDocument()
+ doc_ref._type = PARSER_DATA_EMPTY
+ return doc_ref
+
+ def resolve_string(self, string, context, *, base_url=None):
+ """resolve_string(self, string, context, base_url=None)
+
+ Return a parsable string as input document.
+
+ Pass data string and context as parameters. You can pass the
+ source URL or filename through the ``base_url`` keyword
+ argument.
+ """
+ cdef _InputDocument doc_ref
+ if isinstance(string, unicode):
+ string = (<unicode>string).encode('utf8')
+ elif not isinstance(string, bytes):
+ raise TypeError, "argument must be a byte string or unicode string"
+ doc_ref = _InputDocument()
+ doc_ref._type = PARSER_DATA_STRING
+ doc_ref._data_bytes = string
+ if base_url is not None:
+ doc_ref._filename = _encodeFilename(base_url)
+ return doc_ref
+
+ def resolve_filename(self, filename, context):
+ """resolve_filename(self, filename, context)
+
+ Return the name of a parsable file as input document.
+
+ Pass filename and context as parameters. You can also pass a
+ URL with an HTTP, FTP or file target.
+ """
+ cdef _InputDocument doc_ref
+ doc_ref = _InputDocument()
+ doc_ref._type = PARSER_DATA_FILENAME
+ doc_ref._filename = _encodeFilename(filename)
+ return doc_ref
+
+ def resolve_file(self, f, context, *, base_url=None, bint close=True):
+ """resolve_file(self, f, context, base_url=None, close=True)
+
+ Return an open file-like object as input document.
+
+ Pass open file and context as parameters. You can pass the
+ base URL or filename of the file through the ``base_url``
+ keyword argument. If the ``close`` flag is True (the
+ default), the file will be closed after reading.
+
+ Note that using ``.resolve_filename()`` is more efficient,
+ especially in threaded environments.
+ """
+ cdef _InputDocument doc_ref
+ try:
+ f.read
+ except AttributeError:
+ raise TypeError, "Argument is not a file-like object"
+ doc_ref = _InputDocument()
+ doc_ref._type = PARSER_DATA_FILE
+ if base_url is not None:
+ doc_ref._filename = _encodeFilename(base_url)
+ else:
+ doc_ref._filename = _getFilenameForFile(f)
+ doc_ref._close_file = close
+ doc_ref._file = f
+ return doc_ref
+
+@cython.final
+@cython.internal
+cdef class _ResolverRegistry:
+ cdef object _resolvers
+ cdef Resolver _default_resolver
+ def __cinit__(self, Resolver default_resolver=None):
+ self._resolvers = set()
+ self._default_resolver = default_resolver
+
+ def add(self, Resolver resolver not None):
+ """add(self, resolver)
+
+ Register a resolver.
+
+ For each requested entity, the 'resolve' method of the resolver will
+ be called and the result will be passed to the parser. If this method
+ returns None, the request will be delegated to other resolvers or the
+ default resolver. The resolvers will be tested in an arbitrary order
+ until the first match is found.
+ """
+ self._resolvers.add(resolver)
+
+ def remove(self, resolver):
+ "remove(self, resolver)"
+ self._resolvers.discard(resolver)
+
+ cdef _ResolverRegistry _copy(self):
+ cdef _ResolverRegistry registry
+ registry = _ResolverRegistry(self._default_resolver)
+ registry._resolvers = self._resolvers.copy()
+ return registry
+
+ def copy(self):
+ "copy(self)"
+ return self._copy()
+
+ def resolve(self, system_url, public_id, context):
+ "resolve(self, system_url, public_id, context)"
+ for resolver in self._resolvers:
+ result = resolver.resolve(system_url, public_id, context)
+ if result is not None:
+ return result
+ if self._default_resolver is None:
+ return None
+ return self._default_resolver.resolve(system_url, public_id, context)
+
+ def __repr__(self):
+ return repr(self._resolvers)
+
+
+@cython.internal
+cdef class _ResolverContext(_ExceptionContext):
+ cdef _ResolverRegistry _resolvers
+ cdef _TempStore _storage
+
+ cdef int clear(self) except -1:
+ _ExceptionContext.clear(self)
+ self._storage.clear()
+ return 0
+
+
+cdef _initResolverContext(_ResolverContext context,
+ _ResolverRegistry resolvers):
+ if resolvers is None:
+ context._resolvers = _ResolverRegistry()
+ else:
+ context._resolvers = resolvers
+ context._storage = _TempStore()