Rev 5025: (mbp) Add bzrlib.initialize in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Feb 11 02:16:43 GMT 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5025 [merge]
revision-id: pqm at pqm.ubuntu.com-20100211021642-eitum30b2e09oalf
parent: pqm at pqm.ubuntu.com-20100210222403-ie0c64ofqz81pq2n
parent: mbp at sourcefrog.net-20100211011346-gilmqchyuik99u2n
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2010-02-11 02:16:42 +0000
message:
  (mbp) Add bzrlib.initialize
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzr                            bzr.py-20050313053754-5485f144c7006fa6
  bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
  bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
  bzrlib/trace.py                trace.py-20050309040759-c8ed824bdcd4748a
=== modified file 'NEWS'
--- a/NEWS	2010-02-10 22:24:03 +0000
+++ b/NEWS	2010-02-11 01:13:46 +0000
@@ -49,6 +49,11 @@
 API Changes
 ***********
 
+* New ``bzrlib.initialize`` is recommended for programs using bzrlib to 
+  run when starting up; it sets up several things that previously needed
+  to be done separately.
+  (Martin Pool, #507710)
+
 * Remove unused ``CommandFailed`` exception.
   (Martin Pool)
 

=== modified file 'bzr'
--- a/bzr	2010-01-21 22:23:29 +0000
+++ b/bzr	2010-02-10 00:31:24 +0000
@@ -1,6 +1,6 @@
 #! /usr/bin/env python
 
-# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Canonical Ltd
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -138,16 +138,12 @@
 
 
 if __name__ == '__main__':
-    bzrlib.trace.enable_default_logging()
+    bzrlib.initialize()
     exit_val = bzrlib.commands.main()
 
     if profiling:
         profile_imports.log_stack_info(sys.stderr)
 
-    # run anything registered by atexit, because it won't be run in the normal
-    # way
-    sys.exitfunc()
-
     # By this point we really have completed everything we want to do, and
     # there's no point doing any additional cleanup.  Abruptly exiting here
     # stops any background threads getting into trouble as code is unloaded,
@@ -155,18 +151,7 @@
     # are just about to be discarded anyhow.  This does mean that atexit hooks
     # won't run but we don't use them.  Also file buffers won't be flushed,
     # but our policy is to always close files from a finally block. -- mbp 20070215
-    try:
-        sys.stdout.flush()
-        sys.stderr.flush()
-    except IOError, e:
-        import errno
-        if e.errno in [errno.EINVAL, errno.EPIPE]:
-            pass
-        else:
-            raise
-    if bzrlib.trace._trace_file:
-        # this is also _bzr_log
-        bzrlib.trace._trace_file.flush()
+    sys.exitfunc()
     os._exit(exit_val)
 else:
     raise ImportError("The bzr script cannot be imported.")

=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py	2010-01-29 11:09:30 +0000
+++ b/bzrlib/__init__.py	2010-02-10 00:31:24 +0000
@@ -116,3 +116,52 @@
 def test_suite():
     import tests
     return tests.test_suite()
+
+
+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
+    this function to initialize various subsystems.  
+
+    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`.
+    :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 atexit
+    import bzrlib.trace
+
+    bzrlib.trace.enable_default_logging()
+    atexit.register(bzrlib.trace._flush_stdout_stderr)
+    atexit.register(bzrlib.trace._flush_trace)
+
+    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)
+
+    import bzrlib.osutils
+    atexit.register(osutils.report_extension_load_failures)

=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py	2010-02-10 17:52:08 +0000
+++ b/bzrlib/commands.py	2010-02-11 01:13:46 +0000
@@ -59,7 +59,6 @@
     deprecated_function,
     deprecated_in,
     deprecated_method,
-    suppress_deprecation_warnings,
     )
 
 
@@ -1078,25 +1077,12 @@
         "bzr plugin-provider-db check")
 
 
-def main(argv=None):
-    """Main entry point of command-line interface.
-
-    :param argv: list of unicode command-line arguments similar to sys.argv.
-        argv[0] is script name usually, it will be ignored.
-        Don't pass here sys.argv because this list contains plain strings
-        and not unicode; pass None instead.
-
-    :return: exit code of bzr command.
-    """
-    import bzrlib.ui
-    bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
-        sys.stdin, sys.stdout, sys.stderr)
-
-    # Is this a final release version? If so, we should suppress warnings
-    if bzrlib.version_info[3] == 'final':
-        suppress_deprecation_warnings(override=True)
+
+def _specified_or_unicode_argv(argv):
+    # For internal or testing use, argv can be passed.  Otherwise, get it from
+    # the process arguments in a unicode-safe way.
     if argv is None:
-        argv = osutils.get_unicode_argv()
+        return osutils.get_unicode_argv()
     else:
         new_argv = []
         try:
@@ -1108,12 +1094,26 @@
                     new_argv.append(a.decode('ascii'))
         except UnicodeDecodeError:
             raise errors.BzrError("argv should be list of unicode strings.")
-        argv = new_argv
+        return new_argv
+
+
+def main(argv=None):
+    """Main entry point of command-line interface.
+
+    Typically `bzrlib.initialize` should be called first.
+
+    :param argv: list of unicode command-line arguments similar to sys.argv.
+        argv[0] is script name usually, it will be ignored.
+        Don't pass here sys.argv because this list contains plain strings
+        and not unicode; pass None instead.
+
+    :return: exit code of bzr command.
+    """
+    argv = _specified_or_unicode_argv(argv)
     ret = run_bzr_catch_errors(argv)
     bzrlib.ui.ui_factory.log_transport_activity(
         display=('bytes' in debug.debug_flags))
     trace.mutter("return code %d", ret)
-    osutils.report_extension_load_failures()
     return ret
 
 
@@ -1123,6 +1123,7 @@
     This function assumed that that UI layer is setup, that symbol deprecations
     are already applied, and that unicode decoding has already been performed on argv.
     """
+    # done here so that they're covered for every test run
     install_bzr_command_hooks()
     return exception_to_return_code(run_bzr, argv)
 
@@ -1133,6 +1134,7 @@
     This is used for the test suite, and might be useful for other programs
     that want to wrap the commandline interface.
     """
+    # done here so that they're covered for every test run
     install_bzr_command_hooks()
     try:
         return run_bzr(argv)
@@ -1188,7 +1190,3 @@
             yield provider
 
 command_providers_registry = ProvidersRegistry()
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))

=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py	2010-01-15 03:29:33 +0000
+++ b/bzrlib/trace.py	2010-02-10 00:31:24 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Canonical Ltd
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -501,3 +501,23 @@
     """Report an exception that probably indicates a bug in bzr"""
     from bzrlib.crash import report_bug
     report_bug(exc_info, err_file)
+
+
+def _flush_stdout_stderr():
+    # installed into an atexit hook by bzrlib.initialize()
+    try:
+        sys.stdout.flush()
+        sys.stderr.flush()
+    except IOError, e:
+        import errno
+        if e.errno in [errno.EINVAL, errno.EPIPE]:
+            pass
+        else:
+            raise
+
+
+def _flush_trace():
+    # run from atexit hook
+    global _trace_file
+    if _trace_file:
+        _trace_file.flush()




More information about the bazaar-commits mailing list