summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Hellmann <doug.hellmann@gmail.com>2013-08-16 12:33:45 -0400
committerDoug Hellmann <doug.hellmann@dreamhost.com>2013-08-16 12:36:20 -0400
commitba73f3f2c5b0a86ef302561b89d5db9ff4139e1a (patch)
tree7bc9547010f34bfbb103b86668e999bfd3202c18
parent269f06ff6f07060f57b91c8e189d7c87740ac1ed (diff)
downloadcliff-ba73f3f2c5b0a86ef302561b89d5db9ff4139e1a.tar.gz
Provide a default output encoding
Set a class attribute on the App to force the input/output encoding in case neither stdout nor getdefaultencoding() have a valid value. This case comes up sometimes under test runners that capture stdout, without setting up a proper encoding for the stream capture buffer. Change-Id: Iab1d0b1549e1d00f64ef36765852261c108e0388
-rw-r--r--cliff/app.py6
-rw-r--r--cliff/tests/test_app.py27
2 files changed, 32 insertions, 1 deletions
diff --git a/cliff/app.py b/cliff/app.py
index 261c5cc..5cbd195 100644
--- a/cliff/app.py
+++ b/cliff/app.py
@@ -61,6 +61,7 @@ class App(object):
LOG_FILE_MESSAGE_FORMAT = \
'[%(asctime)s] %(levelname)-8s %(name)s %(message)s'
DEFAULT_VERBOSE_LEVEL = 1
+ DEFAULT_OUTPUT_ENCODING = 'utf-8'
def __init__(self, description, version, command_manager,
stdin=None, stdout=None, stderr=None,
@@ -85,7 +86,10 @@ class App(object):
# works around a problem with Python 2.6 fixed in 2.7 and
# later (http://hg.python.org/cpython/rev/e60ef17561dc/).
lang, encoding = locale.getdefaultlocale()
- encoding = getattr(sys.stdout, 'encoding', None) or encoding
+ encoding = (getattr(sys.stdout, 'encoding', None)
+ or encoding
+ or self.DEFAULT_OUTPUT_ENCODING
+ )
self.stdin = stdin or codecs.getreader(encoding)(sys.stdin)
self.stdout = stdout or codecs.getwriter(encoding)(sys.stdout)
self.stderr = stderr or codecs.getwriter(encoding)(sys.stderr)
diff --git a/cliff/tests/test_app.py b/cliff/tests/test_app.py
index 57256ee..5f13007 100644
--- a/cliff/tests/test_app.py
+++ b/cliff/tests/test_app.py
@@ -264,6 +264,33 @@ def test_output_encoding_default():
assert data == actual
+def test_output_encoding_cliff_default():
+ # The encoding should come from cliff.App.DEFAULT_OUTPUT_ENCODING
+ # because the other values are missing or None
+ if sys.version_info[:2] != (2, 6):
+ raise nose.SkipTest('only needed for python 2.6')
+ data = '\xc3\xa9'
+ u_data = data.decode('utf-8')
+
+ class MyApp(App):
+ def __init__(self):
+ super(MyApp, self).__init__(
+ description='testing',
+ version='0.1',
+ command_manager=CommandManager('tests'),
+ )
+
+ stdout = StringIO()
+ getdefaultlocale = lambda: ('ignored', None)
+
+ with mock.patch('sys.stdout', stdout):
+ with mock.patch('locale.getdefaultlocale', getdefaultlocale):
+ app = MyApp()
+ app.stdout.write(u_data)
+ actual = stdout.getvalue()
+ assert data == actual
+
+
def test_output_encoding_sys():
# The encoding should come from sys.stdout because it is set
# there.