Skip to content

Commit

Permalink
[svn r4180] r5180@delle: sbehnel | 2009-07-11 21:43:07 +0200
Browse files Browse the repository at this point in the history
 more fixes (and a test) for diverting the global error log to Python's logging package

--HG--
branch : trunk
  • Loading branch information
scoder committed Jul 11, 2009
1 parent b6e8a40 commit fb943cb
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
15 changes: 15 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
lxml changelog
==============

Under development
==================

Features added
--------------

Bugs fixed
----------

* Diverting the error logging to Python's logging system was broken.

Other changes
-------------


2.2.2 (2009-06-21)
==================

Expand Down
75 changes: 53 additions & 22 deletions src/lxml/tests/test_etree.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,28 +427,6 @@ def test_parse_parser_type_error(self):
parse = self.etree.parse
self.assertRaises(TypeError, parse, 'notthere.xml', object())

def test_parse_error_logging(self):
parse = self.etree.parse
f = BytesIO('<a><b></c></b></a>')
self.etree.clear_error_log()
try:
parse(f)
logs = None
except SyntaxError:
e = sys.exc_info()[1]
logs = e.error_log
f.close()
self.assert_([ log for log in logs
if 'mismatch' in log.message ])
self.assert_([ log for log in logs
if 'PARSER' in log.domain_name])
self.assert_([ log for log in logs
if 'TAG_NAME_MISMATCH' in log.type_name ])
self.assert_([ log for log in logs
if 1 == log.line ])
self.assert_([ log for log in logs
if 15 == log.column ])

def test_iterparse_tree_comments(self):
# ET removes comments
iterparse = self.etree.iterparse
Expand Down Expand Up @@ -2942,6 +2920,58 @@ def test_write_file_gzipfile_parse(self):
self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
data)

class ETreeErrorLogTest(HelperTestCase):
etree = etree

def test_parse_error_logging(self):
parse = self.etree.parse
f = BytesIO('<a><b></c></b></a>')
self.etree.clear_error_log()
try:
parse(f)
logs = None
except SyntaxError:
e = sys.exc_info()[1]
logs = e.error_log
f.close()
self.assert_([ log for log in logs
if 'mismatch' in log.message ])
self.assert_([ log for log in logs
if 'PARSER' in log.domain_name])
self.assert_([ log for log in logs
if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
self.assert_([ log for log in logs
if 1 == log.line ])
self.assert_([ log for log in logs
if 15 == log.column ])

def _test_python_error_logging(self):
"""This can't really be tested as long as there isn't a way to
reset the logging setup ...
"""
parse = self.etree.parse

messages = []
class Logger(self.etree.PyErrorLog):
def log(self, entry, message, *args):
messages.append(message)

self.etree.use_global_python_log(Logger())
f = BytesIO('<a><b></c></b></a>')
try:
parse(f)
except SyntaxError:
pass
f.close()

self.assert_([ message for message in messages
if 'mismatch' in message ])
self.assert_([ message for message in messages
if ':PARSER:' in message])
self.assert_([ message for message in messages
if ':ERR_TAG_NAME_MISMATCH:' in message ])
self.assert_([ message for message in messages
if ':1:15:' in message ])

def test_suite():
suite = unittest.TestSuite()
Expand All @@ -2950,6 +2980,7 @@ def test_suite():
suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
suite.addTests(
[make_doctest('../../../doc/tutorial.txt')])
suite.addTests(
Expand Down
34 changes: 28 additions & 6 deletions src/lxml/xmlerror.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -401,14 +401,35 @@ cdef class PyErrorLog(_BaseErrorLog):
"""
return _ListErrorLog([], None, None)

def log(self, entry, message_format_string, *args):
def log(self, log_entry, message, *args):
u"""log(self, log_entry, message, *args)
Called by the .receive() method to log a _LogEntry instance to
the Python logging system. This handles the error level
mapping.
In the default implementation, the ``message`` argument
receives a complete log line, and there are no further
``args``. To change the message format, it is best to
override the .receive() method instead of this one.
"""
self._log(
self._map_level(entry.level, 0),
message_format_string, *args
self._map_level(log_entry.level, 0),
message, *args
)

def receive(self, entry):
self.log(entry, entry)
def receive(self, _LogEntry log_entry):
u"""receive(self, log_entry)
Receive a _LogEntry instance from the logging system. Calls
the .log() method with appropriate parameters::
self.log(log_entry, repr(log_entry))
You can override this method to provide your own log output
format.
"""
self.log(log_entry, repr(log_entry))

# thread-local, global list log to collect error output messages from
# libxml2/libxslt
Expand Down Expand Up @@ -436,7 +457,8 @@ cdef _setGlobalErrorLog(_BaseErrorLog log):
if thread_dict is NULL:
global __GLOBAL_ERROR_LOG
__GLOBAL_ERROR_LOG = log
(<object>thread_dict)[u"_GlobalErrorLog"] = log
else:
(<object>thread_dict)[u"_GlobalErrorLog"] = log

cdef __copyGlobalErrorLog():
u"Helper function for properties in exceptions."
Expand Down

0 comments on commit fb943cb

Please sign in to comment.