diff --git a/hydra/utils.py b/hydra/utils.py index 8ef5611243..079f97667a 100644 --- a/hydra/utils.py +++ b/hydra/utils.py @@ -142,4 +142,7 @@ def to_hydra_override_value_str(obj: Any) -> str: return ( "[" + ", ".join([to_hydra_override_value_str(value) for value in obj]) + "]" ) + elif isinstance(obj, str): + new_str = obj.replace('\\"', '\\\\"').replace('"', '\\"') + return f'"{new_str}"' return json.dumps(obj) diff --git a/tests/test_utils.py b/tests/test_utils.py index 0d8848a7b8..96e1837e1a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,6 @@ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved import io +import json import os import re from pathlib import Path @@ -15,6 +16,7 @@ from hydra._internal.utils import run_and_report from hydra.conf import HydraConf, RuntimeConf from hydra.core.hydra_config import HydraConfig +from hydra.core.override_parser.overrides_parser import OverridesParser from hydra.errors import HydraDeprecationError from hydra.test_utils.test_utils import ( assert_multiline_regex_search, @@ -74,22 +76,30 @@ def test_to_absolute_path_without_hydra( @mark.parametrize( - "obj, expected", + "obj", [ - ("foo bar", '"foo bar"'), - (10, "10"), - ({"foo": '\\"bar'}, '{foo: "\\\\\\"bar"}'), - ([1, 2, "3", {"a": "xyz"}], '[1, 2, "3", {a: "xyz"}]'), + ("foo bar"), + (10), + ({"foo": '\\"bar\\\'"'}), + ([1, 2, "3", {"a": "xyz"}]), + ({"a": 10, "b": "c", "d": {"e": [1, 2, "3"], "f": ["g", {"h": {"i": "j"}}]}}), ( - {"a": 10, "b": "c", "d": {"e": [1, 2, "3"], "f": ["g", {"h": {"i": "j"}}]}}, - '{a: 10, b: "c", d: {e: [1, 2, "3"], f: ["g", {h: {i: "j"}}]}}', + { + "a": 10, + "b": "c\nnl", + "d": {"e": [1, 2, "3"], "f": ["g", {"h": {"i": "j"}}]}, + } ), + ({"json_val": json.dumps({"a": 10, "b": "c\\\nnl"}, indent=4)}), ], ) -def test_to_hydra_override_value_str( - hydra_restore_singletons: Any, obj: Any, expected: str +def test_to_hydra_override_value_str_roundtrip( + hydra_restore_singletons: Any, obj: Any ) -> None: - assert utils.to_hydra_override_value_str(obj) == expected + override_str = utils.to_hydra_override_value_str(obj) + override_params = f"++ov={override_str}" + o = OverridesParser.create().parse_override(override_params) + assert o.value() == obj @mark.parametrize(