From 4d1d96a0aeb49070fbd9b46bff777ef1ddf257a3 Mon Sep 17 00:00:00 2001
From: Pere Diaz Bou <30913090+pereman2@users.noreply.github.com>
Date: Fri, 24 Jul 2020 18:35:56 +0200
Subject: [PATCH] OmegaConf.to_yaml (#313)
---
docs/notebook/Tutorial.ipynb | 102 ++++++++++-------
docs/source/structured_config.rst | 4 +-
docs/source/usage.rst | 24 ++--
news/263.removal | 1 +
omegaconf/basecontainer.py | 24 ++--
omegaconf/omegaconf.py | 23 +++-
tests/examples/test_dataclass_example.py | 2 +-
tests/test_basic_ops_dict.py | 65 -----------
tests/test_basic_ops_list.py | 64 +----------
tests/test_nodes.py | 16 ---
tests/test_to_yaml.py | 139 +++++++++++++++++++++++
11 files changed, 245 insertions(+), 219 deletions(-)
create mode 100644 news/263.removal
create mode 100644 tests/test_to_yaml.py
diff --git a/docs/notebook/Tutorial.ipynb b/docs/notebook/Tutorial.ipynb
index 43411ce34..d37bd6ce4 100644
--- a/docs/notebook/Tutorial.ipynb
+++ b/docs/notebook/Tutorial.ipynb
@@ -75,7 +75,7 @@
],
"source": [
"conf = OmegaConf.create(dict(k='v',list=[1,dict(a='1',b='2')]))\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -108,7 +108,7 @@
],
"source": [
"conf = OmegaConf.create([1, dict(a=10, b=dict(a=10))])\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -145,7 +145,7 @@
],
"source": [
"conf = OmegaConf.load('../source/example.yaml')\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -186,7 +186,7 @@
"- item2\n",
"\"\"\"\n",
"conf = OmegaConf.create(yaml)\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -223,7 +223,7 @@
"source": [
"dot_list = [\"a.aa.aaa=1\", \"a.aa.bbb=2\", \"a.bb.aaa=3\", \"a.bb.bbb=4\"]\n",
"conf = OmegaConf.from_dotlist(dot_list)\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -261,7 +261,7 @@
"import sys\n",
"sys.argv = ['your-program.py', 'server.port=82', 'log.file=log2.txt']\n",
"conf = OmegaConf.from_cli()\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -299,7 +299,7 @@
],
"source": [
"conf = OmegaConf.load('../source/example.yaml')\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -528,9 +528,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Interpolations are evaluated lazily on field access.
\n",
- "Note below that when printed the interpolations are not resolved.
\n",
- "They get resolved once you access them."
+ "Interpolations are evaluated lazily on field access. OmegaConf.to_yaml() is eagerly resolving the interpolations by default."
]
},
{
@@ -550,47 +548,52 @@
" host: localhost\n",
" port: 80\n",
"client:\n",
- " url: http://${server.host}:${server.port}/\n",
- " server_port: ${server.port}\n",
+ " url: http://localhost:80/\n",
+ " server_port: 80\n",
"\n"
]
}
],
"source": [
"conf = OmegaConf.load('../source/config_interpolation.yaml')\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can change it by passing `resolve=False`."
]
},
{
"cell_type": "code",
"execution_count": 18,
- "metadata": {
- "pycharm": {
- "name": "#%%\n"
- }
- },
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "conf.client.server_port: 80 int\n",
- "conf.client.url: http://localhost:80/ str\n"
+ "server:\n",
+ " host: localhost\n",
+ " port: 80\n",
+ "client:\n",
+ " url: http://${server.host}:${server.port}/\n",
+ " server_port: ${server.port}\n",
+ "\n"
]
}
],
"source": [
- "# Primitive interpolation types are inherited from the referenced value\n",
- "print(\"conf.client.server_port: \", conf.client.server_port, type(conf.client.server_port).__name__)\n",
- "# Composite interpolation types are always string\n",
- "print(\"conf.client.url: \", conf.client.url, type(conf.client.url).__name__)"
+ "print(OmegaConf.to_yaml(conf, resolve=False))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "You can resolve interpolation while you are printing using `resolve=True`."
+ "Notice that the url and server_port changes with the port."
]
},
{
@@ -602,18 +605,17 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "server:\n",
- " host: localhost\n",
- " port: 80\n",
- "client:\n",
- " url: http://localhost:80/\n",
- " server_port: 80\n",
- "\n"
+ "conf.client.server_port: 90 int\n",
+ "conf.client.url: http://localhost:90/ str\n"
]
}
],
"source": [
- "print(conf.pretty(resolve=True))"
+ "conf.server.port = 90\n",
+ "# Primitive interpolation types are inherited from the referenced value\n",
+ "print(\"conf.client.server_port: \", conf.client.server_port, type(conf.client.server_port).__name__)\n",
+ "# Composite interpolation types are always string\n",
+ "print(\"conf.client.url: \", conf.client.url, type(conf.client.url).__name__)"
]
},
{
@@ -626,7 +628,12 @@
{
"cell_type": "code",
"execution_count": 20,
- "metadata": {},
+ "metadata": {
+ "pycharm": {
+ "name": "#%%\n"
+ },
+ "scrolled": true
+ },
"outputs": [
{
"name": "stdout",
@@ -693,15 +700,15 @@
"output_type": "stream",
"text": [
"user:\n",
- " name: ${env:USER}\n",
- " home: /home/${env:USER}\n",
+ " name: omry\n",
+ " home: /home/omry\n",
"\n"
]
}
],
"source": [
"conf = OmegaConf.load('../source/env_interpolation.yaml')\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
},
{
@@ -718,15 +725,15 @@
"output_type": "stream",
"text": [
"user:\n",
- " name: omry\n",
- " home: /home/omry\n",
+ " name: ${env:USER}\n",
+ " home: /home/${env:USER}\n",
"\n"
]
}
],
"source": [
"conf = OmegaConf.load('../source/env_interpolation.yaml')\n",
- "print(conf.pretty(resolve=True))"
+ "print(OmegaConf.to_yaml(conf, resolve=False))"
]
},
{
@@ -862,7 +869,7 @@
],
"source": [
"base_conf = OmegaConf.load('../source/example2.yaml')\n",
- "print(base_conf.pretty())"
+ "print(OmegaConf.to_yaml(base_conf))"
]
},
{
@@ -886,7 +893,7 @@
],
"source": [
"second_conf = OmegaConf.load('../source/example3.yaml')\n",
- "print(second_conf.pretty())"
+ "print(OmegaConf.to_yaml(second_conf))"
]
},
{
@@ -924,8 +931,15 @@
"sys.argv = ['program.py', 'server.port=82']\n",
"# Merge with cli arguments\n",
"conf.merge_with_cli()\n",
- "print(conf.pretty())"
+ "print(OmegaConf.to_yaml(conf))"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
@@ -944,7 +958,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.3"
+ "version": "3.6.10"
},
"pycharm": {
"stem_cell": {
diff --git a/docs/source/structured_config.rst b/docs/source/structured_config.rst
index 659a8b1c5..18385a44e 100644
--- a/docs/source/structured_config.rst
+++ b/docs/source/structured_config.rst
@@ -66,7 +66,7 @@ fields during construction.
>>> conf3 = OmegaConf.structured(
... SimpleTypes(num=20,
... height=Height.TALL))
- >>> print(conf3.pretty())
+ >>> print(OmegaConf.to_yaml(conf3))
num: 20
pi: 3.1415
is_awesome: true
@@ -176,7 +176,7 @@ Structured configs can be nested.
... manager: User = User(name="manager", height=Height.TALL)
>>> conf : Group = OmegaConf.structured(Group)
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
name: ???
admin:
name: ???
diff --git a/docs/source/usage.rst b/docs/source/usage.rst
index 577278531..1e27d42ad 100644
--- a/docs/source/usage.rst
+++ b/docs/source/usage.rst
@@ -30,7 +30,7 @@ Empty
>>> from omegaconf import OmegaConf
>>> conf = OmegaConf.create()
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
{}
@@ -40,7 +40,7 @@ From a dictionary
.. doctest::
>>> conf = OmegaConf.create({"k" : "v", "list" : [1, {"a": "1", "b": "2"}]})
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
k: v
list:
- 1
@@ -54,7 +54,7 @@ From a list
.. doctest::
>>> conf = OmegaConf.create([1, {"a":10, "b": {"a":10}}])
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
- 1
- a: 10
b:
@@ -70,7 +70,7 @@ From a yaml file
>>> conf = OmegaConf.load('source/example.yaml')
>>> # Output is identical to the yaml file
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
server:
port: 80
log:
@@ -95,7 +95,7 @@ From a yaml string
... - item2
... """
>>> conf = OmegaConf.create(s)
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
a: b
b: c
list:
@@ -110,7 +110,7 @@ From a dot-list
>>> dot_list = ["a.aa.aaa=1", "a.aa.bbb=2", "a.bb.aaa=3", "a.bb.bbb=4"]
>>> conf = OmegaConf.from_dotlist(dot_list)
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
a:
aa:
aaa: 1
@@ -130,7 +130,7 @@ To parse the content of sys.arg:
>>> # Simulating command line arguments
>>> sys.argv = ['your-program.py', 'server.port=82', 'log.file=log2.txt']
>>> conf = OmegaConf.from_cli()
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
server:
port: 82
log:
@@ -153,7 +153,7 @@ See :doc:`structured_config` for more details, or keep reading for a minimal exa
... host: str = "localhost"
>>> # For strict typing purposes, prefer OmegaConf.structured() when creating structured configs
>>> conf = OmegaConf.structured(MyConfig)
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
port: 80
host: localhost
@@ -163,7 +163,7 @@ You can use an object to initialize the config as well:
.. doctest::
>>> conf = OmegaConf.structured(MyConfig(port=443))
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
port: 443
host: localhost
@@ -427,7 +427,7 @@ Note how the port changes to 82, and how the users lists are combined.
>>>
>>> # merge them all
>>> conf = OmegaConf.merge(base_conf, second_conf, cli_conf)
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
server:
port: 82
users:
@@ -589,13 +589,13 @@ Creates a copy of a DictConfig that contains only specific keys.
.. doctest:: loaded
>>> conf = OmegaConf.create({"a": {"b": 10}, "c":20})
- >>> print(conf.pretty())
+ >>> print(OmegaConf.to_yaml(conf))
a:
b: 10
c: 20
>>> c = OmegaConf.masked_copy(conf, ["a"])
- >>> print(c.pretty())
+ >>> print(OmegaConf.to_yaml(c))
a:
b: 10
diff --git a/news/263.removal b/news/263.removal
new file mode 100644
index 000000000..a89569d50
--- /dev/null
+++ b/news/263.removal
@@ -0,0 +1 @@
+cfg.pretty() is deprecated in favor of OmegaConf.to_yaml(config). Resolve parameter now defaults to True.
diff --git a/omegaconf/basecontainer.py b/omegaconf/basecontainer.py
index 9a5ba2076..e66faf381 100644
--- a/omegaconf/basecontainer.py
+++ b/omegaconf/basecontainer.py
@@ -13,7 +13,6 @@
_get_value,
_is_interpolation,
_resolve_optional,
- get_omega_conf_dumper,
get_ref_type,
get_value_kind,
get_yaml_loader,
@@ -216,24 +215,19 @@ def convert(val: Node) -> Any:
assert False
def pretty(self, resolve: bool = False, sort_keys: bool = False) -> str:
- """
- returns a yaml dump of this config object.
- :param resolve: if True, will return a string with the interpolations resolved, otherwise
- interpolations are preserved
- :param sort_keys: If True, will print dict keys in sorted order. default False.
- :return: A string containing the yaml representation.
- """
from omegaconf import OmegaConf
- container = OmegaConf.to_container(self, resolve=resolve, enum_to_str=True)
- return yaml.dump( # type: ignore
- container,
- default_flow_style=False,
- allow_unicode=True,
- sort_keys=sort_keys,
- Dumper=get_omega_conf_dumper(),
+ warnings.warn(
+ """
+ pretty() is deprecated and will be removed in a future version.
+ Use OmegaConf.to_yaml. Please note that the default value for
+ resolve has changed to True.
+ """,
+ category=UserWarning,
)
+ return OmegaConf.to_yaml(self, resolve=resolve, sort_keys=sort_keys)
+
@staticmethod
def _map_merge(dest: "BaseContainer", src: "BaseContainer") -> None:
"""merge src into dest and return a new copy, does not modified input"""
diff --git a/omegaconf/omegaconf.py b/omegaconf/omegaconf.py
index 780527e46..9819eb66b 100644
--- a/omegaconf/omegaconf.py
+++ b/omegaconf/omegaconf.py
@@ -34,6 +34,7 @@
format_and_raise,
get_dict_key_value_types,
get_list_element_type,
+ get_omega_conf_dumper,
get_type_of,
is_attr_class,
is_dataclass,
@@ -273,7 +274,7 @@ def save(
"""
if is_dataclass(config) or is_attr_class(config):
config = OmegaConf.create(config)
- data = config.pretty(resolve=resolve)
+ data = OmegaConf.to_yaml(config, resolve=resolve)
if isinstance(f, (str, pathlib.Path)):
with io.open(os.path.abspath(f), "w", encoding="utf-8") as file:
file.write(data)
@@ -568,6 +569,26 @@ def update(cfg: Container, key: str, value: Any = None) -> None:
idx = int(last)
root[idx] = value
+ @staticmethod
+ def to_yaml(
+ cfg: Container, *, resolve: bool = True, sort_keys: bool = False
+ ) -> str:
+ """
+ returns a yaml dump of this config object.
+ :param resolve: if True, will return a string with the interpolations resolved, otherwise
+ interpolations are preserved
+ :param sort_keys: If True, will print dict keys in sorted order. default False.
+ :return: A string containing the yaml representation.
+ """
+ container = OmegaConf.to_container(cfg, resolve=resolve, enum_to_str=True)
+ return yaml.dump( # type: ignore
+ container,
+ default_flow_style=False,
+ allow_unicode=True,
+ sort_keys=sort_keys,
+ Dumper=get_omega_conf_dumper(),
+ )
+
# register all default resolvers
register_default_resolvers()
diff --git a/tests/examples/test_dataclass_example.py b/tests/examples/test_dataclass_example.py
index b831a5ebc..7711600d3 100644
--- a/tests/examples/test_dataclass_example.py
+++ b/tests/examples/test_dataclass_example.py
@@ -159,7 +159,7 @@ def test_nesting() -> None:
name: manager
height: TALL
"""
- assert conf.pretty() == expected
+ assert OmegaConf.to_yaml(conf) == expected
# you can assign a different object of the same type
conf.admin = User(name="omry", height=Height.TALL)
diff --git a/tests/test_basic_ops_dict.py b/tests/test_basic_ops_dict.py
index f0025ca14..ba3fd4a1b 100644
--- a/tests/test_basic_ops_dict.py
+++ b/tests/test_basic_ops_dict.py
@@ -119,52 +119,6 @@ def test_subscript_set_with_dot_warning_suppressed(recwarn: Any, mocker: Any) ->
assert len(recwarn) == 0
-def test_pretty_dict() -> None:
- c = OmegaConf.create(dict(hello="world", list=[1, 2]))
- expected = """hello: world
-list:
-- 1
-- 2
-"""
- assert expected == c.pretty()
- assert OmegaConf.create(c.pretty()) == c
-
-
-def test_pretty_sort_keys() -> None:
- c = OmegaConf.create({"b": 2, "a": 1})
- # keys are not sorted by default
- assert c.pretty() == "b: 2\na: 1\n"
- c = OmegaConf.create({"b": 2, "a": 1})
- assert c.pretty(sort_keys=True) == "a: 1\nb: 2\n"
-
-
-def test_pretty_dict_unicode() -> None:
- c = OmegaConf.create(dict(你好="世界", list=[1, 2]))
- expected = """你好: 世界
-list:
-- 1
-- 2
-"""
- assert expected == c.pretty()
- assert OmegaConf.create(c.pretty()) == c
-
-
-def test_pretty_strings_float() -> None:
- c = OmegaConf.create({"b": "10e2", "a": "1.0", "c": 1.0})
- assert c.pretty() == "b: '10e2'\na: '1.0'\nc: 1.0\n"
-
-
-def test_pretty_string_boolean() -> None:
- for t in _utils.YAML_BOOL_TYPES:
- c = OmegaConf.create({"b": t, "a": 1})
- assert c.pretty() == "b: '%s'\na: 1\n" % t
-
-
-def test_pretty_string_int() -> None:
- c = OmegaConf.create({"b": "1", "a": 1})
- assert c.pretty() == "b: '1'\na: 1\n"
-
-
def test_default_value() -> None:
c = OmegaConf.create()
assert c.missing_key or "a default value" == "a default value"
@@ -522,25 +476,6 @@ def test_assign_dict_in_dict() -> None:
assert isinstance(c.foo, DictConfig)
-def test_pretty_without_resolve() -> None:
- c = OmegaConf.create(dict(a1="${ref}", ref="bar"))
- # without resolve, references are preserved
- c2 = OmegaConf.create(c.pretty(resolve=False))
- assert isinstance(c2, DictConfig)
- assert c2.a1 == "bar"
- c2.ref = "changed"
- assert c2.a1 == "changed"
-
-
-def test_pretty_with_resolve() -> None:
- c = OmegaConf.create(dict(a1="${ref}", ref="bar"))
- c2 = OmegaConf.create(c.pretty(resolve=True))
- assert isinstance(c2, DictConfig)
- assert c2.a1 == "bar"
- c2.ref = "changed"
- assert c2.a1 == "bar"
-
-
def test_instantiate_config_fails() -> None:
with pytest.raises(TypeError):
BaseContainer() # type: ignore
diff --git a/tests/test_basic_ops_list.py b/tests/test_basic_ops_list.py
index 3f8ae1037..9e0f875f1 100644
--- a/tests/test_basic_ops_list.py
+++ b/tests/test_basic_ops_list.py
@@ -4,7 +4,7 @@
import pytest
-from omegaconf import AnyNode, ListConfig, OmegaConf, _utils
+from omegaconf import AnyNode, ListConfig, OmegaConf
from omegaconf.errors import (
ConfigKeyError,
ConfigTypeError,
@@ -30,49 +30,6 @@ def test_list_of_dicts() -> None:
assert c[1].key2 == "value2"
-def test_pretty_list() -> None:
- c = OmegaConf.create(["item1", "item2", dict(key3="value3")])
- expected = """- item1
-- item2
-- key3: value3
-"""
- assert expected == c.pretty()
- assert OmegaConf.create(c.pretty()) == c
-
-
-def test_pretty_list_unicode() -> None:
- c = OmegaConf.create(["item一", "item二", dict(key三="value三")])
- expected = """- item一
-- item二
-- key三: value三
-"""
- assert expected == c.pretty()
- assert OmegaConf.create(c.pretty()) == c
-
-
-def test_pretty_strings_float() -> None:
- c = OmegaConf.create(["10e2", "1.0", 1.0])
- expected = """- '10e2'
-- '1.0'
-- 1.0
-"""
- assert c.pretty() == expected
-
-
-def test_pretty_string_boolean() -> None:
- for t in _utils.YAML_BOOL_TYPES:
- print(t)
- c = OmegaConf.create([t, 1])
- expected = "- '%s'\n- 1\n" % t
- assert c.pretty() == expected
-
-
-def test_pretty_string_int() -> None:
- c = OmegaConf.create(["1", 1])
- expected = "- '1'\n- 1\n"
- assert c.pretty() == expected
-
-
def test_list_get_with_default() -> None:
c = OmegaConf.create([None, "???", "found"])
assert c.get(0, "default_value") == "default_value"
@@ -230,25 +187,6 @@ def test_list_append() -> None:
validate_list_keys(c)
-def test_pretty_without_resolve() -> None:
- c = OmegaConf.create([100, "${0}"])
- # without resolve, references are preserved
- yaml_str = c.pretty(resolve=False)
- c2 = OmegaConf.create(yaml_str)
- assert isinstance(c2, ListConfig)
- c2[0] = 1000
- assert c2[1] == 1000
-
-
-def test_pretty_with_resolve() -> None:
- c = OmegaConf.create([100, "${0}"])
- # with resolve, references are not preserved.
- c2 = OmegaConf.create(c.pretty(resolve=True))
- assert isinstance(c2, ListConfig)
- c2[0] = 1000
- assert c[1] == 100
-
-
@pytest.mark.parametrize( # type: ignore
"index, expected", [(slice(1, 3), [11, 12]), (slice(0, 3, 2), [10, 12]), (-1, 13)]
)
diff --git a/tests/test_nodes.py b/tests/test_nodes.py
index 760666552..18facc33e 100644
--- a/tests/test_nodes.py
+++ b/tests/test_nodes.py
@@ -353,22 +353,6 @@ def test_legal_assignment_enum(
node_type(enum_type)
-def test_pretty_with_enum() -> None:
- cfg = OmegaConf.create()
- assert isinstance(cfg, DictConfig)
- cfg.foo = EnumNode(Enum1)
- cfg.foo = Enum1.FOO
-
- expected = """foo: FOO
-"""
- s = cfg.pretty()
- assert s == expected
- assert (
- OmegaConf.merge({"foo": EnumNode(Enum1, value="???")}, OmegaConf.create(s))
- == cfg
- )
-
-
class DummyEnum(Enum):
FOO = 1
diff --git a/tests/test_to_yaml.py b/tests/test_to_yaml.py
new file mode 100644
index 000000000..4b3ae96f0
--- /dev/null
+++ b/tests/test_to_yaml.py
@@ -0,0 +1,139 @@
+import re
+from typing import Any
+
+import pytest
+
+from omegaconf import DictConfig, EnumNode, ListConfig, OmegaConf, _utils
+
+from . import Enum1
+
+
+@pytest.mark.parametrize( # type: ignore
+ "input_, expected",
+ [
+ (["item1", "item2", dict(key3="value3")], "- item1\n- item2\n- key3: value3\n"),
+ (dict(hello="world", list=[1, 2]), "hello: world\nlist:\n- 1\n- 2\n"),
+ ],
+)
+def test_to_yaml(input_: Any, expected: str) -> None:
+ c = OmegaConf.create(input_)
+ assert expected == OmegaConf.to_yaml(c)
+ assert OmegaConf.create(OmegaConf.to_yaml(c)) == c
+
+
+@pytest.mark.parametrize( # type: ignore
+ "input_, expected",
+ [
+ (["item一", "item二", dict(key三="value三")], "- item一\n- item二\n- key三: value三\n"),
+ (dict(你好="世界", list=[1, 2]), "你好: 世界\nlist:\n- 1\n- 2\n"),
+ ],
+)
+def test_to_yaml_unicode(input_: Any, expected: str) -> None:
+ c = OmegaConf.create(input_)
+ assert expected == OmegaConf.to_yaml(c)
+ assert OmegaConf.create(OmegaConf.to_yaml(c)) == c
+
+
+@pytest.mark.parametrize( # type: ignore
+ "input_, expected, type_",
+ [
+ (["1", 1], "- '1'\n- 1\n", int),
+ (["10e2", "1.0", 1.0], "- '10e2'\n- '1.0'\n- 1.0\n", float),
+ (_utils.YAML_BOOL_TYPES, None, bool),
+ ],
+)
+def test_to_yaml_string_primitive_types_list(
+ input_: Any, expected: str, type_: type
+) -> None:
+ if type_ == bool:
+ for t in input_:
+ c = OmegaConf.create([t, 1])
+ expected = "- '%s'\n- 1\n" % t
+ assert OmegaConf.to_yaml(c) == expected
+
+ else:
+ c = OmegaConf.create(input_)
+ assert OmegaConf.to_yaml(c) == expected
+
+
+@pytest.mark.parametrize( # type: ignore
+ "input_, expected, type_",
+ [
+ ({"b": "1", "a": 1}, "b: '1'\na: 1\n", int),
+ ({"b": "10e2", "a": "1.0", "c": 1.0}, "b: '10e2'\na: '1.0'\nc: 1.0\n", float),
+ (_utils.YAML_BOOL_TYPES, None, bool),
+ ],
+)
+def test_to_yaml_string_primitive_types_dict(
+ input_: Any, expected: str, type_: type
+) -> None:
+ if type_ == bool:
+ for t in input_:
+ c = OmegaConf.create({"b": t, "a": 1})
+ assert OmegaConf.to_yaml(c) == "b: '%s'\na: 1\n" % t
+ else:
+ c = OmegaConf.create(input_)
+ assert OmegaConf.to_yaml(c) == expected
+
+
+@pytest.mark.parametrize( # type: ignore
+ "input_, resolve, expected",
+ [
+ (dict(a1="${ref}", ref="bar"), True, "bar"),
+ (dict(a1="${ref}", ref="bar"), False, "changed"),
+ ([100, "${0}"], True, 100),
+ ([100, "${0}"], False, 1000),
+ ],
+)
+def test_to_yaml_resolve(input_: Any, resolve: bool, expected: int) -> None:
+ c = OmegaConf.create(input_)
+ # without resolve, references are preserved
+ yaml_str = OmegaConf.to_yaml(c, resolve=resolve)
+ c2 = OmegaConf.create(yaml_str)
+ assert isinstance(c2, ListConfig) or isinstance(c2, DictConfig)
+ if isinstance(c2, DictConfig):
+ assert c2.a1 == "bar"
+ c2.ref = "changed"
+ assert c2.a1 == expected
+ else:
+ c2[0] = 1000
+ assert c2[1] == expected
+
+
+def test_to_yaml_sort_keys() -> None:
+ c = OmegaConf.create({"b": 2, "a": 1})
+ # keys are not sorted by default
+ assert OmegaConf.to_yaml(c) == "b: 2\na: 1\n"
+ c = OmegaConf.create({"b": 2, "a": 1})
+ assert OmegaConf.to_yaml(c, sort_keys=True) == "a: 1\nb: 2\n"
+
+
+def test_to_yaml_with_enum() -> None:
+ cfg = OmegaConf.create()
+ assert isinstance(cfg, DictConfig)
+ cfg.foo = EnumNode(Enum1)
+ cfg.foo = Enum1.FOO
+
+ expected = """foo: FOO
+"""
+ s = OmegaConf.to_yaml(cfg)
+ assert s == expected
+ assert (
+ OmegaConf.merge({"foo": EnumNode(Enum1, value="???")}, OmegaConf.create(s))
+ == cfg
+ )
+
+
+def test_pretty_deprecated() -> None:
+ c = OmegaConf.create({"foo": "bar"})
+ with pytest.warns(
+ expected_warning=UserWarning,
+ match=re.escape(
+ """
+ pretty() is deprecated and will be removed in a future version.
+ Use OmegaConf.to_yaml. Please note that the default value for
+ resolve has changed to True.
+ """,
+ ),
+ ):
+ assert c.pretty() == "foo: bar\n"