Merge lp:~gz/brz/mutter_unicode into lp:brz

Proposed by Martin Packman
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~gz/brz/mutter_unicode
Merge into: lp:brz
Diff against target: 208 lines (+54/-37)
5 files modified
breezy/bzr/remote.py (+5/-6)
breezy/tests/test_export_pot.py (+1/-1)
breezy/tests/test_trace.py (+20/-14)
breezy/trace.py (+22/-16)
python3.passing (+6/-0)
To merge this branch: bzr merge lp:~gz/brz/mutter_unicode
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+348789@code.launchpad.net

Commit message

Make mutter format with unicode

Description of the change

Previously making everything utf-8 encoded bytes before interpolating was most robust, but better particularly with Python 3 to leave as unicode till all formatting has happened.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Merci!

review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Running landing tests failed
https://ci.breezy-vcs.org/job/land-brz/217/

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Running landing tests failed
https://ci.breezy-vcs.org/job/land-brz/221/

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Running landing tests failed
https://ci.breezy-vcs.org/job/land-brz/226/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/bzr/remote.py'
2--- breezy/bzr/remote.py 2018-06-30 22:12:58 +0000
3+++ breezy/bzr/remote.py 2018-06-30 23:03:12 +0000
4@@ -4262,8 +4262,8 @@
5 def find(name):
6 try:
7 return context[name]
8- except KeyError as key_err:
9- mutter('Missing key %r in context %r', key_err.args[0], context)
10+ except KeyError:
11+ mutter('Missing key \'%s\' in context %r', name, context)
12 raise err
13 def get_path():
14 """Get the path from the context if present, otherwise use first error
15@@ -4271,12 +4271,11 @@
16 """
17 try:
18 return context['path'].decode('utf-8')
19- except KeyError as key_err:
20+ except KeyError:
21 try:
22 return err.error_args[0].decode('utf-8')
23- except IndexError as idx_err:
24- mutter(
25- 'Missing key %r in context %r', key_err.args[0], context)
26+ except IndexError:
27+ mutter('Missing key \'path\' in context %r', context)
28 raise err
29 if not isinstance(err.error_verb, bytes):
30 raise TypeError(err.error_verb)
31
32=== modified file 'breezy/tests/test_export_pot.py'
33--- breezy/tests/test_export_pot.py 2018-06-19 19:44:00 +0000
34+++ breezy/tests/test_export_pot.py 2018-06-30 23:03:12 +0000
35@@ -221,7 +221,7 @@
36 self.check_context(context2A, path, 4)
37 context2B = context1.from_string("not there")
38 self.check_context(context2B, path, 21)
39- self.assertContainsRe(self.get_log(), "String 'not there' not found")
40+ self.assertContainsRe(self.get_log(), "String b?'not there' not found")
41
42
43 class TestWriteOption(tests.TestCase):
44
45=== modified file 'breezy/tests/test_trace.py'
46--- breezy/tests/test_trace.py 2017-10-27 00:18:42 +0000
47+++ breezy/tests/test_trace.py 2018-06-30 23:03:12 +0000
48@@ -197,6 +197,12 @@
49 log = self.get_log()
50 self.assertContainsRe(log, 'the unicode character')
51
52+ def test_trace_argument_exception(self):
53+ err = Exception('an error')
54+ mutter(u'can format stringable classes %s', err)
55+ log = self.get_log()
56+ self.assertContainsRe(log, 'can format stringable classes an error')
57+
58 def test_report_broken_pipe(self):
59 try:
60 raise IOError(errno.EPIPE, 'broken pipe foofofo')
61@@ -237,21 +243,21 @@
62 self.assertEndsWith(log, ' "a string")\n')
63
64 def test_mutter_never_fails(self):
65- # Even if the decode/encode stage fails, mutter should not
66- # raise an exception
67- # This test checks that mutter doesn't fail; the current behaviour
68- # is that it doesn't fail *and writes non-utf8*.
69- mutter(u'Writing a greek mu (\xb5) works in a unicode string')
70- mutter(b'But fails in an ascii string \xb5')
71- mutter(b'and in an ascii argument: %s', b'\xb5')
72+ """Even with unencodable input mutter should not raise errors."""
73+ mutter(u'can write unicode \xa7')
74+ mutter('can interpolate unicode %s', u'\xa7')
75+ mutter(b'can write bytes \xa7')
76+ mutter('can repr bytes %r', b'\xa7')
77+ mutter('can interpolate bytes %s', b'\xa7')
78+ # Log will always be written as utf-8
79 log = self.get_log()
80- self.assertContainsRe(log, 'Writing a greek mu')
81- self.assertContainsRe(log, "But fails in an ascii string")
82- # However, the log content object does unicode replacement on reading
83- # to let it get unicode back where good data has been written. So we
84- # have to do a replaceent here as well.
85- self.assertContainsRe(log, b"ascii argument: \xb5".decode('utf8',
86- 'replace'))
87+ self.assertContainsRe(
88+ log,
89+ u'.* +can write unicode \xa7\n'
90+ u'.* +can interpolate unicode \xa7\n'
91+ u'.* +can write bytes \ufffd\n'
92+ u'.* +can repr bytes b\'\\\\xa7\'\n'
93+ u'.* +can interpolate bytes (?:\ufffd|b\'\\\\xa7\')\n')
94
95 def test_show_error(self):
96 show_error('error1')
97
98=== modified file 'breezy/trace.py'
99--- breezy/trace.py 2018-06-17 11:15:04 +0000
100+++ breezy/trace.py 2018-06-30 23:03:12 +0000
101@@ -138,6 +138,16 @@
102 _brz_logger.error(*args, **kwargs)
103
104
105+class _Bytes(str):
106+ """Compat class for displaying bytes on Python 2."""
107+
108+ def __repr__(self):
109+ return 'b' + str.__repr__(self)
110+
111+ def __unicode__(self):
112+ return self.decode('ascii', 'replace')
113+
114+
115 def mutter(fmt, *args):
116 if _trace_file is None:
117 return
118@@ -146,24 +156,20 @@
119 if (getattr(_trace_file, 'closed', None) is not None) and _trace_file.closed:
120 return
121
122- if isinstance(fmt, text_type):
123- fmt = fmt.encode('utf8')
124+ # Let format strings be specified as ascii bytes to help Python 2
125+ if isinstance(fmt, bytes):
126+ fmt = fmt.decode('ascii', 'replace')
127
128- if len(args) > 0:
129- # It seems that if we do ascii % (unicode, ascii) we can
130- # get a unicode cannot encode ascii error, so make sure that "fmt"
131- # is a unicode string
132- real_args = []
133- for arg in args:
134- if isinstance(arg, text_type):
135- arg = arg.encode('utf8')
136- real_args.append(arg)
137- out = fmt % tuple(real_args)
138+ if args:
139+ if not PY3:
140+ args = tuple(
141+ _Bytes(arg) if isinstance(arg, bytes) else arg for arg in args)
142+ out = fmt % args
143 else:
144 out = fmt
145 now = time.time()
146- out = b'%0.3f %s\n' % (now - _brz_log_start_time, out)
147- _trace_file.write(out)
148+ out = '%0.3f %s\n' % (now - _brz_log_start_time, out)
149+ _trace_file.write(out.encode('utf-8'))
150 # there's no explicit flushing; the file is typically line buffered.
151
152
153@@ -612,8 +618,8 @@
154 # Try saving the details that would have been logged in some form
155 msg = args = "<Unformattable>"
156 try:
157- msg = repr(record.msg).encode("ascii", "backslashescape")
158- args = repr(record.args).encode("ascii", "backslashescape")
159+ msg = repr(record.msg)
160+ args = repr(record.args)
161 except Exception:
162 pass
163 # Using mutter() bypasses the logging module and writes directly
164
165=== modified file 'python3.passing'
166--- python3.passing 2018-06-30 22:12:58 +0000
167+++ python3.passing 2018-06-30 23:03:12 +0000
168@@ -12699,6 +12699,7 @@
169 breezy.tests.test_chk_map.TestLeafNode.test_current_size_width_changed
170 breezy.tests.test_chk_map.TestLeafNode.test_key_new
171 breezy.tests.test_chk_map.TestLeafNode.test_unique_serialised_prefix_empty_new
172+breezy.tests.test_chk_map.TestLeafNode.test_unmap_missing
173 breezy.tests.test_chk_map.TestMapSearchKeys.test_search_key_is_passed_to_root_node
174 breezy.tests.test_chk_map.TestMapSearchKeys.test_search_key_passed_via__ensure_root
175 breezy.tests.test_chk_map.TestMap.test_init_and_save_new
176@@ -13826,6 +13827,7 @@
177 breezy.tests.test_export_pot.TestModuleContext.test_from_class
178 breezy.tests.test_export_pot.TestModuleContext.test_from_class_missing
179 breezy.tests.test_export_pot.TestModuleContext.test_from_string
180+breezy.tests.test_export_pot.TestModuleContext.test_from_string_missing
181 breezy.tests.test_export_pot.TestModuleContext.test___init__
182 breezy.tests.test_export_pot.TestNormalize.test_multi_lines
183 breezy.tests.test_export_pot.TestNormalize.test_single_line
184@@ -16162,6 +16164,8 @@
185 breezy.tests.test_remote.Test_ClientMedium_remote_is_at_least.test__remember_remote_is_before
186 breezy.tests.test_remote.Test_ClientMedium_remote_path_from_transport.test_remote_path_from_transport
187 breezy.tests.test_remote.Test_ClientMedium_remote_path_from_transport.test_remote_path_from_transport_http
188+breezy.tests.test_remote.TestErrorTranslationRobustness.test_context_missing_a_key
189+breezy.tests.test_remote.TestErrorTranslationRobustness.test_path_missing
190 breezy.tests.test_remote.TestErrorTranslationRobustness.test_unrecognised_server_error
191 breezy.tests.test_remote.TestErrorTranslationSuccess.test_Diverged
192 breezy.tests.test_remote.TestErrorTranslationSuccess.test_generic_IndexError_no_classname
193@@ -16882,6 +16886,7 @@
194 breezy.tests.test_smart.TestSmartServerRepositoryGetRevisionGraph.test_specific_revision_argument
195 breezy.tests.test_smart.TestSmartServerRepositoryGetRevisionSignatureText.test_get_signature
196 breezy.tests.test_smart.TestSmartServerRepositoryGetSerializerFormat.test_get_serializer_format
197+breezy.tests.test_smart.TestSmartServerRepositoryGetStreamForMissingKeys.test_unknown_format
198 breezy.tests.test_smart.TestSmartServerRepositoryGetStream.test_ancestry_of
199 breezy.tests.test_smart.TestSmartServerRepositoryGetStream.test_search
200 breezy.tests.test_smart.TestSmartServerRepositoryGetStream.test_search_everything
201@@ -17450,6 +17455,7 @@
202 breezy.tests.test_trace.TestTrace.test_report_external_import_error
203 breezy.tests.test_trace.TestTrace.test_report_import_syntax_error
204 breezy.tests.test_trace.TestTrace.test_show_error
205+breezy.tests.test_trace.TestTrace.test_trace_argument_exception
206 breezy.tests.test_trace.TestTrace.test_trace_argument_unicode
207 breezy.tests.test_trace.TestTrace.test_trace_argument_utf8
208 breezy.tests.test_trace.TestTrace.test_trace_unicode

Subscribers

People subscribed via source and target branches