Rev 6497: (gz) Encode progress task messages when written to a terminal (Martin in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/2.5/
Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Apr 30 11:12:00 UTC 2012
At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/2.5/
------------------------------------------------------------
revno: 6497 [merge]
revision-id: pqm at pqm.ubuntu.com-20120430111200-3zw0af8s9hhx877t
parent: pqm at pqm.ubuntu.com-20120430092759-upfwbgheb2udt89w
parent: martin.packman at canonical.com-20120430104404-0tqn17kcmiv793fh
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: 2.5
timestamp: Mon 2012-04-30 11:12:00 +0000
message:
(gz) Encode progress task messages when written to a terminal (Martin
Packman)
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_progress.py test_progress.py-20060308160359-978c397bc79b7fda
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/progress.py'
--- a/bzrlib/progress.py 2011-12-19 13:23:58 +0000
+++ b/bzrlib/progress.py 2012-04-30 09:14:35 +0000
@@ -58,7 +58,9 @@
Code updating the task may also set fields as hints about how to display
it: show_pct, show_spinner, show_eta, show_count, show_bar. UIs
will not necessarily respect all these fields.
-
+
+ The message given when updating a task must be unicode, not bytes.
+
:ivar update_latency: The interval (in seconds) at which the PB should be
updated. Setting this to zero suggests every update should be shown
synchronously.
@@ -106,6 +108,10 @@
self.msg)
def update(self, msg, current_cnt=None, total_cnt=None):
+ """Report updated task message and if relevent progress counters
+
+ The message given must be unicode, not a byte string.
+ """
self.msg = msg
self.current_cnt = current_cnt
if total_cnt:
=== modified file 'bzrlib/tests/test_progress.py'
--- a/bzrlib/tests/test_progress.py 2011-01-12 01:01:53 +0000
+++ b/bzrlib/tests/test_progress.py 2012-04-30 10:44:04 +0000
@@ -15,32 +15,20 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-from StringIO import StringIO
+from cStringIO import StringIO
+from bzrlib import (
+ tests,
+ )
from bzrlib.progress import (
ProgressTask,
)
-from bzrlib.tests import TestCase
from bzrlib.ui.text import (
TextProgressView,
)
-class _TTYStringIO(StringIO):
- """A helper class which makes a StringIO look like a terminal"""
-
- def isatty(self):
- return True
-
-
-class _NonTTYStringIO(StringIO):
- """Helper that implements isatty() but returns False"""
-
- def isatty(self):
- return False
-
-
-class TestTextProgressView(TestCase):
+class TestTextProgressView(tests.TestCase):
"""Tests for text display of progress bars.
These try to exercise the progressview independently of its construction,
@@ -49,13 +37,16 @@
# The ProgressTask now connects directly to the ProgressView, so we can
# check them independently of the factory or of the determination of what
# view to use.
-
+
+ def make_view_only(self, out, width=79):
+ view = TextProgressView(out)
+ view._avail_width = lambda: width
+ return view
+
def make_view(self):
out = StringIO()
- view = TextProgressView(out)
- view._avail_width = lambda: 79
- return out, view
-
+ return out, self.make_view_only(out)
+
def make_task(self, parent_task, view, msg, curr, total):
# would normally be done by UIFactory; is done here so that we don't
# have to have one.
@@ -168,3 +159,30 @@
' 123kB 100kB/s \\ start_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.. 2000/5000',
line)
self.assertEqual(len(line), 79)
+
+ def test_render_progress_unicode_enc_utf8(self):
+ out = tests.StringIOWrapper()
+ out.encoding = "utf-8"
+ view = self.make_view_only(out, 20)
+ task = self.make_task(None, view, u"\xa7", 0, 1)
+ view.show_progress(task)
+ self.assertEqual('\r/ \xc2\xa7 0/1 \r',
+ out.getvalue())
+
+ def test_render_progress_unicode_enc_missing(self):
+ out = StringIO()
+ self.assertRaises(AttributeError, getattr, out, "encoding")
+ view = self.make_view_only(out, 20)
+ task = self.make_task(None, view, u"\xa7", 0, 1)
+ view.show_progress(task)
+ self.assertEqual('\r/ ? 0/1 \r',
+ out.getvalue())
+
+ def test_render_progress_unicode_enc_none(self):
+ out = tests.StringIOWrapper()
+ out.encoding = None
+ view = self.make_view_only(out, 20)
+ task = self.make_task(None, view, u"\xa7", 0, 1)
+ view.show_progress(task)
+ self.assertEqual('\r/ ? 0/1 \r',
+ out.getvalue())
=== modified file 'bzrlib/tests/test_ui.py'
--- a/bzrlib/tests/test_ui.py 2011-10-08 19:01:59 +0000
+++ b/bzrlib/tests/test_ui.py 2012-04-30 08:59:57 +0000
@@ -31,7 +31,6 @@
)
from bzrlib.tests import (
fixtures,
- test_progress,
)
from bzrlib.ui import text as _mod_ui_text
from bzrlib.tests.testui import (
@@ -39,6 +38,20 @@
)
+class TTYStringIO(StringIO):
+ """A helper class which makes a StringIO look like a terminal"""
+
+ def isatty(self):
+ return True
+
+
+class NonTTYStringIO(StringIO):
+ """Helper that implements isatty() but returns False"""
+
+ def isatty(self):
+ return False
+
+
class TestUIConfiguration(tests.TestCaseWithTransport):
def test_output_encoding_configuration(self):
@@ -221,7 +234,7 @@
def test_text_factory_prompts_and_clears(self):
# a get_boolean call should clear the pb before prompting
- out = test_progress._TTYStringIO()
+ out = TTYStringIO()
self.overrideEnv('TERM', 'xterm')
factory = _mod_ui_text.TextUIFactory(
stdin=tests.StringIOWrapper("yada\ny\n"),
@@ -292,8 +305,8 @@
def test_quietness(self):
self.overrideEnv('BZR_PROGRESS_BAR', 'text')
ui_factory = _mod_ui_text.TextUIFactory(None,
- test_progress._TTYStringIO(),
- test_progress._TTYStringIO())
+ TTYStringIO(),
+ TTYStringIO())
self.assertIsInstance(ui_factory._progress_view,
_mod_ui_text.TextProgressView)
ui_factory.be_quiet(True)
@@ -358,7 +371,6 @@
def test_progress_construction(self):
"""TextUIFactory constructs the right progress view.
"""
- TTYStringIO = test_progress._TTYStringIO
FileStringIO = tests.StringIOWrapper
for (file_class, term, pb, expected_pb_class) in (
# on an xterm, either use them or not as the user requests,
@@ -391,9 +403,9 @@
def test_text_ui_non_terminal(self):
"""Even on non-ttys, make_ui_for_terminal gives a text ui."""
- stdin = test_progress._NonTTYStringIO('')
- stderr = test_progress._NonTTYStringIO()
- stdout = test_progress._NonTTYStringIO()
+ stdin = NonTTYStringIO('')
+ stderr = NonTTYStringIO()
+ stdout = NonTTYStringIO()
for term_type in ['dumb', None, 'xterm']:
self.overrideEnv('TERM', term_type)
uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
=== modified file 'bzrlib/ui/text.py'
--- a/bzrlib/ui/text.py 2011-12-18 12:46:49 +0000
+++ b/bzrlib/ui/text.py 2012-04-30 10:44:04 +0000
@@ -404,8 +404,13 @@
this only prints the stack from the nominated current task up to the root.
"""
- def __init__(self, term_file):
+ def __init__(self, term_file, encoding=None, errors="replace"):
self._term_file = term_file
+ if encoding is None:
+ self._encoding = getattr(term_file, "encoding", None) or "ascii"
+ else:
+ self._encoding = encoding
+ self._encoding_errors = errors
# true when there's output on the screen we may need to clear
self._have_output = False
self._last_transport_msg = ''
@@ -432,10 +437,12 @@
else:
return w - 1
- def _show_line(self, s):
- # sys.stderr.write("progress %r\n" % s)
+ def _show_line(self, u):
+ s = u.encode(self._encoding, self._encoding_errors)
width = self._avail_width()
if width is not None:
+ # GZ 2012-03-28: Counting bytes is wrong for calculating width of
+ # text but better than counting codepoints.
s = '%-*.*s' % (width, width, s)
self._term_file.write('\r' + s + '\r')
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt 2012-03-29 12:53:01 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt 2012-04-30 11:12:00 +0000
@@ -36,6 +36,9 @@
destination rather than the proxy when checking certificates.
(Martin Packman, #944696)
+* Fix UnicodeEncodeError when translated progress task messages contain
+ non-ascii text. (Martin Packman, #966934)
+
* Fixed merge tool availability checking and invocation to search the
Windows App Path registry in addition to the PATH. (Gordon Tyler, #939605)
More information about the bazaar-commits
mailing list