From 53fa44c01e7b50b571c48101d6ca59ac0fd94ace Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 20 Sep 2016 18:05:59 -0700 Subject: [PATCH] Don't break when interpolating environment with unicode characters Signed-off-by: Joffrey F --- compose/service.py | 2 ++ tests/acceptance/cli_test.py | 19 +++++++++++++++++++ .../unicode-environment/docker-compose.yml | 7 +++++++ 3 files changed, 28 insertions(+) create mode 100644 tests/fixtures/unicode-environment/docker-compose.yml diff --git a/compose/service.py b/compose/service.py index b5a35b7e8..1759bf7d4 100644 --- a/compose/service.py +++ b/compose/service.py @@ -1109,6 +1109,8 @@ def format_environment(environment): def format_env(key, value): if value is None: return key + if isinstance(value, six.binary_type): + value = value.decode('utf-8') return '{key}={value}'.format(key=key, value=value) return [format_env(*item) for item in environment.items()] diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 3939a97b4..67cca8c75 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import unicode_literals @@ -12,6 +13,7 @@ from collections import namedtuple from operator import attrgetter import py +import six import yaml from docker import errors @@ -1286,6 +1288,23 @@ class CLITestCase(DockerClientTestCase): 'simplecomposefile_simple_run_1', 'exited')) + @mock.patch.dict(os.environ) + def test_run_unicode_env_values_from_system(self): + value = 'ą, ć, ę, ł, ń, ó, ś, ź, ż' + if six.PY2: # os.environ doesn't support unicode values in Py2 + os.environ['BAR'] = value.encode('utf-8') + else: # ... and doesn't support byte values in Py3 + os.environ['BAR'] = value + self.base_dir = 'tests/fixtures/unicode-environment' + result = self.dispatch(['run', 'simple']) + + if six.PY2: # Can't retrieve output on Py3. See issue #3670 + assert value == result.stdout.strip() + + container = self.project.containers(one_off=OneOffFilter.only, stopped=True)[0] + environment = container.get('Config.Env') + assert 'FOO={}'.format(value) in environment + @mock.patch.dict(os.environ) def test_run_env_values_from_system(self): os.environ['FOO'] = 'bar' diff --git a/tests/fixtures/unicode-environment/docker-compose.yml b/tests/fixtures/unicode-environment/docker-compose.yml new file mode 100644 index 000000000..a41af4f07 --- /dev/null +++ b/tests/fixtures/unicode-environment/docker-compose.yml @@ -0,0 +1,7 @@ +version: '2' +services: + simple: + image: busybox:latest + command: sh -c 'echo $$FOO' + environment: + FOO: ${BAR}