From 95abadad70f45b70f0b4d421b53a1ffe096265bf Mon Sep 17 00:00:00 2001 From: Haim Dimer Date: Sat, 15 Aug 2026 23:22:21 -0700 Subject: [PATCH] Keep non-ASCII characters in `config` output `yaml.safe_dump` defaults to `allow_unicode=False`, so any non-ASCII character in a compose value was rendered as a `\xE9`-style escape in the output of `podman-compose config`. Docker Compose prints these characters literally. Fixes #1536 Signed-off-by: Haim Dimer --- .../config_keeps_non_ascii_characters.bugfix | 1 + podman_compose.py | 2 +- .../docker-compose_non_ascii.yaml | 5 +++ .../test_podman_compose_config_command.py | 20 +++++++++++ tests/unit/test_merged_yaml.py | 35 +++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 newsfragments/config_keeps_non_ascii_characters.bugfix create mode 100644 tests/integration/command_config/docker-compose_non_ascii.yaml create mode 100644 tests/unit/test_merged_yaml.py diff --git a/newsfragments/config_keeps_non_ascii_characters.bugfix b/newsfragments/config_keeps_non_ascii_characters.bugfix new file mode 100644 index 00000000..32aaf353 --- /dev/null +++ b/newsfragments/config_keeps_non_ascii_characters.bugfix @@ -0,0 +1 @@ +Fixed `podman-compose config` escaping non-ASCII characters, so values such as accented bind mount paths print literally instead of as `\xE9` escapes. diff --git a/podman_compose.py b/podman_compose.py index 307804b9..a36599ff 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2892,7 +2892,7 @@ def _parse_compose_file(self) -> None: if not getattr(args, "no_normalize", None): compose = normalize_final(compose, self.dirname) compose.pop("version", None) - self.merged_yaml = yaml.safe_dump(compose) + self.merged_yaml = yaml.safe_dump(compose, allow_unicode=True) merged_json_b = json.dumps( self.original_configuration(compose), separators=(",", ":") ).encode("utf-8") diff --git a/tests/integration/command_config/docker-compose_non_ascii.yaml b/tests/integration/command_config/docker-compose_non_ascii.yaml new file mode 100644 index 00000000..51fb8da4 --- /dev/null +++ b/tests/integration/command_config/docker-compose_non_ascii.yaml @@ -0,0 +1,5 @@ +services: + sample: + image: nopush/podman-compose-test + volumes: + - /home/développement:/home/dev diff --git a/tests/integration/command_config/test_podman_compose_config_command.py b/tests/integration/command_config/test_podman_compose_config_command.py index 9452ae8f..376ce586 100644 --- a/tests/integration/command_config/test_podman_compose_config_command.py +++ b/tests/integration/command_config/test_podman_compose_config_command.py @@ -58,6 +58,26 @@ def test_config_short_syntax_env(self) -> None: """) self.assertEqual(out.decode("utf-8"), expected) + def test_config_keeps_non_ascii_characters(self) -> None: + out, _ = self.run_subprocess_assert_returncode( + [ + podman_compose_path(), + "-f", + compose_yaml_path("_non_ascii"), + "config", + ], + 0, + ) + expected = textwrap.dedent("""\ + services: + sample: + image: nopush/podman-compose-test + volumes: + - /home/développement:/home/dev + + """) + self.assertEqual(out.decode("utf-8"), expected) + def test_config_omits_version_and_warns(self) -> None: config_cmd = [ "coverage", diff --git a/tests/unit/test_merged_yaml.py b/tests/unit/test_merged_yaml.py new file mode 100644 index 00000000..603faa12 --- /dev/null +++ b/tests/unit/test_merged_yaml.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0 +# pylint: disable=protected-access +from __future__ import annotations + +import os +import tempfile +import unittest + +from podman_compose import PodmanCompose + + +class TestMergedYaml(unittest.TestCase): + def test_merged_yaml_keeps_non_ascii_characters(self) -> None: + content = """\ +services: + sample: + image: nopush/podman-compose-test + volumes: + - /home/développement:/home/dev +""" + + with tempfile.TemporaryDirectory() as tmp_dir: + compose_file = os.path.join(tmp_dir, "docker-compose.yaml") + with open(compose_file, "w", encoding="utf-8") as f: + f.write(content) + + podman_compose = PodmanCompose() + podman_compose.global_args.file = [compose_file] + podman_compose.global_args.project_name = "test_project" + podman_compose.global_args.env_file = None + podman_compose.global_args.profile = [] + podman_compose.global_args.in_pod = "false" + podman_compose._parse_compose_file() + + self.assertIn("/home/développement", podman_compose.merged_yaml)