Rev 5226: Rather than adding another global thing, use a context manager to represent all the global state. in http://bazaar.launchpad.net/~lifeless/bzr/fix-terminal-spew

Robert Collins robertc at robertcollins.net
Mon Jun 21 02:21:57 BST 2010


At http://bazaar.launchpad.net/~lifeless/bzr/fix-terminal-spew

------------------------------------------------------------
revno: 5226
revision-id: robertc at robertcollins.net-20100621012156-jexseiyd7jfcdie2
parent: robertc at robertcollins.net-20100621012152-8imhqjie6q03f6ji
committer: Robert Collins <robertc at robertcollins.net>
branch nick: fix-terminal-spew
timestamp: Mon 2010-06-21 13:21:56 +1200
message:
  Rather than adding another global thing, use a context manager to represent all the global state.
=== modified file 'bzr'
--- a/bzr	2010-05-13 13:18:20 +0000
+++ b/bzr	2010-06-21 01:21:56 +0000
@@ -135,14 +135,13 @@
 
 
 if __name__ == '__main__':
-    bzrlib.initialize()
+    library_state = bzrlib.initialize()
     try:
         exit_val = bzrlib.commands.main()
-
         if profiling:
             profile_imports.log_stack_info(sys.stderr)
     finally:
-        bzrlib.clean_up()
+        library_state.__exit__(None, None, None)
 
     # By this point we really have completed everything we want to do, and
     # there's no point doing any additional cleanup.  Abruptly exiting here

=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py	2010-05-13 13:18:20 +0000
+++ b/bzrlib/__init__.py	2010-06-21 01:21:56 +0000
@@ -120,9 +120,59 @@
     return tests.test_suite()
 
 
-def initialize(
-    setup_ui=True,
-    stdin=None, stdout=None, stderr=None):
+class BzrLibraryState(object):
+    """The state about how bzrlib has been configured."""
+
+    def __init__(self, setup_ui=True, stdin=None, stdout=None, stderr=None):
+        """Create library start for normal use of bzrlib.
+
+        Most applications that embed bzrlib, including bzr itself, should just call
+        bzrlib.initialize(), but it is possible to use the state class directly.
+
+        More options may be added in future so callers should use named arguments.
+
+        :param setup_ui: If true (default) use a terminal UI; otherwise 
+            some other ui_factory must be assigned to `bzrlib.ui.ui_factory` by
+            the caller.
+        :param stdin, stdout, stderr: If provided, use these for terminal IO;
+            otherwise use the files in `sys`.
+        """
+        self.setup_ui = setup_ui
+        self.stdin = stdin
+        self.stdout = stdout
+        self.stderr = stderr
+
+    def __enter__(self):
+        # NB: This function tweaks so much global state it's hard to test it in
+        # isolation within the same interpreter.  It's not reached on normal
+        # in-process run_bzr calls.  If it's broken, we expect that
+        # TestRunBzrSubprocess may fail.
+        if version_info[3] == 'final':
+            from bzrlib.symbol_versioning import suppress_deprecation_warnings
+            suppress_deprecation_warnings(override=True)
+
+        import bzrlib.trace
+        bzrlib.trace.enable_default_logging()
+
+        if self.setup_ui:
+            import bzrlib.ui
+            stdin = self.stdin or sys.stdin
+            stdout = self.stdout or sys.stdout
+            stderr = self.stderr or sys.stderr
+            bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
+                stdin, stdout, stderr)
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        import bzrlib.ui
+        bzrlib.trace._flush_stdout_stderr()
+        bzrlib.trace._flush_trace()
+        import bzrlib.osutils
+        bzrlib.osutils.report_extension_load_failures()
+        bzrlib.ui.ui_factory.__exit__(None, None, None)
+        bzrlib.ui.ui_factory = None
+
+
+def initialize(setup_ui=True, stdin=None, stdout=None, stderr=None):
     """Set up everything needed for normal use of bzrlib.
 
     Most applications that embed bzrlib, including bzr itself, should call
@@ -131,42 +181,13 @@
     More options may be added in future so callers should use named arguments.
 
     :param setup_ui: If true (default) use a terminal UI; otherwise 
-        something else must be put into `bzrlib.ui.ui_factory`.
+        some other ui_factory must be assigned to `bzrlib.ui.ui_factory` by
+        the caller.
     :param stdin, stdout, stderr: If provided, use these for terminal IO;
         otherwise use the files in `sys`.
     """
     # TODO: mention this in a guide to embedding bzrlib
-    #
-    # NB: This function tweaks so much global state it's hard to test it in
-    # isolation within the same interpreter.  It's not reached on normal
-    # in-process run_bzr calls.  If it's broken, we expect that
-    # TestRunBzrSubprocess may fail.
-    
-    import bzrlib.trace
-
-    bzrlib.trace.enable_default_logging()
-
-    import bzrlib.ui
-    if stdin is None:
-        stdin = sys.stdin
-    if stdout is None:
-        stdout = sys.stdout
-    if stderr is None:
-        stderr = sys.stderr
-
-    if setup_ui:
-        bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
-            stdin, stdout, stderr)
-
-    if bzrlib.version_info[3] == 'final':
-        from bzrlib.symbol_versioning import suppress_deprecation_warnings
-        suppress_deprecation_warnings(override=True)
-
-def clean_up():
-    import bzrlib.ui
-    bzrlib.trace._flush_stdout_stderr()
-    bzrlib.trace._flush_trace()
-    import bzrlib.osutils
-    bzrlib.osutils.report_extension_load_failures()
-    bzrlib.ui.ui_factory.__exit__(None, None, None)
-    bzrlib.ui.ui_factory = None
+    library_state = BzrLibraryState(setup_ui=setup_ui, stdin=stdin,
+        stdout=stdout, stderr=stderr)
+    library_state.__enter__()
+    return library_state




More information about the bazaar-commits mailing list