applied patch from Stephane Bidoul for structured error handling from

* python/libxml2-python-api.xml python/libxml_wrap.h python/types.c
  python/tests/Makefile.am python/tests/tstLastError.py: applied
  patch from Stephane Bidoul for structured error handling from
  python, and the associated test
Daniel
This commit is contained in:
Daniel Veillard 2004-01-06 22:54:57 +00:00
parent 5d4cba413a
commit 46da46493f
8 changed files with 157 additions and 1 deletions

View File

@ -1,3 +1,10 @@
Tue Jan 6 23:51:46 CET 2004 Daniel Veillard <daniel@veillard.com>
* python/libxml2-python-api.xml python/libxml_wrap.h python/types.c
python/tests/Makefile.am python/tests/tstLastError.py: applied
patch from Stephane Bidoul for structured error handling from
python, and the associated test
Tue Jan 6 23:18:11 HKT 2004 William Brack <wbrack@mmm.com.hk>
* configure.in: fixed Bug130593

View File

@ -268,6 +268,7 @@ py_types = {
'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
'FILE *': ('O', "File", "FILEPtr", "FILE *"),
'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
'xmlErrorPtr': ('O', "Error", "xmlErrorPtr", "xmlErrorPtr"),
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
@ -641,6 +642,7 @@ classes_type = {
"htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
"xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
"xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
"xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
"xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
@ -721,6 +723,9 @@ def nameFixup(name, classe, type, file):
elif name[0:9] == "xmlURISet" and file == "python_accessor":
func = name[6:]
func = string.lower(func[0:1]) + func[1:]
elif name[0:11] == "xmlErrorGet" and file == "python_accessor":
func = name[11:]
func = string.lower(func[0:1]) + func[1:]
elif name[0:17] == "xmlXPathParserGet" and file == "python_accessor":
func = name[17:]
func = string.lower(func[0:1]) + func[1:]

View File

@ -275,5 +275,36 @@
<arg name='URI' type='xmlURIPtr' info='the URI'/>
<arg name='port' type='int' info='The URI port part'/>
</function>
<!-- xmlErrorPtr accessors -->
<function name='xmlErrorGetDomain' file='python_accessor'>
<info>What part of the library raised this error</info>
<return type='int' info="The error domain" field="domain"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
<function name='xmlErrorGetCode' file='python_accessor'>
<info>The error code, e.g. an xmlParserError</info>
<return type='int' info="The error code" field="code"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
<function name='xmlErrorGetMessage' file='python_accessor'>
<info>human-readable informative error message</info>
<return type='const char *' info="The error message" field="message"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
<function name='xmlErrorGetLevel' file='python_accessor'>
<info>how consequent is the error</info>
<return type='int' info="The error level" field="level"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
<function name='xmlErrorGetFile' file='python_accessor'>
<info>the filename</info>
<return type='const char *' info="The error file" field="file"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
<function name='xmlErrorGetLine' file='python_accessor'>
<info>the line number if available</info>
<return type='int' info="The error line" field="line"/>
<arg name='Error' type='xmlErrorPtr' info='the Error'/>
</function>
</symbols>
</api>

View File

@ -203,6 +203,7 @@ registerDefaultOutputCallbacks()
registerHTTPPostCallbacks()
# functions from module xmlerror
lastError()
resetLastError()
# functions from module xmlreader
@ -779,6 +780,18 @@ Class relaxNgSchema()
# functions from module xmlreader
RelaxNGSetSchema()
Class Error()
# accessors
code()
domain()
file()
level()
line()
message()
# functions from module xmlerror
copyError()
resetError()
Class relaxNgValidCtxt()
# functions from module relaxng

View File

@ -107,6 +107,14 @@ typedef struct {
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
(((PyURI_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlErrorPtr obj;
} PyError_Object;
#define PyError_Get(v) (((v) == Py_None) ? NULL : \
(((PyError_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlOutputBufferPtr obj;
@ -194,3 +202,4 @@ PyObject * libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt);
PyObject * libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt);
PyObject * libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid);
#endif /* LIBXML_SCHEMAS_ENABLED */
PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error);

View File

@ -31,7 +31,8 @@ PYTESTS= \
ctxterror.py\
readererr.py\
relaxng.py \
thread2.py
thread2.py \
tstLastError.py
XMLS= \
tst.xml \

72
python/tests/tstLastError.py Executable file
View File

@ -0,0 +1,72 @@
#!/usr/bin/python -u
import sys, unittest
import libxml2
class TestCase(unittest.TestCase):
def setUp(self):
libxml2.debugMemory(1)
def tearDown(self):
libxml2.cleanupParser()
if libxml2.debugMemory(1) != 0:
libxml2.dumpMemory()
self.fail("Memory leak %d bytes" % (libxml2.debugMemory(1),))
def failUnlessXmlError(self,f,args,exc,domain,code,message,level,file,line):
"""Run function f, with arguments args and expect an exception exc;
when the exception is raised, check the libxml2.lastError for
expected values."""
# disable the default error handler
libxml2.registerErrorHandler(None,None)
try:
f(*args)
except exc:
e = libxml2.lastError()
if e is None:
self.fail("lastError not set")
if 0:
print "domain = ",e.domain()
print "code = ",e.code()
print "message =",repr(e.message())
print "level =",e.level()
print "file =",e.file()
print "line =",e.line()
print
self.failUnlessEqual(domain,e.domain())
self.failUnlessEqual(code,e.code())
self.failUnlessEqual(message,e.message())
self.failUnlessEqual(level,e.level())
self.failUnlessEqual(file,e.file())
self.failUnlessEqual(line,e.line())
else:
self.fail("exception %s should have been raised" % exc)
def test1(self):
"""Test readFile with a file that does not exist"""
self.failUnlessXmlError(libxml2.readFile,
("dummy.xml",None,0),
libxml2.treeError,
domain=8, # XML_FROM_IO
code=1549, # XML_IO_LOAD_ERROR
message='failed to load external entity "dummy.xml"\n',
level=1, # XML_ERR_WARNING
file=None,
line=0)
def test2(self):
"""Test a well-formedness error: we get the last error only"""
s = "<x>\n<a>\n</x>"
self.failUnlessXmlError(libxml2.readMemory,
(s,len(s),"dummy.xml",None,0),
libxml2.treeError,
domain=1, # XML_FROM_PARSER
code=77, # XML_ERR_TAG_NOT_FINISHED
message='Premature end of data in tag x line 1\n',
level=3, # XML_ERR_FATAL
file='dummy.xml',
line=3)
if __name__ == "__main__":
unittest.main()

View File

@ -641,3 +641,21 @@ libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
return (ret);
}
#endif /* LIBXML_SCHEMAS_ENABLED */
PyObject *
libxml_xmlErrorPtrWrap(xmlErrorPtr error)
{
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlErrorPtrWrap: error = %p\n", error);
#endif
if (error == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
ret =
PyCObject_FromVoidPtrAndDesc((void *) error,
(char *) "xmlErrorPtr", NULL);
return (ret);
}