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