Rev 5325: Make bzrlib startup use a trace context manager. in http://bazaar.launchpad.net/~lifeless/bzr/globalzapping
Robert Collins
robertc at robertcollins.net
Sat Jun 26 02:07:18 BST 2010
At http://bazaar.launchpad.net/~lifeless/bzr/globalzapping
------------------------------------------------------------
revno: 5325
revision-id: robertc at robertcollins.net-20100626010716-jowzrldm4ntsaki2
parent: robertc at robertcollins.net-20100625203405-c74lxd3enklhaqf9
committer: Robert Collins <robertc at robertcollins.net>
branch nick: globalzapping
timestamp: Sat 2010-06-26 11:07:16 +1000
message:
Make bzrlib startup use a trace context manager.
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py 2010-06-25 06:23:08 +0000
+++ b/bzrlib/__init__.py 2010-06-26 01:07:16 +0000
@@ -35,6 +35,7 @@
# Keep track of when bzrlib was first imported, so that we can give rough
# timestamps relative to program start in the log file kept by bzrlib.trace.
+# XXX: GLOBAL
_start_time = time.time()
import sys
@@ -172,7 +173,8 @@
ui_factory = bzrlib.ui.make_ui_for_terminal(stdin, stdout, stderr)
else:
ui_factory = None
- return bzrlib.library_state.BzrLibraryState(ui=ui_factory)
+ tracer = bzrlib.trace.DefaultConfig()
+ return bzrlib.library_state.BzrLibraryState(ui=ui_factory, trace=tracer)
def test_suite():
=== modified file 'bzrlib/library_state.py'
--- a/bzrlib/library_state.py 2010-06-25 06:23:08 +0000
+++ b/bzrlib/library_state.py 2010-06-26 01:07:16 +0000
@@ -39,7 +39,7 @@
in __enter__ and executed in __exit__.
"""
- def __init__(self, ui=None):
+ def __init__(self, ui, trace):
"""Create library start for normal use of bzrlib.
Most applications that embed bzrlib, including bzr itself, should just
@@ -56,8 +56,11 @@
__exit__.
:param ui: A bzrlib.ui.ui_factory to use.
+ :param trace: A bzrlib.trace.Config context manager to use, perhaps
+ bzrlib.trace.DefaultConfig.
"""
self._ui = ui
+ self._trace = trace
def __enter__(self):
# NB: This function tweaks so much global state it's hard to test it in
@@ -72,11 +75,10 @@
warning_cleanup = None
import bzrlib.cleanup
- import bzrlib.trace
self.cleanups = bzrlib.cleanup.ObjectWithCleanups()
if warning_cleanup:
self.cleanups.add_cleanup(warning_cleanup)
- bzrlib.trace.enable_default_logging()
+ self._trace.__enter__()
self._orig_ui = bzrlib.ui.ui_factory
bzrlib.ui.ui_factory = self._ui
@@ -94,6 +96,7 @@
import bzrlib.osutils
bzrlib.osutils.report_extension_load_failures()
self._ui.__exit__(None, None, None)
+ self._trace.__exit__(None, None, None)
bzrlib.ui.ui_factory = self._orig_ui
global global_state
global_state = self.saved_state
=== modified file 'bzrlib/tests/fixtures.py'
--- a/bzrlib/tests/fixtures.py 2010-06-21 22:29:38 +0000
+++ b/bzrlib/tests/fixtures.py 2010-06-26 01:07:16 +0000
@@ -82,3 +82,18 @@
else:
e = [n for (n, u) in interesting_encodings]
return itertools.cycle(iter(e))
+
+
+class RecordingContextManager(object):
+ """A context manager that records."""
+
+ def __init__(self):
+ self._calls = []
+
+ def __enter__(self):
+ self._calls.append('__enter__')
+ return self # This is bound to the 'as' clause in a with statement.
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._calls.append('__exit__')
+ return False # propogate exceptions.
=== modified file 'bzrlib/tests/test_library_state.py'
--- a/bzrlib/tests/test_library_state.py 2010-06-25 06:23:08 +0000
+++ b/bzrlib/tests/test_library_state.py 2010-06-26 01:07:16 +0000
@@ -22,6 +22,7 @@
tests,
ui as _mod_ui
)
+from bzrlib.tests import fixtures
# TODO: once sufficiently cleaned up this should be able to be TestCase.
@@ -29,7 +30,8 @@
def test_ui_is_used(self):
ui = _mod_ui.SilentUIFactory()
- state = library_state.BzrLibraryState(ui=ui)
+ state = library_state.BzrLibraryState(
+ ui=ui, trace=fixtures.RecordingContextManager())
orig_ui = _mod_ui.ui_factory
state.__enter__()
try:
@@ -37,3 +39,14 @@
finally:
state.__exit__(None, None, None)
self.assertEqual(orig_ui, _mod_ui.ui_factory)
+
+ def test_trace_context(self):
+ tracer = fixtures.RecordingContextManager()
+ ui = _mod_ui.SilentUIFactory()
+ state = library_state.BzrLibraryState(ui=ui, trace=tracer)
+ state.__enter__()
+ try:
+ self.assertEqual(['__enter__'], tracer._calls)
+ finally:
+ state.__exit__(None, None, None)
+ self.assertEqual(['__enter__', '__exit__'], tracer._calls)
=== modified file 'bzrlib/tests/test_trace.py'
--- a/bzrlib/tests/test_trace.py 2010-05-20 21:45:02 +0000
+++ b/bzrlib/tests/test_trace.py 2010-06-26 01:07:16 +0000
@@ -333,3 +333,21 @@
_rollover_trace_maybe(temp_log_name)
# should have been rolled over
self.assertFalse(os.access(temp_log_name, os.R_OK))
+
+
+class TestTraceConfiguration(TestCaseInTempDir):
+
+ def test_default_config(self):
+ config = trace.DefaultConfig()
+ self.overrideAttr(trace, "_bzr_log_filename", None)
+ trace._bzr_log_filename = None
+ expected_filename = trace._get_bzr_log_filename()
+ self.assertEqual(None, trace._bzr_log_filename)
+ config.__enter__()
+ try:
+ # Should have entered and setup a default filename.
+ self.assertEqual(expected_filename, trace._bzr_log_filename)
+ finally:
+ config.__exit__(None, None, None)
+ # Should have exited and cleaned up.
+ self.assertEqual(None, trace._bzr_log_filename)
=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py 2010-06-25 20:34:05 +0000
+++ b/bzrlib/trace.py 2010-06-26 01:07:16 +0000
@@ -306,6 +306,8 @@
logging.getLogger("bzr").
Output can be redirected away by calling _push_log_file.
+
+ :return: A memento from push_log_file for restoring the log state.
"""
start_time = osutils.format_local_date(_bzr_log_start_time,
timezone='local')
@@ -313,7 +315,7 @@
bzr_log_file = _open_bzr_log()
if bzr_log_file is not None:
bzr_log_file.write(start_time.encode('utf-8') + '\n')
- push_log_file(bzr_log_file,
+ memento = push_log_file(bzr_log_file,
r'[%(process)5d] %(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
r'%Y-%m-%d %H:%M:%S')
# after hooking output into bzr_log, we also need to attach a stderr
@@ -324,6 +326,7 @@
stderr_handler = logging.StreamHandler(encoded_stderr)
stderr_handler.setLevel(logging.INFO)
logging.getLogger('bzr').addHandler(stderr_handler)
+ return memento
def push_log_file(to_file, log_format=None, date_format=None):
@@ -555,3 +558,36 @@
global _trace_file
if _trace_file:
_trace_file.flush()
+
+
+class Config(object):
+ """Configuration of message tracing in bzrlib.
+
+ This implements the context manager protocol and should manage any global
+ variables still used. The default config used is DefaultConfig, but
+ embedded uses of bzrlib may wish to use a custom manager.
+ """
+
+ def __enter__(self):
+ return self # This is bound to the 'as' clause in a with statement.
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ return False # propogate exceptions.
+
+
+class DefaultConfig(Config):
+ """A default configuration for tracing of messages in bzrlib.
+
+ This implements the context manager protocol.
+ """
+
+ def __enter__(self):
+ self._original_filename = _bzr_log_filename
+ self._original_state = enable_default_logging()
+ return self # This is bound to the 'as' clause in a with statement.
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ pop_log_file(self._original_state)
+ global _bzr_log_filename
+ _bzr_log_filename = self._original_filename
+ return False # propogate exceptions.
More information about the bazaar-commits
mailing list