about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi')
-rw-r--r--.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi281
1 files changed, 281 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi b/.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi
new file mode 100644
index 00000000..a3c86f0e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/lxml/nsclasses.pxi
@@ -0,0 +1,281 @@
+# module-level API for namespace implementations
+
+cdef class LxmlRegistryError(LxmlError):
+    """Base class of lxml registry errors.
+    """
+
+cdef class NamespaceRegistryError(LxmlRegistryError):
+    """Error registering a namespace extension.
+    """
+
+
+@cython.internal
+cdef class _NamespaceRegistry:
+    "Dictionary-like namespace registry"
+    cdef object _ns_uri
+    cdef bytes _ns_uri_utf
+    cdef dict _entries
+    cdef char* _c_ns_uri_utf
+    def __cinit__(self, ns_uri):
+        self._ns_uri = ns_uri
+        if ns_uri is None:
+            self._ns_uri_utf = None
+            self._c_ns_uri_utf = NULL
+        else:
+            self._ns_uri_utf = _utf8(ns_uri)
+            self._c_ns_uri_utf = _cstr(self._ns_uri_utf)
+        self._entries = {}
+
+    def update(self, class_dict_iterable):
+        """update(self, class_dict_iterable)
+
+        Forgivingly update the registry.
+
+        ``class_dict_iterable`` may be a dict or some other iterable
+        that yields (name, value) pairs.
+
+        If a value does not match the required type for this registry,
+        or if the name starts with '_', it will be silently discarded.
+        This allows registrations at the module or class level using
+        vars(), globals() etc."""
+        if hasattr(class_dict_iterable, 'items'):
+            class_dict_iterable = class_dict_iterable.items()
+        for name, item in class_dict_iterable:
+            if (name is None or name[:1] != '_') and callable(item):
+                self[name] = item
+
+    def __getitem__(self, name):
+        if name is not None:
+            name = _utf8(name)
+        return self._get(name)
+
+    def __delitem__(self, name):
+        if name is not None:
+            name = _utf8(name)
+        del self._entries[name]
+
+    cdef object _get(self, object name):
+        cdef python.PyObject* dict_result
+        dict_result = python.PyDict_GetItem(self._entries, name)
+        if dict_result is NULL:
+            raise KeyError, "Name not registered."
+        return <object>dict_result
+
+    cdef object _getForString(self, char* name):
+        cdef python.PyObject* dict_result
+        dict_result = python.PyDict_GetItem(self._entries, name)
+        if dict_result is NULL:
+            raise KeyError, "Name not registered."
+        return <object>dict_result
+
+    def __iter__(self):
+        return iter(self._entries)
+
+    def items(self):
+        return list(self._entries.items())
+
+    def iteritems(self):
+        return iter(self._entries.items())
+
+    def clear(self):
+        self._entries.clear()
+
+    def __call__(self, obj):
+        # Usage as decorator:
+        #   ns = lookup.get_namespace("...")
+        #   @ns('abc')
+        #   class element(ElementBase): pass
+        #
+        #   @ns
+        #   class elementname(ElementBase): pass
+
+        if obj is None or python._isString(obj):
+            # @ns(None) or @ns('tag')
+            return partial(self.__deco, obj)
+        # plain @ns decorator
+        self[obj.__name__] = obj
+        return obj
+
+    def __deco(self, name, obj):
+        self[name] = obj
+        return obj
+
+
+@cython.final
+@cython.internal
+cdef class _ClassNamespaceRegistry(_NamespaceRegistry):
+    "Dictionary-like registry for namespace implementation classes"
+    def __setitem__(self, name, item):
+        if not isinstance(item, type) or not issubclass(item, ElementBase):
+            raise NamespaceRegistryError, \
+                "Registered element classes must be subtypes of ElementBase"
+        if name is not None:
+            name = _utf8(name)
+        self._entries[name] = item
+
+    def __repr__(self):
+        return "Namespace(%r)" % self._ns_uri
+
+
+cdef class ElementNamespaceClassLookup(FallbackElementClassLookup):
+    """ElementNamespaceClassLookup(self, fallback=None)
+
+    Element class lookup scheme that searches the Element class in the
+    Namespace registry.
+
+    Usage:
+
+    >>> lookup = ElementNamespaceClassLookup()
+    >>> ns_elements = lookup.get_namespace("http://schema.org/Movie")
+
+    >>> @ns_elements
+    ... class movie(ElementBase):
+    ...     "Element implementation for 'movie' tag (using class name) in schema namespace."
+
+    >>> @ns_elements("movie")
+    ... class MovieElement(ElementBase):
+    ...     "Element implementation for 'movie' tag (explicit tag name) in schema namespace."
+    """
+    cdef dict _namespace_registries
+    def __cinit__(self):
+        self._namespace_registries = {}
+
+    def __init__(self, ElementClassLookup fallback=None):
+        FallbackElementClassLookup.__init__(self, fallback)
+        self._lookup_function = _find_nselement_class
+
+    def get_namespace(self, ns_uri):
+        """get_namespace(self, ns_uri)
+
+        Retrieve the namespace object associated with the given URI.
+        Pass None for the empty namespace.
+
+        Creates a new namespace object if it does not yet exist."""
+        if ns_uri:
+            ns_utf = _utf8(ns_uri)
+        else:
+            ns_utf = None
+        try:
+            return self._namespace_registries[ns_utf]
+        except KeyError:
+            registry = self._namespace_registries[ns_utf] = \
+                       _ClassNamespaceRegistry(ns_uri)
+            return registry
+
+cdef object _find_nselement_class(state, _Document doc, xmlNode* c_node):
+    cdef python.PyObject* dict_result
+    cdef ElementNamespaceClassLookup lookup
+    cdef _NamespaceRegistry registry
+    if state is None:
+        return _lookupDefaultElementClass(None, doc, c_node)
+
+    lookup = <ElementNamespaceClassLookup>state
+    if c_node.type != tree.XML_ELEMENT_NODE:
+        return _callLookupFallback(lookup, doc, c_node)
+
+    c_namespace_utf = _getNs(c_node)
+    if c_namespace_utf is not NULL:
+        dict_result = python.PyDict_GetItem(
+            lookup._namespace_registries, <unsigned char*>c_namespace_utf)
+    else:
+        dict_result = python.PyDict_GetItem(
+            lookup._namespace_registries, None)
+    if dict_result is not NULL:
+        registry = <_NamespaceRegistry>dict_result
+        classes = registry._entries
+
+        if c_node.name is not NULL:
+            dict_result = python.PyDict_GetItem(
+                classes, <unsigned char*>c_node.name)
+        else:
+            dict_result = NULL
+
+        if dict_result is NULL:
+            dict_result = python.PyDict_GetItem(classes, None)
+
+        if dict_result is not NULL:
+            return <object>dict_result
+    return _callLookupFallback(lookup, doc, c_node)
+
+
+################################################################################
+# XPath extension functions
+
+cdef dict __FUNCTION_NAMESPACE_REGISTRIES
+__FUNCTION_NAMESPACE_REGISTRIES = {}
+
+def FunctionNamespace(ns_uri):
+    """FunctionNamespace(ns_uri)
+
+    Retrieve the function namespace object associated with the given
+    URI.
+
+    Creates a new one if it does not yet exist. A function namespace
+    can only be used to register extension functions.
+
+    Usage:
+
+    >>> ns_functions = FunctionNamespace("http://schema.org/Movie")
+
+    >>> @ns_functions  # uses function name
+    ... def add2(x):
+    ...     return x + 2
+
+    >>> @ns_functions("add3")  # uses explicit name
+    ... def add_three(x):
+    ...     return x + 3
+    """
+    ns_utf = _utf8(ns_uri) if ns_uri else None
+    try:
+        return __FUNCTION_NAMESPACE_REGISTRIES[ns_utf]
+    except KeyError:
+        registry = __FUNCTION_NAMESPACE_REGISTRIES[ns_utf] = \
+                   _XPathFunctionNamespaceRegistry(ns_uri)
+        return registry
+
+@cython.internal
+cdef class _FunctionNamespaceRegistry(_NamespaceRegistry):
+    def __setitem__(self, name, item):
+        if not callable(item):
+            raise NamespaceRegistryError, \
+                "Registered functions must be callable."
+        if not name:
+            raise ValueError, \
+                "extensions must have non empty names"
+        self._entries[_utf8(name)] = item
+
+    def __repr__(self):
+        return "FunctionNamespace(%r)" % self._ns_uri
+
+@cython.final
+@cython.internal
+cdef class _XPathFunctionNamespaceRegistry(_FunctionNamespaceRegistry):
+    cdef object _prefix
+    cdef bytes _prefix_utf
+
+    property prefix:
+        "Namespace prefix for extension functions."
+        def __del__(self):
+            self._prefix = None # no prefix configured
+            self._prefix_utf = None
+        def __get__(self):
+            if self._prefix is None:
+                return ''
+            else:
+                return self._prefix
+        def __set__(self, prefix):
+            if prefix == '':
+                prefix = None # empty prefix
+            self._prefix_utf = _utf8(prefix) if prefix is not None else None
+            self._prefix = prefix
+
+cdef list _find_all_extension_prefixes():
+    "Internal lookup function to find all function prefixes for XSLT/XPath."
+    cdef _XPathFunctionNamespaceRegistry registry
+    cdef list ns_prefixes = []
+    for registry in __FUNCTION_NAMESPACE_REGISTRIES.itervalues():
+        if registry._prefix_utf is not None:
+            if registry._ns_uri_utf is not None:
+                ns_prefixes.append(
+                    (registry._prefix_utf, registry._ns_uri_utf))
+    return ns_prefixes