Merge lp:~lifeless/bzr/encoding-option into lp:bzr

Proposed by Robert Collins
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 5317
Proposed branch: lp:~lifeless/bzr/encoding-option
Merge into: lp:bzr
Diff against target: 255 lines (+157/-3)
7 files modified
NEWS (+7/-0)
bzrlib/help_topics/en/configuration.txt (+11/-0)
bzrlib/tests/__init__.py (+2/-0)
bzrlib/tests/fixtures.py (+84/-0)
bzrlib/tests/test_fixtures.py (+28/-0)
bzrlib/tests/test_ui.py (+18/-1)
bzrlib/ui/__init__.py (+7/-2)
To merge this branch: bzr merge lp:~lifeless/bzr/encoding-option
Reviewer Review Type Date Requested Status
bzr-core Pending
Review via email: mp+28126@code.launchpad.net

Commit message

Polish and adjust news for Martin's output_encoding branch.

Description of the change

Martins branch, NEWS moved to the right section, the config option added
to NEWS, copyright changed to 2010 for the new files.

Hmm, I may have missed the man page stuff, I think there is a bug open
about it not using the configuration help - but we should just fix that
bug.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

discussed it on the phone with poolie yesterday - marking approved now as it gives martin[gz] a test vehicle, and the questions I had are addressed.

Revision history for this message
Robert Collins (lifeless) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-06-21 04:16:16 +0000
3+++ NEWS 2010-06-21 22:33:25 +0000
4@@ -114,6 +114,10 @@
5 formats is needed or when the format string for the object is
6 encountered. (Robert Collins, Jelmer Vernooij)
7
8+* The encoding that bzr uses to output things other than file content can
9+ now be overridden via the output_encoding configuration option.
10+ (Martin Pool, #340394)
11+
12 * Use lazy imports in ``bzrlib/merge.py`` so that plugins like ``news_merge``
13 do not cause modules to be loaded unnecessarily just because the plugin
14 registers a merge hook. This improves ``bzr rocks`` time by about 25%
15@@ -166,6 +170,9 @@
16 Testing
17 *******
18
19+* Add ``bzrlib.tests.fixtures`` to hold code for setting up objects
20+ to test. (Martin Pool)
21+
22 * ``test_import_tariff`` now respects BZR_PLUGINS_AT and BZR_PLUGINS_DISABLE.
23 (Vincent Ladeuil, #595587)
24
25
26=== modified file 'bzrlib/help_topics/en/configuration.txt'
27--- bzrlib/help_topics/en/configuration.txt 2010-06-02 05:03:31 +0000
28+++ bzrlib/help_topics/en/configuration.txt 2010-06-21 22:33:25 +0000
29@@ -496,6 +496,17 @@
30 using deprecated formats.
31
32
33+Unicode options
34+---------------
35+
36+output_encoding
37+~~~~~~~~~~~~~~~
38+
39+A Python unicode encoding name for text output from bzr, such as log
40+information. Values include: utf8, cp850, ascii, iso-8859-1. The default
41+is the terminal encoding prefered by the operating system.
42+
43+
44 Branch type specific options
45 ----------------------------
46
47
48=== modified file 'bzrlib/tests/__init__.py'
49--- bzrlib/tests/__init__.py 2010-06-08 01:42:50 +0000
50+++ bzrlib/tests/__init__.py 2010-06-21 22:33:25 +0000
51@@ -3704,6 +3704,7 @@
52 'bzrlib.tests.test_export',
53 'bzrlib.tests.test_extract',
54 'bzrlib.tests.test_fetch',
55+ 'bzrlib.tests.test_fixtures',
56 'bzrlib.tests.test_fifo_cache',
57 'bzrlib.tests.test_filters',
58 'bzrlib.tests.test_ftp_transport',
59@@ -3839,6 +3840,7 @@
60 'bzrlib.option',
61 'bzrlib.symbol_versioning',
62 'bzrlib.tests',
63+ 'bzrlib.tests.fixtures',
64 'bzrlib.timestamp',
65 'bzrlib.version_info_formats.format_custom',
66 ]
67
68=== added file 'bzrlib/tests/fixtures.py'
69--- bzrlib/tests/fixtures.py 1970-01-01 00:00:00 +0000
70+++ bzrlib/tests/fixtures.py 2010-06-21 22:33:25 +0000
71@@ -0,0 +1,84 @@
72+# Copyright (C) 2010 Canonical Ltd
73+#
74+# This program is free software; you can redistribute it and/or modify
75+# it under the terms of the GNU General Public License as published by
76+# the Free Software Foundation; either version 2 of the License, or
77+# (at your option) any later version.
78+#
79+# This program is distributed in the hope that it will be useful,
80+# but WITHOUT ANY WARRANTY; without even the implied warranty of
81+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
82+# GNU General Public License for more details.
83+#
84+# You should have received a copy of the GNU General Public License
85+# along with this program; if not, write to the Free Software
86+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
87+
88+
89+"""Fixtures that can be used within tests.
90+
91+Fixtures can be created during a test as a way to separate out creation of
92+objects to test. Fixture objects can hold some state so that different
93+objects created during a test instance can be related. Normally a fixture
94+should live only for the duration of a single test, and its tearDown method
95+should be passed to `addCleanup` on the test.
96+"""
97+
98+
99+import itertools
100+
101+
102+def generate_unicode_names():
103+ """Generate a sequence of arbitrary unique unicode names.
104+
105+ By default they are not representable in ascii.
106+
107+ >>> gen = generate_unicode_names()
108+ >>> n1 = gen.next()
109+ >>> n2 = gen.next()
110+ >>> type(n1)
111+ <type 'unicode'>
112+ >>> n1 == n2
113+ False
114+ >>> n1.encode('ascii', 'replace') == n1
115+ False
116+ """
117+ # include a mathematical symbol unlikely to be in 8-bit encodings
118+ return (u"\N{SINE WAVE}%d" % x for x in itertools.count())
119+
120+
121+interesting_encodings = [
122+ ('iso-8859-1', False),
123+ ('ascii', False),
124+ ('cp850', False),
125+ ('utf-8', True),
126+ ('ucs-2', True),
127+ ]
128+
129+
130+def generate_unicode_encodings(universal_encoding=None):
131+ """Return a generator of unicode encoding names.
132+
133+ These can be passed to Python encode/decode/etc.
134+
135+ :param universal_encoding: True/False/None tristate to say whether the
136+ generated encodings either can or cannot encode all unicode
137+ strings.
138+
139+ >>> n1 = generate_unicode_names().next()
140+ >>> enc = generate_unicode_encodings(universal_encoding=True).next()
141+ >>> enc2 = generate_unicode_encodings(universal_encoding=False).next()
142+ >>> n1.encode(enc).decode(enc) == n1
143+ True
144+ >>> try:
145+ ... n1.encode(enc2).decode(enc2)
146+ ... except UnicodeError:
147+ ... print 'fail'
148+ fail
149+ """
150+ # TODO: check they're supported on this platform?
151+ if universal_encoding is not None:
152+ e = [n for (n, u) in interesting_encodings if u == universal_encoding]
153+ else:
154+ e = [n for (n, u) in interesting_encodings]
155+ return itertools.cycle(iter(e))
156
157=== added file 'bzrlib/tests/test_fixtures.py'
158--- bzrlib/tests/test_fixtures.py 1970-01-01 00:00:00 +0000
159+++ bzrlib/tests/test_fixtures.py 2010-06-21 22:33:25 +0000
160@@ -0,0 +1,28 @@
161+# Copyright (C) 2010 Canonical Ltd
162+#
163+# This program is free software; you can redistribute it and/or modify
164+# it under the terms of the GNU General Public License as published by
165+# the Free Software Foundation; either version 2 of the License, or
166+# (at your option) any later version.
167+#
168+# This program is distributed in the hope that it will be useful,
169+# but WITHOUT ANY WARRANTY; without even the implied warranty of
170+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
171+# GNU General Public License for more details.
172+#
173+# You should have received a copy of the GNU General Public License
174+# along with this program; if not, write to the Free Software
175+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
176+
177+"""Tests for test fixtures"""
178+
179+import codecs
180+
181+from bzrlib import (
182+ tests,
183+ )
184+from bzrlib.tests import (
185+ fixtures,
186+ )
187+
188+
189
190=== modified file 'bzrlib/tests/test_ui.py'
191--- bzrlib/tests/test_ui.py 2010-05-20 18:23:17 +0000
192+++ bzrlib/tests/test_ui.py 2010-06-21 22:33:25 +0000
193@@ -24,6 +24,7 @@
194 from StringIO import StringIO
195
196 from bzrlib import (
197+ config,
198 errors,
199 remote,
200 repository,
201@@ -33,10 +34,26 @@
202 from bzrlib.symbol_versioning import (
203 deprecated_in,
204 )
205-from bzrlib.tests import test_progress
206+from bzrlib.tests import (
207+ fixtures,
208+ test_progress,
209+ )
210 from bzrlib.ui import text as _mod_ui_text
211
212
213+class TestUIConfiguration(tests.TestCaseWithTransport):
214+
215+ def test_output_encoding_configuration(self):
216+ enc = fixtures.generate_unicode_encodings().next()
217+ config.GlobalConfig().set_user_option('output_encoding',
218+ enc)
219+ ui = tests.TestUIFactory(stdin=None,
220+ stdout=tests.StringIOWrapper(),
221+ stderr=tests.StringIOWrapper())
222+ os = ui.make_output_stream()
223+ self.assertEquals(os.encoding, enc)
224+
225+
226 class TestTextUIFactory(tests.TestCase):
227
228 def test_text_factory_ascii_password(self):
229
230=== modified file 'bzrlib/ui/__init__.py'
231--- bzrlib/ui/__init__.py 2010-06-21 20:03:23 +0000
232+++ bzrlib/ui/__init__.py 2010-06-21 22:33:25 +0000
233@@ -178,8 +178,9 @@
234 version of stdout, but in a GUI it might be appropriate to send it to a
235 window displaying the text.
236
237- :param encoding: Unicode encoding for output; default is the
238- terminal encoding, which may be different from the user encoding.
239+ :param encoding: Unicode encoding for output; if not specified
240+ uses the configured 'output_encoding' if any; otherwise the
241+ terminal encoding.
242 (See get_terminal_encoding.)
243
244 :param encoding_type: How to handle encoding errors:
245@@ -187,6 +188,10 @@
246 """
247 # XXX: is the caller supposed to close the resulting object?
248 if encoding is None:
249+ from bzrlib import config
250+ encoding = config.GlobalConfig().get_user_option(
251+ 'output_encoding')
252+ if encoding is None:
253 encoding = osutils.get_terminal_encoding()
254 if encoding_type is None:
255 encoding_type = 'replace'