Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/zenml/utils/string_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def format_name_template(
KeyError: If a key in template is missing in the substitutions.
ValueError: If the formatted name is empty.
"""
substitutions = substitutions or {}
substitutions = dict(substitutions or {})

if ("date" not in substitutions and "{date}" in name_template) or (
"time" not in substitutions and "{time}" in name_template
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/utils/test_string_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,29 @@ def substitution_func(s):
{3: "value_suffix", "key_suffix": model_sub},
set(["set_value_suffix", 4]),
]


def test_format_name_template_does_not_mutate_substitutions() -> None:
"""The caller's substitutions dict must not be modified.

`substitutions or {}` only builds a new dict for a falsy argument, so a
non-empty dict was aliased and had date/time injected into it.
"""
substitutions = {"custom": "value"}

formatted = string_utils.format_name_template(
"run-{custom}-{date}-{time}", substitutions=substitutions
)

assert substitutions == {"custom": "value"}
assert formatted.startswith("run-value-")


def test_format_name_template_uses_given_substitutions() -> None:
"""Explicit date/time substitutions are still honored."""
formatted = string_utils.format_name_template(
"run-{date}-{time}",
substitutions={"date": "2020_01_01", "time": "00_00_00"},
)

assert formatted == "run-2020_01_01-00_00_00"