Rev 5324: (lifeless) Make the trace module managed more cleanly by BzrLibraryState. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Jun 28 05:42:09 BST 2010
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5324 [merge]
revision-id: pqm at pqm.ubuntu.com-20100628044207-67md0bfc3ojod6of
parent: pqm at pqm.ubuntu.com-20100628031248-icctusovofhlk7z9
parent: robertc at robertcollins.net-20100628032326-nwwjuav8wuby7r63
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2010-06-28 05:42:07 +0100
message:
(lifeless) Make the trace module managed more cleanly by BzrLibraryState.
(Robert Collins)
added:
bzrlib/library_state.py library_state.py-20100625053036-962zdkiik8k6m5jx-1
bzrlib/tests/test_library_state.py test_library_state.p-20100625052815-tig59sysysgqd6wh-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/__init__.py __init__.py-20050309040759-33e65acf91bbcd5d
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/symbol_versioning.py symbol_versioning.py-20060105104851-9ecf8af605d15a80
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
bzrlib/tests/fixtures.py fixtures.py-20100514150609-1kpa1jqaciel01wn-1
bzrlib/tests/test_osutils_encodings.py test_osutils_encodin-20061226013130-kkp732tpt3lm91vv-1
bzrlib/tests/test_symbol_versioning.py test_symbol_versioning.py-20060105104851-51d7722c2018d42b
bzrlib/tests/test_trace.py testtrace.py-20051110225523-a21117fc7a07eeff
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
=== modified file 'NEWS'
--- a/NEWS 2010-06-28 03:12:48 +0000
+++ b/NEWS 2010-06-28 03:23:26 +0000
@@ -180,12 +180,22 @@
Internals
*********
+* ``bzrlib.osutils.get_terminal_encoding`` will now only mutter its
+ selection when explicitly requested; this avoids many duplicate calls
+ being logged when helpers, wrappers and older code that manually calls
+ it are executed it is now logged deliberately by the ui setup code.
+ (Robert Collins)
+
* Improved ``bzrlib.urlutils`` to handle lp:foo/bar URLs. (Gordon Tyler)
* ``bzrlib._c_static_tuple.StaticTuple`` now implements ``__sizeof__``, so
that ``sys.getsizeof`` and other memory analysis tools will report more
accurate results. (Andrew Bennetts)
+* The symbol_versioning module can now cleanup after itself -
+ ``suppress_deprecation_warnings`` now returns a cleanup function.
+ (Robert Collins)
+
Testing
*******
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py 2010-06-21 20:03:23 +0000
+++ b/bzrlib/__init__.py 2010-06-26 02:15:26 +0000
@@ -131,12 +131,12 @@
# bzr has various bits of global state that are slowly being eliminated.
# This variable is intended to permit any new state-like things to be attached
-# to a BzrLibraryState object rather than getting new global variables that
-# need to be hunted down. Accessing the current BzrLibraryState through this
-# variable is not encouraged: it is better to pass it around as part of the
-# context of an operation than to look it up directly, but when that is too
-# hard, it is better to use this variable than to make a branch new global
-# variable.
+# to a library_state.BzrLibraryState object rather than getting new global
+# variables that need to be hunted down. Accessing the current BzrLibraryState
+# through this variable is not encouraged: it is better to pass it around as
+# part of the context of an operation than to look it up directly, but when
+# that is too hard, it is better to use this variable than to make a branch new
+# global variable.
# If using this variable by looking it up (because it can't be easily obtained)
# it is important to store the reference you get, rather than looking it up
# repeatedly; that way your code will behave properly in the bzrlib test suite
@@ -144,82 +144,6 @@
global_state = None
-class BzrLibraryState(object):
- """The state about how bzrlib has been configured.
-
- :ivar saved_state: The bzrlib.global_state at the time __enter__ was
- called.
- :ivar cleanups: An ObjectWithCleanups which can be used for cleanups that
- should occur when the use of bzrlib is completed. This is initialised
- in __enter__ and executed in __exit__.
- """
-
- 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.
-
- BzrLibraryState implements the Python 2.5 Context Manager protocol
- PEP343, and can be used with the with statement. Upon __enter__ the
- global variables in use by bzr are set, and they are cleared on
- __exit__.
-
- :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.cleanup
- import bzrlib.trace
- self.cleanups = bzrlib.cleanup.ObjectWithCleanups()
- 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)
- global global_state
- self.saved_state = global_state
- global_state = self
- return self # This is bound to the 'as' clause in a with statement.
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.cleanups.cleanup_now()
- 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
- global global_state
- global_state = self.saved_state
- return False # propogate exceptions.
-
-
def initialize(setup_ui=True, stdin=None, stdout=None, stderr=None):
"""Set up everything needed for normal use of bzrlib.
@@ -239,8 +163,17 @@
otherwise stopping use of bzrlib. Advanced callers can use
BzrLibraryState directly.
"""
- return BzrLibraryState(setup_ui=setup_ui, stdin=stdin,
- stdout=stdout, stderr=stderr)
+ import bzrlib.library_state
+ if setup_ui:
+ import bzrlib.ui
+ stdin = stdin or sys.stdin
+ stdout = stdout or sys.stdout
+ stderr = stderr or sys.stderr
+ ui_factory = bzrlib.ui.make_ui_for_terminal(stdin, stdout, stderr)
+ else:
+ ui_factory = None
+ tracer = bzrlib.trace.DefaultConfig()
+ return bzrlib.library_state.BzrLibraryState(ui=ui_factory, trace=tracer)
def test_suite():
=== added file 'bzrlib/library_state.py'
--- a/bzrlib/library_state.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/library_state.py 2010-06-26 01:07:16 +0000
@@ -0,0 +1,103 @@
+# Copyright (C) 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""The core state needed to make use of bzr is managed here."""
+
+__all__ = [
+ 'BzrLibraryState',
+ ]
+
+import sys
+
+import bzrlib
+
+
+class BzrLibraryState(object):
+ """The state about how bzrlib has been configured.
+
+ This is the core state needed to make use of bzr. The current instance is
+ currently always exposed as bzrlib.global_state, but we desired to move
+ to a point where no global state is needed at all.
+
+ :ivar saved_state: The bzrlib.global_state at the time __enter__ was
+ called.
+ :ivar cleanups: An ObjectWithCleanups which can be used for cleanups that
+ should occur when the use of bzrlib is completed. This is initialised
+ in __enter__ and executed in __exit__.
+ """
+
+ def __init__(self, ui, trace):
+ """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. The initialize() function provides sensible defaults for a
+ CLI program, such as a text UI factory.
+
+ More options may be added in future so callers should use named
+ arguments.
+
+ BzrLibraryState implements the Python 2.5 Context Manager protocol
+ PEP343, and can be used with the with statement. Upon __enter__ the
+ global variables in use by bzr are set, and they are cleared on
+ __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
+ # 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
+ if bzrlib.version_info[3] == 'final':
+ from bzrlib.symbol_versioning import suppress_deprecation_warnings
+ warning_cleanup = suppress_deprecation_warnings(override=True)
+ else:
+ warning_cleanup = None
+
+ import bzrlib.cleanup
+ self.cleanups = bzrlib.cleanup.ObjectWithCleanups()
+ if warning_cleanup:
+ self.cleanups.add_cleanup(warning_cleanup)
+ self._trace.__enter__()
+
+ self._orig_ui = bzrlib.ui.ui_factory
+ bzrlib.ui.ui_factory = self._ui
+ self._ui.__enter__()
+
+ self.saved_state = bzrlib.global_state
+ bzrlib.global_state = self
+ return self # This is bound to the 'as' clause in a with statement.
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.cleanups.cleanup_now()
+ import bzrlib.ui
+ bzrlib.trace._flush_stdout_stderr()
+ bzrlib.trace._flush_trace()
+ 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
+ return False # propogate exceptions.
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2010-06-18 10:57:20 +0000
+++ b/bzrlib/osutils.py 2010-06-25 20:34:05 +0000
@@ -441,7 +441,7 @@
getcwd = _mac_getcwd
-def get_terminal_encoding():
+def get_terminal_encoding(trace=False):
"""Find the best encoding for printing to the screen.
This attempts to check both sys.stdout and sys.stdin to see
@@ -453,6 +453,8 @@
On my standard US Windows XP, the preferred encoding is
cp1252, but the console is cp437
+
+ :param trace: If True trace the selected encoding via mutter().
"""
from bzrlib.trace import mutter
output_encoding = getattr(sys.stdout, 'encoding', None)
@@ -460,17 +462,22 @@
input_encoding = getattr(sys.stdin, 'encoding', None)
if not input_encoding:
output_encoding = get_user_encoding()
- mutter('encoding stdout as osutils.get_user_encoding() %r',
+ if trace:
+ mutter('encoding stdout as osutils.get_user_encoding() %r',
output_encoding)
else:
output_encoding = input_encoding
- mutter('encoding stdout as sys.stdin encoding %r', output_encoding)
+ if trace:
+ mutter('encoding stdout as sys.stdin encoding %r',
+ output_encoding)
else:
- mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
+ if trace:
+ mutter('encoding stdout as sys.stdout encoding %r', output_encoding)
if output_encoding == 'cp0':
# invalid encoding (cp0 means 'no codepage' on Windows)
output_encoding = get_user_encoding()
- mutter('cp0 is invalid encoding.'
+ if trace:
+ mutter('cp0 is invalid encoding.'
' encoding stdout as osutils.get_user_encoding() %r',
output_encoding)
# check encoding
=== modified file 'bzrlib/symbol_versioning.py'
--- a/bzrlib/symbol_versioning.py 2009-09-15 02:28:34 +0000
+++ b/bzrlib/symbol_versioning.py 2010-06-25 06:11:21 +0000
@@ -314,6 +314,7 @@
:param override: If True, always set the ignore, if False, only set the
ignore if there isn't already a filter.
+ :return: A callable to remove the new warnings this added.
"""
import warnings
if not override and _check_for_filter(error_only=False):
@@ -321,6 +322,10 @@
# then skip it.
return
warnings.filterwarnings('ignore', category=DeprecationWarning)
+ filter = warnings.filters[0]
+ def cleanup():
+ warnings.filters.remove(filter)
+ return cleanup
def activate_deprecation_warnings(override=True):
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2010-06-25 01:49:49 +0000
+++ b/bzrlib/tests/__init__.py 2010-06-25 06:12:56 +0000
@@ -3733,6 +3733,7 @@
'bzrlib.tests.test_knit',
'bzrlib.tests.test_lazy_import',
'bzrlib.tests.test_lazy_regex',
+ 'bzrlib.tests.test_library_state',
'bzrlib.tests.test_lock',
'bzrlib.tests.test_lockable_files',
'bzrlib.tests.test_lockdir',
=== modified file 'bzrlib/tests/blackbox/test_commit.py'
--- a/bzrlib/tests/blackbox/test_commit.py 2010-06-11 07:32:12 +0000
+++ b/bzrlib/tests/blackbox/test_commit.py 2010-06-28 02:41:22 +0000
@@ -129,7 +129,7 @@
# by ui.text.show_warning
default_get_terminal_enc = osutils.get_terminal_encoding
try:
- osutils.get_terminal_encoding = lambda: 'ascii'
+ osutils.get_terminal_encoding = lambda trace=None: 'ascii'
file_name = u'foo\u1234'
open(file_name, 'w').write('hello world')
self.run_bzr(['add'])
=== 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.
=== added file 'bzrlib/tests/test_library_state.py'
--- a/bzrlib/tests/test_library_state.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_library_state.py 2010-06-26 01:07:16 +0000
@@ -0,0 +1,52 @@
+# Copyright (C) 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for BzrLibraryState."""
+
+import bzrlib
+from bzrlib import (
+ library_state,
+ tests,
+ ui as _mod_ui
+ )
+from bzrlib.tests import fixtures
+
+
+# TODO: once sufficiently cleaned up this should be able to be TestCase.
+class TestLibraryState(tests.TestCaseWithTransport):
+
+ def test_ui_is_used(self):
+ ui = _mod_ui.SilentUIFactory()
+ state = library_state.BzrLibraryState(
+ ui=ui, trace=fixtures.RecordingContextManager())
+ orig_ui = _mod_ui.ui_factory
+ state.__enter__()
+ try:
+ self.assertEqual(ui, _mod_ui.ui_factory)
+ 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_osutils_encodings.py'
--- a/bzrlib/tests/test_osutils_encodings.py 2010-01-25 17:48:22 +0000
+++ b/bzrlib/tests/test_osutils_encodings.py 2010-06-25 20:34:05 +0000
@@ -114,6 +114,26 @@
# and in the worst case, use osutils.get_user_encoding()
self.assertEqual('user_encoding', osutils.get_terminal_encoding())
+ def test_get_terminal_encoding_silent(self):
+ self.make_wrapped_streams('stdout_encoding',
+ 'stderr_encoding',
+ 'stdin_encoding')
+ # Calling get_terminal_encoding should not mutter when silent=True is
+ # passed.
+ log = self.get_log()
+ osutils.get_terminal_encoding()
+ self.assertEqual(log, self.get_log())
+
+ def test_get_terminal_encoding_trace(self):
+ self.make_wrapped_streams('stdout_encoding',
+ 'stderr_encoding',
+ 'stdin_encoding')
+ # Calling get_terminal_encoding should not mutter when silent=True is
+ # passed.
+ log = self.get_log()
+ osutils.get_terminal_encoding(trace=True)
+ self.assertNotEqual(log, self.get_log())
+
def test_terminal_cp0(self):
# test cp0 encoding (Windows returns cp0 when there is no encoding)
self.make_wrapped_streams('cp0',
=== modified file 'bzrlib/tests/test_symbol_versioning.py'
--- a/bzrlib/tests/test_symbol_versioning.py 2010-04-23 08:51:52 +0000
+++ b/bzrlib/tests/test_symbol_versioning.py 2010-06-25 06:11:21 +0000
@@ -241,6 +241,11 @@
symbol_versioning.suppress_deprecation_warnings()
self.assertFirstWarning('ignore', DeprecationWarning)
+ def test_set_restore_filters(self):
+ original_filters = warnings.filters[:]
+ symbol_versioning.suppress_deprecation_warnings()()
+ self.assertEqual(original_filters, warnings.filters)
+
def test_suppress_deprecation_with_warning_filter(self):
"""don't suppress if we already have a filter"""
warnings.filterwarnings('error', category=Warning)
=== 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-21 03:15:55 +0000
+++ b/bzrlib/trace.py 2010-06-28 02:41:22 +0000
@@ -306,26 +306,27 @@
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.
"""
- # Do this before we open the log file, so we prevent
- # get_terminal_encoding() from mutter()ing multiple times
- term_encoding = osutils.get_terminal_encoding()
start_time = osutils.format_local_date(_bzr_log_start_time,
timezone='local')
# create encoded wrapper around stderr
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
# handler, writing only at level info and with encoding
+ term_encoding = osutils.get_terminal_encoding()
writer_factory = codecs.getwriter(term_encoding)
encoded_stderr = writer_factory(sys.stderr, errors='replace')
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):
@@ -367,7 +368,8 @@
def pop_log_file((magic, old_handlers, new_handler, old_trace_file, new_trace_file)):
"""Undo changes to logging/tracing done by _push_log_file.
- This flushes, but does not close the trace file.
+ This flushes, but does not close the trace file (so that anything that was
+ in it is output.
Takes the memento returned from _push_log_file."""
global _trace_file
@@ -378,7 +380,8 @@
# file will likely already be closed underneath.
new_handler.close()
bzr_logger.handlers = old_handlers
- new_trace_file.flush()
+ if new_trace_file is not None:
+ new_trace_file.flush()
def log_exception_quietly():
@@ -557,3 +560,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.
=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py 2010-06-23 08:14:21 +0000
+++ b/bzrlib/ui/__init__.py 2010-06-25 20:34:05 +0000
@@ -192,7 +192,7 @@
encoding = config.GlobalConfig().get_user_option(
'output_encoding')
if encoding is None:
- encoding = osutils.get_terminal_encoding()
+ encoding = osutils.get_terminal_encoding(trace=True)
if encoding_type is None:
encoding_type = 'replace'
out_stream = self._make_output_stream_explicit(encoding, encoding_type)
More information about the bazaar-commits
mailing list