diff options
author | Georg Brandl <georg@python.org> | 2010-10-15 14:46:48 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2010-10-15 14:46:48 (GMT) |
commit | b4dac71a8768888dbe3de007780cd5467e48f0f4 (patch) | |
tree | c44b7b9544d5953a767a74a8bad038a5f99b4284 | |
parent | f668df5fa7e2048f4b17e98882f2a21405b6bdb4 (diff) | |
download | cpython-b4dac71a8768888dbe3de007780cd5467e48f0f4.zip cpython-b4dac71a8768888dbe3de007780cd5467e48f0f4.tar.gz cpython-b4dac71a8768888dbe3de007780cd5467e48f0f4.tar.bz2 |
#5355: Provide mappings from Expat error numbers to string descriptions and backwards, in order to actually make it possible to analyze error codes provided by ExpatError.
-rw-r--r-- | Doc/library/pyexpat.rst | 91 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/pyexpat.c | 41 |
3 files changed, 83 insertions, 53 deletions
diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index e16e45f..390c38e 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -169,7 +169,7 @@ XMLParser Objects This method can only be called before the :meth:`Parse` or :meth:`ParseFile` methods are called; calling it after either of those have been called causes :exc:`ExpatError` to be raised with the :attr:`code` attribute set to - :const:`errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING`. + ``errors.codes[errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING]``. :class:`xmlparser` objects have the following attributes: @@ -467,8 +467,21 @@ ExpatError Exceptions .. attribute:: ExpatError.code - Expat's internal error number for the specific error. This will match one of - the constants defined in the ``errors`` object from this module. + Expat's internal error number for the specific error. The + :data:`errors.messages` dictionary maps these error numbers to Expat's error + messages. For example:: + + from xml.parsers.expat import ParserCreate, ExpatError, errors + + p = ParserCreate() + try: + p.Parse(some_xml_document) + except ExpatError as err: + print("Error:", errors.messages[err.code]) + + The :mod:`errors` module also provides error message constants and a + dictionary :data:`~errors.codes` mapping these messages back to the error + codes, see below. .. attribute:: ExpatError.lineno @@ -530,15 +543,16 @@ The output from this program is:: Content Model Descriptions -------------------------- -.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> +.. module:: xml.parsers.expat.model +.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> Content modules are described using nested tuples. Each tuple contains four values: the type, the quantifier, the name, and a tuple of children. Children are simply additional content module descriptions. -The values of the first two fields are constants defined in the ``model`` object -of the :mod:`xml.parsers.expat` module. These constants can be collected in two +The values of the first two fields are constants defined in the +:mod:`xml.parsers.expat.model` module. These constants can be collected in two groups: the model type group and the quantifier group. The constants in the model type group are: @@ -610,143 +624,139 @@ The constants in the quantifier group are: Expat error constants --------------------- -The following constants are provided in the ``errors`` object of the -:mod:`xml.parsers.expat` module. These constants are useful in interpreting -some of the attributes of the :exc:`ExpatError` exception objects raised when an -error has occurred. +.. module:: xml.parsers.expat.errors + +The following constants are provided in the :mod:`xml.parsers.expat.errors` +module. These constants are useful in interpreting some of the attributes of +the :exc:`ExpatError` exception objects raised when an error has occurred. +Since for backwards compatibility reasons, the constants' value is the error +*message* and not the numeric error *code*, you do this by comparing its +:attr:`code` attribute with +:samp:`errors.codes[errors.XML_ERROR_{CONSTANT_NAME}]`. + +The ``errors`` module has the following attributes: + +.. data:: codes + + A dictionary mapping numeric error codes to their string descriptions. + + .. versionadded:: 3.2 + + +.. data:: messages + + A dictionary mapping string descriptions to their error codes. -The ``errors`` object has the following attributes: + .. versionadded:: 3.2 .. data:: XML_ERROR_ASYNC_ENTITY - :noindex: .. data:: XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF - :noindex: An entity reference in an attribute value referred to an external entity instead of an internal entity. .. data:: XML_ERROR_BAD_CHAR_REF - :noindex: A character reference referred to a character which is illegal in XML (for example, character ``0``, or '``�``'). .. data:: XML_ERROR_BINARY_ENTITY_REF - :noindex: An entity reference referred to an entity which was declared with a notation, so cannot be parsed. .. data:: XML_ERROR_DUPLICATE_ATTRIBUTE - :noindex: An attribute was used more than once in a start tag. .. data:: XML_ERROR_INCORRECT_ENCODING - :noindex: .. data:: XML_ERROR_INVALID_TOKEN - :noindex: Raised when an input byte could not properly be assigned to a character; for example, a NUL byte (value ``0``) in a UTF-8 input stream. .. data:: XML_ERROR_JUNK_AFTER_DOC_ELEMENT - :noindex: Something other than whitespace occurred after the document element. .. data:: XML_ERROR_MISPLACED_XML_PI - :noindex: An XML declaration was found somewhere other than the start of the input data. .. data:: XML_ERROR_NO_ELEMENTS - :noindex: The document contains no elements (XML requires all documents to contain exactly one top-level element).. .. data:: XML_ERROR_NO_MEMORY - :noindex: Expat was not able to allocate memory internally. .. data:: XML_ERROR_PARAM_ENTITY_REF - :noindex: A parameter entity reference was found where it was not allowed. .. data:: XML_ERROR_PARTIAL_CHAR - :noindex: An incomplete character was found in the input. .. data:: XML_ERROR_RECURSIVE_ENTITY_REF - :noindex: An entity reference contained another reference to the same entity; possibly via a different name, and possibly indirectly. .. data:: XML_ERROR_SYNTAX - :noindex: Some unspecified syntax error was encountered. .. data:: XML_ERROR_TAG_MISMATCH - :noindex: An end tag did not match the innermost open start tag. .. data:: XML_ERROR_UNCLOSED_TOKEN - :noindex: Some token (such as a start tag) was not closed before the end of the stream or the next token was encountered. .. data:: XML_ERROR_UNDEFINED_ENTITY - :noindex: A reference was made to a entity which was not defined. .. data:: XML_ERROR_UNKNOWN_ENCODING - :noindex: The document encoding is not supported by Expat. .. data:: XML_ERROR_UNCLOSED_CDATA_SECTION - :noindex: A CDATA marked section was not closed. .. data:: XML_ERROR_EXTERNAL_ENTITY_HANDLING - :noindex: .. data:: XML_ERROR_NOT_STANDALONE - :noindex: The parser determined that the document was not "standalone" though it declared itself to be in the XML declaration, and the :attr:`NotStandaloneHandler` was @@ -754,15 +764,12 @@ The ``errors`` object has the following attributes: .. data:: XML_ERROR_UNEXPECTED_STATE - :noindex: .. data:: XML_ERROR_ENTITY_DECLARED_IN_PE - :noindex: .. data:: XML_ERROR_FEATURE_REQUIRES_XML_DTD - :noindex: An operation was requested that requires DTD support to be compiled in, but Expat was configured without DTD support. This should never be reported by a @@ -770,7 +777,6 @@ The ``errors`` object has the following attributes: .. data:: XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING - :noindex: A behavioral change was requested after parsing started that can only be changed before parsing has started. This is (currently) only raised by @@ -778,63 +784,53 @@ The ``errors`` object has the following attributes: .. data:: XML_ERROR_UNBOUND_PREFIX - :noindex: An undeclared prefix was found when namespace processing was enabled. .. data:: XML_ERROR_UNDECLARING_PREFIX - :noindex: The document attempted to remove the namespace declaration associated with a prefix. .. data:: XML_ERROR_INCOMPLETE_PE - :noindex: A parameter entity contained incomplete markup. .. data:: XML_ERROR_XML_DECL - :noindex: The document contained no document element at all. .. data:: XML_ERROR_TEXT_DECL - :noindex: There was an error parsing a text declaration in an external entity. .. data:: XML_ERROR_PUBLICID - :noindex: Characters were found in the public id that are not allowed. .. data:: XML_ERROR_SUSPENDED - :noindex: The requested operation was made on a suspended parser, but isn't allowed. This includes attempts to provide additional input or to stop the parser. .. data:: XML_ERROR_NOT_SUSPENDED - :noindex: An attempt to resume the parser was made when the parser had not been suspended. .. data:: XML_ERROR_ABORTED - :noindex: This should not be reported to Python applications. .. data:: XML_ERROR_FINISHED - :noindex: The requested operation was made on a parser which was finished parsing input, but isn't allowed. This includes attempts to provide additional input or to @@ -842,7 +838,6 @@ The ``errors`` object has the following attributes: .. data:: XML_ERROR_SUSPEND_PE - :noindex: .. rubric:: Footnotes @@ -63,6 +63,10 @@ Library Extensions ---------- +- Issue #5355: Provide mappings from Expat error numbers to string + descriptions and backwards, in order to actually make it possible + to analyze error codes provided by ExpatError. + - The Unicode database was updated to 6.0.0. Tools/Demos diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index e603984..a8b0f8f 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1685,8 +1685,12 @@ MODULE_INITFUNC(void) PyObject *modelmod_name; PyObject *model_module; PyObject *sys_modules; + PyObject *tmpnum, *tmpstr; + PyObject *codes_dict; + PyObject *rev_codes_dict; + int res; static struct PyExpat_CAPI capi; - PyObject* capi_object; + PyObject *capi_object; if (errmod_name == NULL) return NULL; @@ -1789,9 +1793,29 @@ MODULE_INITFUNC(void) } #endif + codes_dict = PyDict_New(); + rev_codes_dict = PyDict_New(); + if (codes_dict == NULL || rev_codes_dict == NULL) { + Py_XDECREF(codes_dict); + Py_XDECREF(rev_codes_dict); + return NULL; + } + #define MYCONST(name) \ - PyModule_AddStringConstant(errors_module, #name, \ - (char*)XML_ErrorString(name)) + if (PyModule_AddStringConstant(errors_module, #name, \ + (char *)XML_ErrorString(name)) < 0) \ + return NULL; \ + tmpnum = PyLong_FromLong(name); \ + if (tmpnum == NULL) return NULL; \ + res = PyDict_SetItemString(codes_dict, \ + XML_ErrorString(name), tmpnum); \ + if (res < 0) return NULL; \ + tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \ + if (tmpstr == NULL) return NULL; \ + res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \ + Py_DECREF(tmpstr); \ + Py_DECREF(tmpnum); \ + if (res < 0) return NULL; \ MYCONST(XML_ERROR_NO_MEMORY); MYCONST(XML_ERROR_SYNTAX); @@ -1833,9 +1857,16 @@ MODULE_INITFUNC(void) MYCONST(XML_ERROR_FINISHED); MYCONST(XML_ERROR_SUSPEND_PE); - PyModule_AddStringConstant(errors_module, "__doc__", - "Constants used to describe error conditions."); + if (PyModule_AddStringConstant(errors_module, "__doc__", + "Constants used to describe " + "error conditions.") < 0) + return NULL; + if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) + return NULL; + if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) + return NULL; + #undef MYCONST #define MYCONST(c) PyModule_AddIntConstant(m, #c, c) |