about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/lxml/relaxng.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/relaxng.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/relaxng.pxi')
-rw-r--r--.venv/lib/python3.12/site-packages/lxml/relaxng.pxi165
1 files changed, 165 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/lxml/relaxng.pxi b/.venv/lib/python3.12/site-packages/lxml/relaxng.pxi
new file mode 100644
index 00000000..35f87589
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/lxml/relaxng.pxi
@@ -0,0 +1,165 @@
+# support for RelaxNG validation
+from lxml.includes cimport relaxng
+
+cdef object _rnc2rng
+try:
+    import rnc2rng as _rnc2rng
+except ImportError:
+    _rnc2rng = None
+
+
+cdef int _require_rnc2rng() except -1:
+    if _rnc2rng is None:
+        raise RelaxNGParseError(
+            'compact syntax not supported (please install rnc2rng)')
+    return 0
+
+
+cdef class RelaxNGError(LxmlError):
+    """Base class for RelaxNG errors.
+    """
+
+cdef class RelaxNGParseError(RelaxNGError):
+    """Error while parsing an XML document as RelaxNG.
+    """
+
+cdef class RelaxNGValidateError(RelaxNGError):
+    """Error while validating an XML document with a RelaxNG schema.
+    """
+
+
+################################################################################
+# RelaxNG
+
+cdef class RelaxNG(_Validator):
+    """RelaxNG(self, etree=None, file=None)
+    Turn a document into a Relax NG validator.
+
+    Either pass a schema as Element or ElementTree, or pass a file or
+    filename through the ``file`` keyword argument.
+    """
+    cdef relaxng.xmlRelaxNG* _c_schema
+    def __cinit__(self):
+        self._c_schema = NULL
+
+    def __init__(self, etree=None, *, file=None):
+        cdef _Document doc
+        cdef _Element root_node
+        cdef xmlDoc* fake_c_doc = NULL
+        cdef relaxng.xmlRelaxNGParserCtxt* parser_ctxt = NULL
+        _Validator.__init__(self)
+        if etree is not None:
+            doc = _documentOrRaise(etree)
+            root_node = _rootNodeOrRaise(etree)
+            fake_c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
+            parser_ctxt = relaxng.xmlRelaxNGNewDocParserCtxt(fake_c_doc)
+        elif file is not None:
+            if _isString(file):
+                if file[-4:].lower() == '.rnc':
+                    _require_rnc2rng()
+                    rng_data_utf8 = _utf8(_rnc2rng.dumps(_rnc2rng.load(file)))
+                    doc = _parseMemoryDocument(rng_data_utf8, parser=None, url=file)
+                    parser_ctxt = relaxng.xmlRelaxNGNewDocParserCtxt(doc._c_doc)
+                else:
+                    doc = None
+                    filename = _encodeFilename(file)
+                    with self._error_log:
+                        orig_loader = _register_document_loader()
+                        parser_ctxt = relaxng.xmlRelaxNGNewParserCtxt(_cstr(filename))
+                        _reset_document_loader(orig_loader)
+            elif (_getFilenameForFile(file) or '')[-4:].lower() == '.rnc':
+                _require_rnc2rng()
+                rng_data_utf8 = _utf8(_rnc2rng.dumps(_rnc2rng.load(file)))
+                doc = _parseMemoryDocument(
+                    rng_data_utf8, parser=None, url=_getFilenameForFile(file))
+                parser_ctxt = relaxng.xmlRelaxNGNewDocParserCtxt(doc._c_doc)
+            else:
+                doc = _parseDocument(file, parser=None, base_url=None)
+                parser_ctxt = relaxng.xmlRelaxNGNewDocParserCtxt(doc._c_doc)
+        else:
+            raise RelaxNGParseError, "No tree or file given"
+
+        if parser_ctxt is NULL:
+            if fake_c_doc is not NULL:
+                _destroyFakeDoc(doc._c_doc, fake_c_doc)
+            raise RelaxNGParseError(
+                self._error_log._buildExceptionMessage(
+                    "Document is not parsable as Relax NG"),
+                self._error_log)
+
+        # Need a cast here because older libxml2 releases do not use 'const' in the functype.
+        relaxng.xmlRelaxNGSetParserStructuredErrors(
+            parser_ctxt, <xmlerror.xmlStructuredErrorFunc> _receiveError, <void*>self._error_log)
+        _connectGenericErrorLog(self._error_log, xmlerror.XML_FROM_RELAXNGP)
+        self._c_schema = relaxng.xmlRelaxNGParse(parser_ctxt)
+        _connectGenericErrorLog(None)
+
+        relaxng.xmlRelaxNGFreeParserCtxt(parser_ctxt)
+        if self._c_schema is NULL:
+            if fake_c_doc is not NULL:
+                _destroyFakeDoc(doc._c_doc, fake_c_doc)
+            raise RelaxNGParseError(
+                self._error_log._buildExceptionMessage(
+                    "Document is not valid Relax NG"),
+                self._error_log)
+        if fake_c_doc is not NULL:
+            _destroyFakeDoc(doc._c_doc, fake_c_doc)
+
+    def __dealloc__(self):
+        relaxng.xmlRelaxNGFree(self._c_schema)
+
+    def __call__(self, etree):
+        """__call__(self, etree)
+
+        Validate doc using Relax NG.
+
+        Returns true if document is valid, false if not."""
+        cdef _Document doc
+        cdef _Element root_node
+        cdef xmlDoc* c_doc
+        cdef relaxng.xmlRelaxNGValidCtxt* valid_ctxt
+        cdef int ret
+
+        assert self._c_schema is not NULL, "RelaxNG instance not initialised"
+        doc = _documentOrRaise(etree)
+        root_node = _rootNodeOrRaise(etree)
+
+        valid_ctxt = relaxng.xmlRelaxNGNewValidCtxt(self._c_schema)
+        if valid_ctxt is NULL:
+            raise MemoryError()
+
+        try:
+            self._error_log.clear()
+            # Need a cast here because older libxml2 releases do not use 'const' in the functype.
+            relaxng.xmlRelaxNGSetValidStructuredErrors(
+                valid_ctxt, <xmlerror.xmlStructuredErrorFunc> _receiveError, <void*>self._error_log)
+            _connectGenericErrorLog(self._error_log, xmlerror.XML_FROM_RELAXNGV)
+            c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
+            with nogil:
+                ret = relaxng.xmlRelaxNGValidateDoc(valid_ctxt, c_doc)
+            _destroyFakeDoc(doc._c_doc, c_doc)
+        finally:
+            _connectGenericErrorLog(None)
+            relaxng.xmlRelaxNGFreeValidCtxt(valid_ctxt)
+
+        if ret == -1:
+            raise RelaxNGValidateError(
+                "Internal error in Relax NG validation",
+                self._error_log)
+        if ret == 0:
+            return True
+        else:
+            return False
+
+    @classmethod
+    def from_rnc_string(cls, src, base_url=None):
+        """Parse a RelaxNG schema in compact syntax from a text string
+
+        Requires the rnc2rng package to be installed.
+
+        Passing the source URL or file path of the source as 'base_url'
+        will enable resolving resource references relative to the source.
+        """
+        _require_rnc2rng()
+        rng_str = utf8(_rnc2rng.dumps(_rnc2rng.loads(src)))
+        return cls(_parseMemoryDocument(rng_str, parser=None, url=base_url))