summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorscoder <none@none>2008-01-24 15:11:57 +0100
committerscoder <none@none>2008-01-24 15:11:57 +0100
commit06c7c27876f5f1721e668744f65913ef1b309694 (patch)
tree63427811a2df12bbc25bbe2364a916ba4d9a8a52 /src
parent17a2a31d68de1d356473f9d0e2ed1eb1728eadcb (diff)
downloadpython-lxml-06c7c27876f5f1721e668744f65913ef1b309694.tar.gz
[svn r3195] r3303@delle: sbehnel | 2008-01-24 15:11:15 +0100
exception cleanup, let them carry local error logs where possible --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/lxml/apihelpers.pxi26
-rw-r--r--src/lxml/classlookup.pxi8
-rw-r--r--src/lxml/docloader.pxi2
-rw-r--r--src/lxml/dtd.pxi10
-rw-r--r--src/lxml/extensions.pxi42
-rw-r--r--src/lxml/iterparse.pxi4
-rw-r--r--src/lxml/lxml.etree.pyx83
-rw-r--r--src/lxml/lxml.objectify.pyx42
-rw-r--r--src/lxml/lxml.pyclasslookup.pyx2
-rw-r--r--src/lxml/nsclasses.pxi16
-rw-r--r--src/lxml/objectpath.pxi32
-rw-r--r--src/lxml/parser.pxi23
-rw-r--r--src/lxml/relaxng.pxi15
-rw-r--r--src/lxml/schematron.pxi14
-rw-r--r--src/lxml/serializer.pxi28
-rw-r--r--src/lxml/tests/test_xpathevaluator.py2
-rw-r--r--src/lxml/xinclude.pxi45
-rw-r--r--src/lxml/xmlid.pxi6
-rw-r--r--src/lxml/xmlschema.pxi9
-rw-r--r--src/lxml/xpath.pxi16
-rw-r--r--src/lxml/xslt.pxi29
21 files changed, 251 insertions, 203 deletions
diff --git a/src/lxml/apihelpers.pxi b/src/lxml/apihelpers.pxi
index f12c72c3..df21fc19 100644
--- a/src/lxml/apihelpers.pxi
+++ b/src/lxml/apihelpers.pxi
@@ -26,9 +26,9 @@ cdef _Document _documentOrRaise(object input):
elif isinstance(input, _Document):
doc = <_Document>input
else:
- raise TypeError, "Invalid input object: %s" % type(input)
+ raise TypeError("Invalid input object: %s" % type(input))
if doc is None:
- raise ValueError, "Input object has no document: %s" % type(input)
+ raise ValueError("Input object has no document: %s" % type(input))
else:
return doc
@@ -46,9 +46,9 @@ cdef _Element _rootNodeOrRaise(object input):
elif isinstance(input, _Document):
node = (<_Document>input).getroot()
else:
- raise TypeError, "Invalid input object: %s" % type(input)
+ raise TypeError("Invalid input object: %s" % type(input))
if node is None:
- raise ValueError, "Input object has no element: %s" % type(input)
+ raise ValueError("Input object has no element: %s" % type(input))
else:
return node
@@ -153,7 +153,7 @@ cdef _Element _makeSubElement(_Element parent, tag, text, tail,
c_node = _createElement(c_doc, name_utf)
if c_node is NULL:
- python.PyErr_NoMemory()
+ return python.PyErr_NoMemory()
tree.xmlAddChild(parent._c_node, c_node)
if text is not None:
@@ -173,7 +173,7 @@ cdef _initNodeAttributes(xmlNode* c_node, _Document doc, attrib, extra):
cdef xmlNs* c_ns
# 'extra' is not checked here (expected to be a keyword dict)
if attrib is not None and not hasattr(attrib, 'items'):
- raise TypeError, "Invalid attribute dictionary: %s" % type(attrib)
+ raise TypeError("Invalid attribute dictionary: %s" % type(attrib))
if extra is not None and extra:
if attrib is None:
attrib = extra
@@ -264,7 +264,7 @@ cdef int _delAttribute(_Element element, key) except -1:
else:
c_href = _cstr(ns)
if _delAttributeFromNsName(element._c_node, c_href, _cstr(tag)):
- raise KeyError, key
+ raise KeyError(key)
return 0
cdef int _delAttributeFromNsName(xmlNode* c_node, char* c_href, char* c_name):
@@ -944,7 +944,7 @@ cdef object _utf8(object s):
assert isutf8py(s) != -1, \
"All strings must be XML compatible, either Unicode or ASCII"
else:
- raise TypeError, "Argument must be string or unicode."
+ raise TypeError("Argument must be string or unicode.")
return s
cdef object _encodeFilename(object filename):
@@ -956,7 +956,7 @@ cdef object _encodeFilename(object filename):
return python.PyUnicode_AsEncodedString(
filename, _C_FILENAME_ENCODING, NULL)
else:
- raise TypeError, "Argument must be string or unicode."
+ raise TypeError("Argument must be string or unicode.")
cdef object _encodeFilenameUTF8(object filename):
"""Recode filename as UTF-8. Tries ASCII, local filesystem encoding and
@@ -985,7 +985,7 @@ cdef object _encodeFilenameUTF8(object filename):
if python.PyUnicode_Check(filename):
return python.PyUnicode_AsUTF8String(filename)
else:
- raise TypeError, "Argument must be string or unicode."
+ raise TypeError("Argument must be string or unicode.")
cdef _getNsTag(tag):
"""Given a tag, find namespace URI and tag name.
@@ -1003,16 +1003,16 @@ cdef _getNsTag(tag):
c_tag = c_tag + 1
c_ns_end = cstd.strchr(c_tag, c'}')
if c_ns_end is NULL:
- raise ValueError, "Invalid tag name"
+ raise ValueError("Invalid tag name")
nslen = c_ns_end - c_tag
taglen = python.PyString_GET_SIZE(tag) - nslen - 2
if taglen == 0:
- raise ValueError, "Empty tag name"
+ raise ValueError("Empty tag name")
if nslen > 0:
ns = python.PyString_FromStringAndSize(c_tag, nslen)
tag = python.PyString_FromStringAndSize(c_ns_end+1, taglen)
elif python.PyString_GET_SIZE(tag) == 0:
- raise ValueError, "Empty tag name"
+ raise ValueError("Empty tag name")
return ns, tag
cdef int _pyXmlNameIsValid(name_utf8):
diff --git a/src/lxml/classlookup.pxi b/src/lxml/classlookup.pxi
index 2da0dd87..d2c50914 100644
--- a/src/lxml/classlookup.pxi
+++ b/src/lxml/classlookup.pxi
@@ -106,28 +106,28 @@ cdef class ElementDefaultClassLookup(ElementClassLookup):
elif issubclass(element, ElementBase):
self.element_class = element
else:
- raise TypeError, "element class must be subclass of ElementBase"
+ raise TypeError("element class must be subclass of ElementBase")
if comment is None:
self.comment_class = _Comment
elif issubclass(comment, CommentBase):
self.comment_class = comment
else:
- raise TypeError, "comment class must be subclass of CommentBase"
+ raise TypeError("comment class must be subclass of CommentBase")
if entity is None:
self.entity_class = _Entity
elif issubclass(entity, EntityBase):
self.entity_class = entity
else:
- raise TypeError, "Entity class must be subclass of EntityBase"
+ raise TypeError("Entity class must be subclass of EntityBase")
if pi is None:
self.pi_class = None # special case, see below
elif issubclass(pi, PIBase):
self.pi_class = pi
else:
- raise TypeError, "PI class must be subclass of PIBase"
+ raise TypeError("PI class must be subclass of PIBase")
cdef object _lookupDefaultElementClass(state, _Document _doc, xmlNode* c_node):
"Trivial class lookup function that always returns the default class."
diff --git a/src/lxml/docloader.pxi b/src/lxml/docloader.pxi
index adf0e9fb..3835ecd7 100644
--- a/src/lxml/docloader.pxi
+++ b/src/lxml/docloader.pxi
@@ -68,7 +68,7 @@ cdef class Resolver:
try:
f.read
except AttributeError:
- raise TypeError, "Argument is not a file-like object"
+ raise TypeError("Argument is not a file-like object")
doc_ref = _InputDocument()
doc_ref._type = PARSER_DATA_FILE
doc_ref._filename = _getFilenameForFile(f)
diff --git a/src/lxml/dtd.pxi b/src/lxml/dtd.pxi
index e2b16719..f7c3c810 100644
--- a/src/lxml/dtd.pxi
+++ b/src/lxml/dtd.pxi
@@ -49,7 +49,7 @@ cdef class DTD(_Validator):
if self._c_dtd is NULL:
raise DTDParseError(
self._error_log._buildExceptionMessage("error parsing DTD"),
- error_log=self._error_log)
+ self._error_log)
def __dealloc__(self):
tree.xmlFreeDtd(self._c_dtd)
@@ -72,7 +72,8 @@ cdef class DTD(_Validator):
valid_ctxt = dtdvalid.xmlNewValidCtxt()
if valid_ctxt is NULL:
self._error_log.disconnect()
- raise DTDError, "Failed to create validation context"
+ raise DTDError("Failed to create validation context",
+ self._error_log)
c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
with nogil:
@@ -83,7 +84,8 @@ cdef class DTD(_Validator):
self._error_log.disconnect()
if ret == -1:
- raise DTDValidateError("Internal error in DTD validation")
+ raise DTDValidateError("Internal error in DTD validation",
+ self._error_log)
if ret == 1:
return True
else:
@@ -105,7 +107,7 @@ cdef tree.xmlDtd* _parseDtdFromFilelike(file) except NULL:
exc_context._raise_if_stored()
if c_dtd is NULL:
- raise DTDParseError("error parsing DTD", error_log=error_log)
+ raise DTDParseError("error parsing DTD", error_log)
return c_dtd
cdef extern from "etree_defs.h":
diff --git a/src/lxml/extensions.pxi b/src/lxml/extensions.pxi
index b5dd2926..501bd42c 100644
--- a/src/lxml/extensions.pxi
+++ b/src/lxml/extensions.pxi
@@ -57,8 +57,8 @@ cdef class _BaseContext:
for extension in extensions:
for (ns_uri, name), function in extension.items():
if name is None:
- raise ValueError, \
- "extensions must have non empty names"
+ raise ValueError(
+ "extensions must have non empty names")
ns_utf = self._to_utf(ns_uri)
name_utf = self._to_utf(name)
python.PyDict_SetItem(
@@ -72,11 +72,11 @@ cdef class _BaseContext:
ns = []
for prefix, ns_uri in namespaces:
if prefix is None or not prefix:
- raise TypeError, \
- "empty namespace prefix is not supported in XPath"
+ raise TypeError(
+ "empty namespace prefix is not supported in XPath")
if ns_uri is None or not ns_uri:
- raise TypeError, \
- "setting default namespace is not supported in XPath"
+ raise TypeError(
+ "setting default namespace is not supported in XPath")
prefix_utf = self._to_utf(prefix)
ns_uri_utf = self._to_utf(ns_uri)
python.PyList_Append(ns, (prefix_utf, ns_uri_utf))
@@ -139,7 +139,7 @@ cdef class _BaseContext:
cdef addNamespace(self, prefix, ns_uri):
if prefix is None:
- raise TypeError, "empty prefix is not supported in XPath"
+ raise TypeError("empty prefix is not supported in XPath")
prefix_utf = self._to_utf(prefix)
ns_uri_utf = self._to_utf(ns_uri)
new_item = (prefix_utf, ns_uri_utf)
@@ -161,7 +161,7 @@ cdef class _BaseContext:
cdef registerNamespace(self, prefix, ns_uri):
if prefix is None:
- raise TypeError, "empty prefix is not supported in XPath"
+ raise TypeError("empty prefix is not supported in XPath")
prefix_utf = self._to_utf(prefix)
ns_uri_utf = self._to_utf(ns_uri)
python.PyList_Append(self._global_namespaces, prefix_utf)
@@ -279,17 +279,17 @@ cdef class _BaseContext:
def __get__(self):
cdef xmlNode* c_node
if self._xpathCtxt is NULL:
- raise XPathError, \
- "XPath context is only usable during the evaluation"
+ raise XPathError(
+ "XPath context is only usable during the evaluation")
c_node = self._xpathCtxt.node
if c_node is NULL:
- raise XPathError, "no context node"
+ raise XPathError("no context node")
if c_node.doc != self._xpathCtxt.doc:
- raise XPathError, \
- "document-external context nodes are not supported"
+ raise XPathError(
+ "document-external context nodes are not supported")
if self._doc is None:
- raise XPathError, \
- "document context is missing"
+ raise XPathError(
+ "document context is missing")
return _elementFactory(self._doc, c_node)
property eval_context:
@@ -475,15 +475,15 @@ cdef xpath.xmlXPathObject* _wrapXPathObject(object obj) except NULL:
xpath.xmlXPathNodeSetAdd(resultSet, node._c_node)
else:
xpath.xmlXPathFreeNodeSet(resultSet)
- raise XPathResultError, "This is not a node: %s" % element
+ raise XPathResultError("This is not a node: %r" % element)
else:
- raise XPathResultError, "Unknown return type: %s" % type(obj)
+ raise XPathResultError("Unknown return type: %s" % type(obj))
return xpath.xmlXPathWrapNodeSet(resultSet)
cdef object _unwrapXPathObject(xpath.xmlXPathObject* xpathObj,
_Document doc):
if xpathObj.type == xpath.XPATH_UNDEFINED:
- raise XPathResultError, "Undefined xpath result"
+ raise XPathResultError("Undefined xpath result")
elif xpathObj.type == xpath.XPATH_NODESET:
return _createNodeSetResult(xpathObj, doc)
elif xpathObj.type == xpath.XPATH_BOOLEAN:
@@ -503,7 +503,7 @@ cdef object _unwrapXPathObject(xpath.xmlXPathObject* xpathObj,
elif xpathObj.type == xpath.XPATH_XSLT_TREE:
raise NotImplementedError
else:
- raise XPathResultError, "Unknown xpath result %s" % str(xpathObj.type)
+ raise XPathResultError("Unknown xpath result %s" % str(xpathObj.type))
cdef object _createNodeSetResult(xpath.xmlXPathObject* xpathObj, _Document doc):
cdef xmlNode* c_node
@@ -543,8 +543,8 @@ cdef object _createNodeSetResult(xpath.xmlXPathObject* xpathObj, _Document doc):
c_node.type == tree.XML_XINCLUDE_END:
continue
else:
- raise NotImplementedError, \
- "Not yet implemented result node type: %d" % c_node.type
+ raise NotImplementedError(
+ "Not yet implemented result node type: %d" % c_node.type)
python.PyList_Append(result, value)
return result
diff --git a/src/lxml/iterparse.pxi b/src/lxml/iterparse.pxi
index 22cb3aae..036aa162 100644
--- a/src/lxml/iterparse.pxi
+++ b/src/lxml/iterparse.pxi
@@ -340,7 +340,7 @@ cdef class iterparse(_BaseParser):
return _IterparseContext()
def copy(self):
- raise TypeError, "iterparse parsers cannot be copied"
+ raise TypeError("iterparse parsers cannot be copied")
def __iter__(self):
return self
@@ -366,7 +366,7 @@ cdef class iterparse(_BaseParser):
data = self._source.read(__ITERPARSE_CHUNK_SIZE)
if not python.PyString_Check(data):
self._source = None
- raise TypeError, "reading file objects must return plain strings"
+ raise TypeError("reading file objects must return plain strings")
elif data:
if self._for_html:
error = htmlparser.htmlParseChunk(
diff --git a/src/lxml/lxml.etree.pyx b/src/lxml/lxml.etree.pyx
index 8e56f75c..f0b0edfd 100644
--- a/src/lxml/lxml.etree.pyx
+++ b/src/lxml/lxml.etree.pyx
@@ -2,7 +2,6 @@ cimport tree, python, config
from tree cimport xmlDoc, xmlNode, xmlAttr, xmlNs, _isElement, _getNs
from python cimport callable, _cstr, _isString
cimport xpath
-cimport xinclude
cimport c14n
cimport cstd
@@ -93,18 +92,17 @@ class LxmlError(Error):
"""Main exception base class for lxml. All other exceptions inherit from
this one.
"""
- def __init__(self, *args, error_log=None):
- _initError(self, *args)
+ def __init__(self, message, error_log=None):
+ _initError(self, message)
if error_log is None:
- self.error_log = __copyGlobalErrorLog()
- else:
- self.error_log = error_log.copy()
+ error_log = __copyGlobalErrorLog()
+ self.error_log = error_log.copy()
cdef object _LxmlError
_LxmlError = LxmlError
-def _superError(obj, *args):
- super(_LxmlError, obj).__init__(*args)
+def _superError(obj, message):
+ super(_LxmlError, obj).__init__(message)
cdef object _initError
if isinstance(_LxmlError, type):
@@ -121,11 +119,6 @@ class LxmlSyntaxError(LxmlError, SyntaxError):
"""
pass
-class XIncludeError(LxmlError):
- """Error during XInclude processing.
- """
- pass
-
class C14NError(LxmlError):
"""Error during C14N serialisation.
"""
@@ -447,7 +440,7 @@ cdef class DocInfo:
self._doc = _documentOrRaise(tree)
root_name, public_id, system_url = self._doc.getdoctype()
if not root_name and (public_id or system_url):
- raise ValueError, "Could not find root node"
+ raise ValueError("Could not find root node")
property root_name:
"Returns the name of the root node as defined by the DOCTYPE."
@@ -564,7 +557,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
element = value
c_node = _findChild(self._c_node, x)
if c_node is NULL:
- raise IndexError, "list index out of range"
+ raise IndexError("list index out of range")
c_next = element._c_node.next
_removeText(c_node.next)
tree.xmlReplaceNode(c_node, element._c_node)
@@ -719,7 +712,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
cdef xmlNode* c_next
c_node = element._c_node
if c_node.parent is not self._c_node:
- raise ValueError, "Element is not a child of this node."
+ raise ValueError("Element is not a child of this node.")
c_next = element._c_node.next
tree.xmlUnlinkNode(c_node)
_moveTail(c_next, c_node)
@@ -736,7 +729,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
cdef xmlNode* c_new_next
c_old_node = old_element._c_node
if c_old_node.parent is not self._c_node:
- raise ValueError, "Element is not a child of this node."
+ raise ValueError("Element is not a child of this node.")
c_old_next = c_old_node.next
c_new_node = new_element._c_node
c_new_next = c_new_node.next
@@ -893,7 +886,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
# indexing
c_node = _findChild(self._c_node, x)
if c_node is NULL:
- raise IndexError, "list index out of range"
+ raise IndexError("list index out of range")
return _elementFactory(self._doc, c_node)
def __len__(self):
@@ -935,7 +928,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
cdef xmlNode* c_start_node
c_child = x._c_node
if c_child.parent is not self._c_node:
- raise ValueError, "Element is not a child of this node."
+ raise ValueError("Element is not a child of this node.")
# handle the unbounded search straight away (normal case)
if stop is None and (start is None or start == 0):
@@ -958,7 +951,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
c_stop = stop
if c_stop == 0 or \
c_start >= c_stop and (c_stop > 0 or c_start < 0):
- raise ValueError, "list.index(x): x not in slice"
+ raise ValueError("list.index(x): x not in slice")
# for negative slice indices, check slice before searching index
if c_start < 0 or c_stop < 0:
@@ -976,9 +969,9 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
if c_start_node == c_child:
# found! before slice end?
if c_stop < 0 and l <= -c_stop:
- raise ValueError, "list.index(x): x not in slice"
+ raise ValueError("list.index(x): x not in slice")
elif c_start < 0:
- raise ValueError, "list.index(x): x not in slice"
+ raise ValueError("list.index(x): x not in slice")
# now determine the index backwards from child
c_child = c_child.prev
@@ -1003,9 +996,9 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
else:
return k
if c_start != 0 or c_stop != 0:
- raise ValueError, "list.index(x): x not in slice"
+ raise ValueError("list.index(x): x not in slice")
else:
- raise ValueError, "list.index(x): x not in list"
+ raise ValueError("list.index(x): x not in list")
def get(self, key, default=None):
"""Gets an element attribute.
@@ -1404,7 +1397,7 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
"""Relocate the ElementTree to a new root node.
"""
if root._c_node.type != tree.XML_ELEMENT_NODE:
- raise TypeError, "Only elements can be the root of an ElementTree"
+ raise TypeError("Only elements can be the root of an ElementTree")
self._context_node = root
self._doc = None
@@ -1476,12 +1469,12 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
cdef char* c_path
doc = self._context_node._doc
if element._doc is not doc:
- raise ValueError, "Element is not in this tree."
+ raise ValueError("Element is not in this tree.")
c_doc = _fakeRootDoc(doc._c_doc, self._context_node._c_node)
c_path = tree.xmlGetNodePath(element._c_node)
_destroyFakeDoc(doc._c_doc, c_doc)
if c_path is NULL:
- raise LxmlError, "Error creating node path."
+ python.PyErr_NoMemory()
path = c_path
tree.xmlFree(c_path)
return path
@@ -1641,23 +1634,7 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
"""
cdef int result
self._assertHasRoot()
- # We cannot pass the XML_PARSE_NOXINCNODE option as this would free
- # the XInclude nodes - there may still be Python references to them!
- # Therefore, we allow XInclude nodes to be converted to
- # XML_XINCLUDE_START nodes. XML_XINCLUDE_END nodes are added as
- # siblings. Tree traversal will simply ignore them as they are not
- # typed as elements. The included fragment is added between the two,
- # i.e. as a sibling, which does not conflict with traversal.
- with nogil:
- if self._context_node._doc._parser is not None:
- result = xinclude.xmlXIncludeProcessTreeFlags(
- self._context_node._c_node,
- self._context_node._doc._parser._parse_options)
- else:
- result = xinclude.xmlXIncludeProcessTree(
- self._context_node._c_node)
- if result == -1:
- raise XIncludeError, "XInclude processing failed"
+ XInclude()(self._context_node)
def write_c14n(self, file):
"""C14N write of document. Always writes UTF-8.
@@ -1700,12 +1677,12 @@ cdef class _Attrib:
def pop(self, key, *default):
if python.PyTuple_GET_SIZE(default) > 1:
- raise TypeError, "pop expected at most 2 arguments, got %d" % \
- (python.PyTuple_GET_SIZE(default)+1)
+ raise TypeError("pop expected at most 2 arguments, got %d" % (
+ python.PyTuple_GET_SIZE(default)+1))
result = _getAttributeValue(self._element, key, None)
if result is None:
if python.PyTuple_GET_SIZE(default) == 0:
- raise KeyError, key
+ raise KeyError(key)
else:
result = python.PyTuple_GET_ITEM(default, 0)
python.Py_INCREF(result)
@@ -1726,7 +1703,7 @@ cdef class _Attrib:
def __getitem__(self, key):
result = _getAttributeValue(self._element, key, None)
if result is None:
- raise KeyError, key
+ raise KeyError(key)
else:
return result
@@ -2286,7 +2263,8 @@ def tostring(element_or_tree, *, encoding=None, method="xml",
return _tostring((<_ElementTree>element_or_tree)._context_node,
encoding, method, write_declaration, 1, pretty_print)
else:
- raise TypeError, "Type '%s' cannot be serialized." % type(element_or_tree)
+ raise TypeError("Type '%s' cannot be serialized." %
+ type(element_or_tree))
def tostringlist(element_or_tree, *args, **kwargs):
"""Serialize an element to an encoded string representation of its XML
@@ -2316,7 +2294,8 @@ def tounicode(element_or_tree, *, method="xml", pretty_print=False):
return _tounicode((<_ElementTree>element_or_tree)._context_node,
method, 1, pretty_print)
else:
- raise TypeError, "Type '%s' cannot be serialized." % type(element_or_tree)
+ raise TypeError("Type '%s' cannot be serialized." %
+ type(element_or_tree))
def parse(source, _BaseParser parser=None):
"""Return an ElementTree object loaded with source elements. If no parser
@@ -2344,6 +2323,7 @@ include "parsertarget.pxi" # ET Parser target
include "serializer.pxi" # XML output functions
include "iterparse.pxi" # incremental XML parsing
include "xmlid.pxi" # XMLID and IDDict
+include "xinclude.pxi" # XInclude
include "extensions.pxi" # XPath/XSLT extension functions
include "xpath.pxi" # XPath evaluation
include "xslt.pxi" # XSL transformations
@@ -2374,7 +2354,8 @@ cdef class _Validator:
"Raises DocumentInvalid if the document does not comply with the schema."
if not self(etree):
raise DocumentInvalid(self._error_log._buildExceptionMessage(
- "Document does not comply with schema"))
+ "Document does not comply with schema"),
+ self._error_log)
def assert_(self, etree):
"Raises AssertionError if the document does not comply with the schema."
diff --git a/src/lxml/lxml.objectify.pyx b/src/lxml/lxml.objectify.pyx
index 24553519..d789fe20 100644
--- a/src/lxml/lxml.objectify.pyx
+++ b/src/lxml/lxml.objectify.pyx
@@ -196,8 +196,8 @@ cdef class ObjectifiedElement(ElementBase):
# properties are looked up /after/ __setattr__, so we must emulate them
if tag == 'text' or tag == 'pyval':
# read-only !
- raise TypeError, "attribute '%s' of '%s' objects is not writable"% \
- (tag, _typename(self))
+ raise TypeError("attribute '%s' of '%s' objects is not writable" %
+ (tag, _typename(self)))
elif tag == 'tail':
cetree.setTailText(self._c_node, value)
return
@@ -256,7 +256,7 @@ cdef class ObjectifiedElement(ElementBase):
if key == 0:
return self
else:
- raise IndexError, key
+ raise IndexError(key)
if key < 0:
c_node = c_parent.last
else:
@@ -264,7 +264,7 @@ cdef class ObjectifiedElement(ElementBase):
c_node = _findFollowingSibling(
c_node, tree._getNs(c_self_node), c_self_node.name, key)
if c_node is NULL:
- raise IndexError, key
+ raise IndexError(key)
return elementFactory(self._doc, c_node)
def __setitem__(self, key, value):
@@ -299,7 +299,7 @@ cdef class ObjectifiedElement(ElementBase):
c_parent = c_self_node.parent
if c_parent is NULL:
# the 'root[i] = ...' case
- raise TypeError, "assignment to root element is invalid"
+ raise TypeError("assignment to root element is invalid")
if python.PySlice_Check(key):
# slice assignment
@@ -338,7 +338,7 @@ cdef class ObjectifiedElement(ElementBase):
c_node = _findFollowingSibling(
c_node, tree._getNs(c_self_node), c_self_node.name, key)
if c_node is NULL:
- raise IndexError, key
+ raise IndexError(key)
element = elementFactory(self._doc, c_node)
_replaceElement(element, value)
@@ -351,7 +351,7 @@ cdef class ObjectifiedElement(ElementBase):
&start, &stop, &step, &slicelength)
parent = self.getparent()
if parent is None:
- raise TypeError, "deleting slices of root element not supported"
+ raise TypeError("deleting slices of root element not supported")
if step < 0:
del_items = list(self)[start:stop:step]
else:
@@ -363,7 +363,7 @@ cdef class ObjectifiedElement(ElementBase):
# normal index deletion
parent = self.getparent()
if parent is None:
- raise TypeError, "deleting items not supported by root element"
+ raise TypeError("deleting items not supported by root element")
sibling = self.__getitem__(key)
parent.remove(sibling)
@@ -466,8 +466,8 @@ cdef object _lookupChild(_Element parent, tag):
cdef object _lookupChildOrRaise(_Element parent, tag):
element = _lookupChild(parent, tag)
if element is None:
- raise AttributeError, "no such child: " + \
- _buildChildTag(parent, tag)
+ raise AttributeError("no such child: " +
+ _buildChildTag(parent, tag))
return element
cdef object _buildChildTag(_Element parent, tag):
@@ -712,7 +712,7 @@ cdef class StringElement(ObjectifiedDataElement):
elif isinstance(other, StringElement):
return _numericValueOf(self) * textOf((<StringElement>other)._c_node)
else:
- raise TypeError, "invalid types for * operator"
+ raise TypeError("invalid types for * operator")
def __mod__(self, other):
return _strValueOf(self) % other
@@ -756,7 +756,7 @@ cdef class BoolElement(ObjectifiedDataElement):
if c_str[1] == c'\0' or text == "true" or text.lower() == "true":
# '1' or 't' or 'true'
return 1
- raise ValueError, "Invalid boolean value: '%s'" % text
+ raise ValueError("Invalid boolean value: '%s'" % text)
def __nonzero__(self):
if self._boolval():
@@ -836,13 +836,13 @@ cdef class PyType:
cdef object _schema_types
def __init__(self, name, type_check, type_class, stringify=None):
if not python._isString(name):
- raise TypeError, "Type name must be a string"
+ raise TypeError("Type name must be a string")
if type_check is not None and not callable(type_check):
- raise TypeError, "Type check function must be callable (or None)"
+ raise TypeError("Type check function must be callable (or None)")
if name != TREE_PYTYPE_NAME and \
not issubclass(type_class, ObjectifiedDataElement):
- raise TypeError, \
- "Data classes must inherit from ObjectifiedDataElement"
+ raise TypeError(
+ "Data classes must inherit from ObjectifiedDataElement")
self.name = name
self._type = type_class
self.type_check = type_check
@@ -864,7 +864,7 @@ cdef class PyType:
ignored. Raises ValueError if the dependencies cannot be fulfilled.
"""
if self.name == TREE_PYTYPE_NAME:
- raise ValueError, "Cannot register tree type"
+ raise ValueError("Cannot register tree type")
if self.type_check is not None:
for item in _TYPE_CHECKS:
if item[0] is self.type_check:
@@ -886,7 +886,7 @@ cdef class PyType:
if last_pos == -1:
_TYPE_CHECKS.append(entry)
elif first_pos > last_pos:
- raise ValueError, "inconsistent before/after dependencies"
+ raise ValueError("inconsistent before/after dependencies")
else:
_TYPE_CHECKS.insert(last_pos, entry)
@@ -1620,7 +1620,7 @@ def set_default_parser(new_parser = None):
elif isinstance(new_parser, etree.XMLParser):
objectify_parser = new_parser
else:
- raise TypeError, "parser must inherit from lxml.etree.XMLParser"
+ raise TypeError("parser must inherit from lxml.etree.XMLParser")
cdef _Element _makeElement(tag, text, attrib, nsmap):
return cetree.makeElement(tag, None, objectify_parser, text, None, attrib, nsmap)
@@ -1734,7 +1734,7 @@ def DataElement(_value, attrib=None, nsmap=None, *, _pytype=None, _xsi=None,
prefix, name = _xsi.split(':', 1)
ns = nsmap.get(prefix)
if ns != XML_SCHEMA_NS:
- raise ValueError, "XSD types require the XSD namespace"
+ raise ValueError("XSD types require the XSD namespace")
elif nsmap is _DEFAULT_NSMAP:
name = _xsi
_xsi = 'xsd:' + _xsi
@@ -1746,7 +1746,7 @@ def DataElement(_value, attrib=None, nsmap=None, *, _pytype=None, _xsi=None,
_xsi = prefix + ':' + _xsi
break
else:
- raise ValueError, "XSD types require the XSD namespace"
+ raise ValueError("XSD types require the XSD namespace")
python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_TYPE_ATTR, _xsi)
if _pytype is None:
# allow using unregistered or even wrong xsi:type names
diff --git a/src/lxml/lxml.pyclasslookup.pyx b/src/lxml/lxml.pyclasslookup.pyx
index b9f47fa9..f849c09c 100644
--- a/src/lxml/lxml.pyclasslookup.pyx
+++ b/src/lxml/lxml.pyclasslookup.pyx
@@ -87,7 +87,7 @@ cdef class _ElementProxy:
cdef tree.xmlNode* c_node
c_node = cetree.findChild(self._c_node, index)
if c_node is NULL:
- raise IndexError, "list index out of range"
+ raise IndexError("list index out of range")
return _newProxy(self._source_proxy, c_node)
def __getslice__(self, Py_ssize_t start, Py_ssize_t stop):
diff --git a/src/lxml/nsclasses.pxi b/src/lxml/nsclasses.pxi
index 1f83791c..137c11f7 100644
--- a/src/lxml/nsclasses.pxi
+++ b/src/lxml/nsclasses.pxi
@@ -52,14 +52,14 @@ cdef class _NamespaceRegistry:
cdef python.PyObject* dict_result
dict_result = python.PyDict_GetItem(self._entries, name)
if dict_result is NULL:
- raise KeyError, "Name not registered."
+ raise KeyError("Name not registered.")
return <object>dict_result
cdef object _getForString(self, char* name):
cdef python.PyObject* dict_result
dict_result = python.PyDict_GetItemString(self._entries, name)
if dict_result is NULL:
- raise KeyError, "Name not registered."
+ raise KeyError("Name not registered.")
return <object>dict_result
def __iter__(self):
@@ -78,8 +78,8 @@ cdef class _ClassNamespaceRegistry(_NamespaceRegistry):
"Dictionary-like registry for namespace implementation classes"
def __setitem__(self, name, item):
if not python.PyType_Check(item) or not issubclass(item, ElementBase):
- raise NamespaceRegistryError, \
- "Registered element classes must be subtypes of ElementBase"
+ raise NamespaceRegistryError(
+ "Registered element classes must be subtypes of ElementBase")
if name is not None:
name = _utf8(name)
self._entries[name] = item
@@ -173,11 +173,11 @@ def FunctionNamespace(ns_uri):
cdef class _FunctionNamespaceRegistry(_NamespaceRegistry):
def __setitem__(self, name, item):
if not callable(item):
- raise NamespaceRegistryError, \
- "Registered functions must be callable."
+ raise NamespaceRegistryError(
+ "Registered functions must be callable.")
if not name:
- raise ValueError, \
- "extensions must have non empty names"
+ raise ValueError(
+ "extensions must have non empty names")
self._entries[_utf8(name)] = item
def __repr__(self):
diff --git a/src/lxml/objectpath.pxi b/src/lxml/objectpath.pxi
index 88fbefe0..c4042cd5 100644
--- a/src/lxml/objectpath.pxi
+++ b/src/lxml/objectpath.pxi
@@ -49,7 +49,7 @@ cdef class ObjectPath:
python.Py_INCREF(default)
use_default = 1
elif use_default > 1:
- raise TypeError, "invalid number of arguments: needs one or two"
+ raise TypeError("invalid number of arguments: needs one or two")
return _findObjectPath(root, self._c_path, self._path_len,
default, use_default)
@@ -107,15 +107,15 @@ cdef _parseObjectPathString(path):
# path '.child' => ignore root
python.PyList_Append(new_path, _RELATIVE_PATH_SEGMENT)
elif index != 0:
- raise ValueError, "index not allowed on root node"
+ raise ValueError("index not allowed on root node")
elif not has_dot:
- raise ValueError, "invalid path"
+ raise ValueError("invalid path")
python.PyList_Append(new_path, (ns, name, index))
path_pos = match.end()
if python.PyList_GET_SIZE(new_path) == 0 or \
python.PyString_GET_SIZE(path) > path_pos:
- raise ValueError, "invalid path"
+ raise ValueError("invalid path")
return new_path
cdef _parseObjectPathList(path):
@@ -140,17 +140,17 @@ cdef _parseObjectPathList(path):
else:
index_end = cstd.strchr(index_pos + 1, c']')
if index_end is NULL:
- raise ValueError, "index must be enclosed in []"
+ raise ValueError("index must be enclosed in []")
index = python.PyNumber_Int(
python.PyString_FromStringAndSize(
index_pos + 1, <Py_ssize_t>(index_end - index_pos - 1)))
if python.PyList_GET_SIZE(new_path) == 0 and index != 0:
- raise ValueError, "index not allowed on root node"
+ raise ValueError("index not allowed on root node")
name = python.PyString_FromStringAndSize(
c_name, <Py_ssize_t>(index_pos - c_name))
python.PyList_Append(new_path, (ns, name, index))
if python.PyList_GET_SIZE(new_path) == 0:
- raise ValueError, "invalid path"
+ raise ValueError("invalid path")
return new_path
cdef _ObjectPath* _buildObjectPathSegments(path_list) except NULL:
@@ -188,8 +188,9 @@ cdef _findObjectPath(_Element root, _ObjectPath* c_path, Py_ssize_t c_path_len,
if c_href is NULL or c_href[0] == c'\0':
c_href = tree._getNs(c_node)
if not cetree.tagMatches(c_node, c_href, c_name):
- raise ValueError, "root element does not match: need %s, got %s" % \
- (cetree.namespacedNameFromNsName(c_href, c_name), root.tag)
+ raise ValueError(
+ "root element does not match: need %s, got %s" %
+ (cetree.namespacedNameFromNsName(c_href, c_name), root.tag))
while c_node is not NULL:
c_path_len = c_path_len - 1
@@ -214,7 +215,7 @@ cdef _findObjectPath(_Element root, _ObjectPath* c_path, Py_ssize_t c_path_len,
return default_value
else:
tag = cetree.namespacedNameFromNsName(c_href, c_name)
- raise AttributeError, "no such child: " + tag
+ raise AttributeError("no such child: " + tag)
cdef _createObjectPath(_Element root, _ObjectPath* c_path,
Py_ssize_t c_path_len, int replace, value):
@@ -229,7 +230,7 @@ cdef _createObjectPath(_Element root, _ObjectPath* c_path,
cdef char* c_name
cdef Py_ssize_t c_index
if c_path_len == 1:
- raise TypeError, "cannot update root node"
+ raise TypeError("cannot update root node")
c_node = root._c_node
c_name = c_path[0].name
@@ -237,8 +238,9 @@ cdef _createObjectPath(_Element root, _ObjectPath* c_path,
if c_href is NULL or c_href[0] == c'\0':
c_href = tree._getNs(c_node)
if not cetree.tagMatches(c_node, c_href, c_name):
- raise ValueError, "root element does not match: need %s, got %s" % \
- (cetree.namespacedNameFromNsName(c_href, c_name), root.tag)
+ raise ValueError(
+ "root element does not match: need %s, got %s" %
+ (cetree.namespacedNameFromNsName(c_href, c_name), root.tag))
while c_path_len > 1:
c_path_len = c_path_len - 1
@@ -257,8 +259,8 @@ cdef _createObjectPath(_Element root, _ObjectPath* c_path,
if c_child is not NULL:
c_node = c_child
elif c_index != 0:
- raise TypeError, \
- "creating indexed path attributes is not supported"
+ raise TypeError(
+ "creating indexed path attributes is not supported")
elif c_path_len == 1:
_appendValue(cetree.elementFactory(root._doc, c_node),
cetree.namespacedNameFromNsName(c_href, c_name),
diff --git a/src/lxml/parser.pxi b/src/lxml/parser.pxi
index 5403093b..5a6782c2 100644
--- a/src/lxml/parser.pxi
+++ b/src/lxml/parser.pxi
@@ -269,7 +269,8 @@ cdef class _FileReaderContext:
if remaining <= 0:
self._bytes = self._filelike.read(c_size)
if not python.PyString_Check(self._bytes):
- raise TypeError, "reading file objects must return plain strings"
+ raise TypeError(
+ "reading file objects must return plain strings")
remaining = python.PyString_GET_SIZE(self._bytes)
self._bytes_read = 0
if remaining == 0:
@@ -417,7 +418,7 @@ cdef class _ParserContext(_ResolverContext):
result = python.PyThread_acquire_lock(
self._lock, python.WAIT_LOCK)
if result == 0:
- raise ParserError, "parser locking failed"
+ raise ParserError("parser locking failed")
self._error_log.connect()
if self._validator is not None:
self._validator.connect(self._c_ctxt)
@@ -559,7 +560,7 @@ cdef class _BaseParser:
if not isinstance(self, HTMLParser) and \
not isinstance(self, XMLParser) and \
not isinstance(self, iterparse):
- raise TypeError, "This class cannot be instantiated"
+ raise TypeError("This class cannot be instantiated")
self._parse_options = parse_options
self._filename = filename
@@ -579,7 +580,7 @@ cdef class _BaseParser:
c_encoding = tree.xmlParseCharEncoding(_cstr(encoding))
if c_encoding == tree.XML_CHAR_ENCODING_ERROR or \
c_encoding == tree.XML_CHAR_ENCODING_NONE:
- raise LookupError, "unknown encoding: '%s'" % encoding
+ raise LookupError("unknown encoding: '%s'" % encoding)
self._default_encoding = encoding
self._default_encoding_int = c_encoding
@@ -758,7 +759,7 @@ cdef class _BaseParser:
cdef xmlparser.xmlParserCtxt* pctxt
cdef char* c_encoding
if c_len > python.INT_MAX:
- raise ParserError, "string is too long to parse it with libxml2"
+ raise ParserError("string is too long to parse it with libxml2")
context = self._getParserContext()
context.prepare()
@@ -891,13 +892,13 @@ cdef class _FeedParser(_BaseParser):
py_buffer_len = python.PyString_GET_SIZE(data)
elif python.PyUnicode_Check(data):
if _UNICODE_ENCODING is NULL:
- raise ParserError, \
- "Unicode parsing is not supported on this platform"
+ raise ParserError(
+ "Unicode parsing is not supported on this platform")
c_encoding = _UNICODE_ENCODING
c_data = python.PyUnicode_AS_DATA(data)
py_buffer_len = python.PyUnicode_GET_DATA_SIZE(data)
else:
- raise TypeError, "Parsing requires string data"
+ raise TypeError("Parsing requires string data")
context = self._getPushParserContext()
pctxt = context._c_ctxt
@@ -1719,13 +1720,13 @@ cdef _Document _parseMemoryDocument(text, url, _BaseParser parser):
cdef xmlDoc* c_doc
if python.PyUnicode_Check(text):
if _hasEncodingDeclaration(text):
- raise ValueError, \
- "Unicode strings with encoding declaration are not supported."
+ raise ValueError(
+ "Unicode strings with encoding declaration are not supported.")
# pass native unicode only if libxml2 can handle it
if _UNICODE_ENCODING is NULL:
text = python.PyUnicode_AsUTF8String(text)
elif not python.PyString_Check(text):
- raise ValueError, "can only parse strings"
+ raise ValueError("can only parse strings")
if python.PyUnicode_Check(url):
url = python.PyUnicode_AsUTF8String(url)
c_doc = _parseDoc(text, url, parser)
diff --git a/src/lxml/relaxng.pxi b/src/lxml/relaxng.pxi
index 02a94a0a..27dffbf4 100644
--- a/src/lxml/relaxng.pxi
+++ b/src/lxml/relaxng.pxi
@@ -46,7 +46,7 @@ cdef class RelaxNG(_Validator):
if c_href is NULL or \
cstd.strcmp(c_href,
'http://relaxng.org/ns/structure/1.0') != 0:
- raise RelaxNGParseError, "Document is not Relax NG"
+ raise RelaxNGParseError("Document is not Relax NG")
self._error_log.connect()
fake_c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
parser_ctxt = relaxng.xmlRelaxNGNewDocParserCtxt(fake_c_doc)
@@ -59,13 +59,16 @@ cdef class RelaxNG(_Validator):
self._error_log.connect()
parser_ctxt = relaxng.xmlRelaxNGNewParserCtxt(_cstr(filename))
else:
- raise RelaxNGParseError, "No tree or file given"
+ raise RelaxNGParseError("No tree or file given")
if parser_ctxt is NULL:
self._error_log.disconnect()
if fake_c_doc is not NULL:
_destroyFakeDoc(doc._c_doc, fake_c_doc)
- raise RelaxNGParseError, "Document is not parsable as Relax NG"
+ raise RelaxNGParseError(
+ self._error_log._buildExceptionMessage(
+ "Document is not parsable as Relax NG"),
+ self._error_log)
self._c_schema = relaxng.xmlRelaxNGParse(parser_ctxt)
self._error_log.disconnect()
@@ -79,7 +82,7 @@ cdef class RelaxNG(_Validator):
raise RelaxNGParseError(
self._error_log._buildExceptionMessage(
"Document is not valid Relax NG"),
- error_log=self._error_log)
+ self._error_log)
if fake_c_doc is not NULL:
_destroyFakeDoc(doc._c_doc, fake_c_doc)
@@ -114,7 +117,9 @@ cdef class RelaxNG(_Validator):
self._error_log.disconnect()
if ret == -1:
- raise RelaxNGValidateError, "Internal error in Relax NG validation"
+ raise RelaxNGValidateError(
+ "Internal error in Relax NG validation",
+ self._error_log)
if ret == 0:
return True
else:
diff --git a/src/lxml/schematron.pxi b/src/lxml/schematron.pxi
index a61fbabc..6286218b 100644
--- a/src/lxml/schematron.pxi
+++ b/src/lxml/schematron.pxi
@@ -80,6 +80,7 @@ cdef class Schematron(_Validator):
cdef xmlDoc* c_doc
cdef char* c_href
cdef schematron.xmlSchematronParserCtxt* parser_ctxt
+ _Validator.__init__(self)
if not config.ENABLE_SCHEMATRON:
raise SchematronError(
"lxml.etree was compiled without Schematron support.")
@@ -88,6 +89,7 @@ cdef class Schematron(_Validator):
doc = _documentOrRaise(etree)
root_node = _rootNodeOrRaise(etree)
c_doc = _copyDocRoot(doc._c_doc, root_node._c_node)
+ self._error_log.connect()
parser_ctxt = schematron.xmlSchematronNewDocParserCtxt(c_doc)
elif file is not None:
filename = _getFilenameForFile(file)
@@ -95,21 +97,24 @@ cdef class Schematron(_Validator):
# XXX assume a string object
filename = file
filename = _encodeFilename(filename)
+ self._error_log.connect()
parser_ctxt = schematron.xmlSchematronNewParserCtxt(_cstr(filename))
c_doc = NULL
else:
raise SchematronParseError("No tree or file given")
if parser_ctxt is NULL:
+ self._error_log.disconnect()
python.PyErr_NoMemory()
self._c_schema = schematron.xmlSchematronParse(parser_ctxt)
+ self._error_log.disconnect()
schematron.xmlSchematronFreeParserCtxt(parser_ctxt)
if self._c_schema is NULL:
raise SchematronParseError(
- "Document is not a valid Schematron schema")
- _Validator.__init__(self)
+ "Document is not a valid Schematron schema",
+ self._error_log)
def __dealloc__(self):
schematron.xmlSchematronFree(self._c_schema)
@@ -136,7 +141,7 @@ cdef class Schematron(_Validator):
valid_ctxt = schematron.xmlSchematronNewValidCtxt(
self._c_schema, options)
if valid_ctxt is NULL:
- raise SchematronError("Failed to create validation context")
+ return python.PyErr_NoMemory()
self._error_log.connect()
c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
@@ -149,7 +154,8 @@ cdef class Schematron(_Validator):
if ret == -1:
raise SchematronValidateError(
- "Internal error in Schematron validation")
+ "Internal error in Schematron validation",
+ self._error_log)
if ret == 0:
return True
else:
diff --git a/src/lxml/serializer.pxi b/src/lxml/serializer.pxi
index 7dc213c4..91b9c61c 100644
--- a/src/lxml/serializer.pxi
+++ b/src/lxml/serializer.pxi
@@ -15,7 +15,7 @@ cdef int _findOutputMethod(method) except -1:
return OUTPUT_METHOD_HTML
if method == "text":
return OUTPUT_METHOD_TEXT
- raise ValueError, "unknown output method %r" % method
+ raise ValueError("unknown output method %r" % method)
cdef _textToString(xmlNode* c_node, encoding):
cdef char* c_text
@@ -67,12 +67,12 @@ cdef _tostring(_Element element, encoding, method,
# encoding during output
enchandler = tree.xmlFindCharEncodingHandler(c_enc)
if enchandler is NULL:
- raise LookupError, python.PyString_FromFormat(
- "unknown encoding: '%s'", c_enc)
+ raise LookupError(python.PyString_FromFormat(
+ "unknown encoding: '%s'", c_enc))
c_buffer = tree.xmlAllocOutputBuffer(enchandler)
if c_buffer is NULL:
tree.xmlCharEncCloseFunc(enchandler)
- raise LxmlError, "Failed to create output buffer"
+ return python.PyErr_NoMemory()
with nogil:
_writeNodeToBuffer(c_buffer, element._c_node, c_enc, c_method,
@@ -108,7 +108,7 @@ cdef _tounicode(_Element element, method,
return python.PyUnicode_FromEncodedObject(text, 'utf-8', 'strict')
c_buffer = tree.xmlAllocOutputBuffer(NULL)
if c_buffer is NULL:
- raise LxmlError, "Failed to create output buffer"
+ return python.PyErr_NoMemory()
with nogil:
_writeNodeToBuffer(c_buffer, element._c_node, NULL, c_method, 0,
@@ -285,13 +285,13 @@ cdef class _FilelikeWriter:
_writeFilelikeWriter, _closeFilelikeWriter,
<python.PyObject*>self, enchandler)
if c_buffer is NULL:
- raise IOError, "Could not create I/O writer context."
+ raise IOError("Could not create I/O writer context.")
return c_buffer
cdef int write(self, char* c_buffer, int size):
try:
if self._filelike is None:
- raise IOError, "File is already closed"
+ raise IOError("File is already closed")
py_buffer = python.PyString_FromStringAndSize(c_buffer, size)
self._filelike.write(py_buffer)
return size
@@ -335,22 +335,22 @@ cdef _tofilelike(f, _Element element, encoding, method,
return
enchandler = tree.xmlFindCharEncodingHandler(c_enc)
if enchandler is NULL:
- raise LookupError, python.PyString_FromFormat(
- "unknown encoding: '%s'", c_enc)
+ raise LookupError(python.PyString_FromFormat(
+ "unknown encoding: '%s'", c_enc))
if _isString(f):
filename8 = _encodeFilename(f)
c_buffer = tree.xmlOutputBufferCreateFilename(
_cstr(filename8), enchandler, 0)
if c_buffer is NULL:
- python.PyErr_SetFromErrno(IOError)
+ return python.PyErr_SetFromErrno(IOError)
state = python.PyEval_SaveThread()
elif hasattr(f, 'write'):
writer = _FilelikeWriter(f)
c_buffer = writer._createOutputBuffer(enchandler)
else:
tree.xmlCharEncCloseFunc(enchandler)
- raise TypeError, "File or filename expected, got '%s'" % type(f)
+ raise TypeError("File or filename expected, got '%s'" % type(f))
_writeNodeToBuffer(c_buffer, element._c_node, c_enc, c_method,
write_xml_declaration, write_doctype, pretty_print)
@@ -386,7 +386,7 @@ cdef _tofilelikeC14N(f, _Element element):
writer.error_log.disconnect()
tree.xmlOutputBufferClose(c_buffer)
else:
- raise TypeError, "File or filename expected, got '%s'" % type(f)
+ raise TypeError("File or filename expected, got '%s'" % type(f))
finally:
_destroyFakeDoc(c_base_doc, c_doc)
@@ -399,14 +399,14 @@ cdef _tofilelikeC14N(f, _Element element):
errors = writer.error_log
if len(errors):
message = errors[0].message
- raise C14NError, message
+ raise C14NError(message)
# dump node to file (mainly for debug)
cdef _dumpToFile(f, xmlNode* c_node, bint pretty_print):
cdef tree.xmlOutputBuffer* c_buffer
if not python.PyFile_Check(f):
- raise ValueError, "Not a file"
+ raise ValueError("not a file")
c_buffer = tree.xmlOutputBufferCreateFile(python.PyFile_AsFile(f), NULL)
tree.xmlNodeDumpOutput(c_buffer, c_node.doc, c_node, 0, pretty_print, NULL)
_writeTail(c_buffer, c_node, NULL, 0)
diff --git a/src/lxml/tests/test_xpathevaluator.py b/src/lxml/tests/test_xpathevaluator.py
index b428753e..7a906659 100644
--- a/src/lxml/tests/test_xpathevaluator.py
+++ b/src/lxml/tests/test_xpathevaluator.py
@@ -618,7 +618,7 @@ def xpath():
>>> e.evaluate("resultTypesTest()")
Traceback (most recent call last):
...
- XPathResultError: This is not a node: x
+ XPathResultError: This is not a node: 'x'
>>> try:
... e.evaluate("resultTypesTest2()")
... except etree.XPathResultError:
diff --git a/src/lxml/xinclude.pxi b/src/lxml/xinclude.pxi
new file mode 100644
index 00000000..647f22de
--- /dev/null
+++ b/src/lxml/xinclude.pxi
@@ -0,0 +1,45 @@
+# XInclude processing
+
+cimport xinclude
+
+class XIncludeError(LxmlError):
+ """Error during XInclude processing.
+ """
+ pass
+
+cdef class XInclude:
+ """XInclude processor.
+
+ Create an instance and call it on an Element to run XInclude
+ processing.
+ """
+ cdef _ErrorLog _error_log
+ def __init__(self):
+ self._error_log = _ErrorLog()
+
+ property error_log:
+ def __get__(self):
+ return self._error_log.copy()
+
+ def __call__(self, _Element node not None):
+ # We cannot pass the XML_PARSE_NOXINCNODE option as this would free
+ # the XInclude nodes - there may still be Python references to them!
+ # Therefore, we allow XInclude nodes to be converted to
+ # XML_XINCLUDE_START nodes. XML_XINCLUDE_END nodes are added as
+ # siblings. Tree traversal will simply ignore them as they are not
+ # typed as elements. The included fragment is added between the two,
+ # i.e. as a sibling, which does not conflict with traversal.
+ self._error_log.connect()
+ with nogil:
+ if node._doc._parser is not None:
+ result = xinclude.xmlXIncludeProcessTreeFlags(
+ node._c_node, node._doc._parser._parse_options)
+ else:
+ result = xinclude.xmlXIncludeProcessTree(node._c_node)
+ self._error_log.disconnect()
+
+ if result == -1:
+ raise XIncludeError(
+ self._error_log._buildExceptionMessage(
+ "XInclude processing failed"),
+ self._error_log)
diff --git a/src/lxml/xmlid.pxi b/src/lxml/xmlid.pxi
index 5370969a..5979dc6b 100644
--- a/src/lxml/xmlid.pxi
+++ b/src/lxml/xmlid.pxi
@@ -62,7 +62,7 @@ cdef class _IDDict:
cdef _Document doc
doc = _documentOrRaise(etree)
if doc._c_doc.ids is NULL:
- raise ValueError, "No ID dictionary available."
+ raise ValueError("No ID dictionary available.")
self._doc = doc
self._keys = None
self._items = None
@@ -78,10 +78,10 @@ cdef class _IDDict:
id_utf = _utf8(id_name)
c_id = <tree.xmlID*>tree.xmlHashLookup(c_ids, _cstr(id_utf))
if c_id is NULL:
- raise KeyError, "Key not found."
+ raise KeyError("key not found.")
c_attr = c_id.attr
if c_attr is NULL or c_attr.parent is NULL:
- raise KeyError, "ID attribute not found."
+ raise KeyError("ID attribute not found.")
return _elementFactory(self._doc, c_attr.parent)
def get(self, id_name):
diff --git a/src/lxml/xmlschema.pxi b/src/lxml/xmlschema.pxi
index b1c3900f..0ca82e1a 100644
--- a/src/lxml/xmlschema.pxi
+++ b/src/lxml/xmlschema.pxi
@@ -76,7 +76,7 @@ cdef class XMLSchema(_Validator):
raise XMLSchemaParseError(
self._error_log._buildExceptionMessage(
"Document is not valid XML Schema"),
- error_log=self._error_log)
+ self._error_log)
def __dealloc__(self):
xmlschema.xmlSchemaFree(self._c_schema)
@@ -99,7 +99,7 @@ cdef class XMLSchema(_Validator):
valid_ctxt = xmlschema.xmlSchemaNewValidCtxt(self._c_schema)
if valid_ctxt is NULL:
self._error_log.disconnect()
- raise XMLSchemaError, "Failed to create validation context"
+ return python.PyErr_NoMemory()
c_doc = _fakeRootDoc(doc._c_doc, root_node._c_node)
with nogil:
@@ -111,7 +111,8 @@ cdef class XMLSchema(_Validator):
self._error_log.disconnect()
if ret == -1:
raise XMLSchemaValidateError(
- "Internal error in XML Schema validation.")
+ "Internal error in XML Schema validation.",
+ self._error_log)
if ret == 0:
return True
else:
@@ -144,7 +145,7 @@ cdef class _ParserSchemaValidationContext:
self._valid_ctxt = xmlschema.xmlSchemaNewValidCtxt(
self._schema._c_schema)
if self._valid_ctxt is NULL:
- raise XMLSchemaError, "Failed to create validation context"
+ return python.PyErr_NoMemory()
self._sax_plug = xmlschema.xmlSchemaSAXPlug(
self._valid_ctxt, &c_ctxt.sax, &c_ctxt.userData)
diff --git a/src/lxml/xpath.pxi b/src/lxml/xpath.pxi
index 3ff3d146..087886bc 100644
--- a/src/lxml/xpath.pxi
+++ b/src/lxml/xpath.pxi
@@ -154,7 +154,7 @@ cdef class _XPathEvaluatorBase:
result = python.PyThread_acquire_lock(
self._eval_lock, python.WAIT_LOCK)
if result == 0:
- raise ParserError, "parser locking failed"
+ raise ParserError("parser locking failed")
return 0
cdef void _unlock(self):
@@ -167,9 +167,10 @@ cdef class _XPathEvaluatorBase:
if entries:
message = entries._buildExceptionMessage(None)
if message is not None:
- raise XPathSyntaxError, message
- raise XPathSyntaxError, self._error_log._buildExceptionMessage(
- "Error in xpath expression")
+ raise XPathSyntaxError(message, self._error_log)
+ raise XPathSyntaxError(self._error_log._buildExceptionMessage(
+ "Error in xpath expression"),
+ self._error_log)
cdef _raise_eval_error(self):
cdef _BaseErrorLog entries
@@ -179,9 +180,10 @@ cdef class _XPathEvaluatorBase:
if entries:
message = entries._buildExceptionMessage(None)
if message is not None:
- raise XPathEvalError, message
- raise XPathEvalError, self._error_log._buildExceptionMessage(
- "Error in xpath expression")
+ raise XPathEvalError(message, self._error_log)
+ raise XPathEvalError(self._error_log._buildExceptionMessage(
+ "Error in xpath expression"),
+ self._error_log)
cdef object _handle_result(self, xpath.xmlXPathObject* xpathObj, _Document doc):
if self._context._exc._has_raised():
diff --git a/src/lxml/xslt.pxi b/src/lxml/xslt.pxi
index 114bc4d0..1323912e 100644
--- a/src/lxml/xslt.pxi
+++ b/src/lxml/xslt.pxi
@@ -183,7 +183,7 @@ cdef class XSLTAccessControl:
read_network=True, write_network=True):
self._prefs = xslt.xsltNewSecurityPrefs()
if self._prefs is NULL:
- raise XSLTError, "Error preparing access control context"
+ python.PyErr_NoMemory()
self._setAccess(xslt.XSLT_SECPREF_READ_FILE, read_file)
self._setAccess(xslt.XSLT_SECPREF_WRITE_FILE, write_file)
self._setAccess(xslt.XSLT_SECPREF_CREATE_DIRECTORY, create_dir)
@@ -230,8 +230,8 @@ cdef class _XSLTContext(_BaseContext):
if extensions is not None:
for ns, prefix in extensions:
if ns is None:
- raise XSLTExtensionError, \
- "extensions must not have empty namespaces"
+ raise XSLTExtensionError(
+ "extensions must not have empty namespaces")
_BaseContext.__init__(self, namespaces, extensions, enable_regexp)
cdef register_context(self, xslt.xsltTransformContext* xsltCtxt,
@@ -308,11 +308,13 @@ cdef class XSLT:
# last error seems to be the most accurate here
if self._error_log.last_error is not None and \
self._error_log.last_error.message:
- raise XSLTParseError(self._error_log.last_error.message)
+ raise XSLTParseError(self._error_log.last_error.message,
+ self._error_log)
else:
raise XSLTParseError(
self._error_log._buildExceptionMessage(
- "Cannot parse stylesheet"))
+ "Cannot parse stylesheet"),
+ self._error_log)
c_doc._private = NULL # no longer used!
self._c_style = c_style
@@ -415,7 +417,7 @@ cdef class XSLT:
message = "Error applying stylesheet, line %d" % error.line
else:
message = "Error applying stylesheet"
- raise XSLTApplyError, message
+ raise XSLTApplyError(message, self._error_log)
finally:
if resolver_context is not None:
resolver_context.clear()
@@ -513,7 +515,7 @@ cdef class _XSLTResultTree(_ElementTree):
r = xslt.xsltSaveResultToString(s, l, doc._c_doc,
self._xslt._c_style)
if r == -1:
- raise XSLTSaveError, "Error saving XSLT result to string"
+ python.PyErr_NoMemory()
def __str__(self):
cdef char* s
@@ -618,10 +620,10 @@ cdef class _XSLTProcessingInstruction(PIBase):
cdef char* c_href
cdef xmlAttr* c_attr
if self._c_node.content is NULL:
- raise ValueError, "PI lacks content"
+ raise ValueError("PI lacks content")
hrefs_utf = _FIND_PI_HREF(' ' + self._c_node.content)
if len(hrefs_utf) != 1:
- raise ValueError, "malformed PI attributes"
+ raise ValueError("malformed PI attributes")
href_utf = hrefs_utf[0]
c_href = _cstr(href_utf)
@@ -649,19 +651,20 @@ cdef class _XSLTProcessingInstruction(PIBase):
# try XPath search
root = _findStylesheetByID(self._doc, funicode(c_href))
if not root:
- raise ValueError, "reference to non-existing embedded stylesheet"
+ raise ValueError("reference to non-existing embedded stylesheet")
elif len(root) > 1:
- raise ValueError, "ambiguous reference to embedded stylesheet"
+ raise ValueError("ambiguous reference to embedded stylesheet")
result_node = root[0]
return _elementTreeFactory(result_node._doc, result_node)
def set(self, key, value):
if key != "href":
- raise AttributeError, "only setting the 'href' attribute is supported on XSLT-PIs"
+ raise AttributeError(
+ "only setting the 'href' attribute is supported on XSLT-PIs")
if value is None:
attrib = ""
elif '"' in value or '>' in value:
- raise ValueError, "Invalid URL, must not contain '\"' or '>'"
+ raise ValueError("Invalid URL, must not contain '\"' or '>'")
else:
attrib = ' href="%s"' % value
text = ' ' + self.text