diff --git a/news/572.api_change b/news/572.api_change new file mode 100644 index 000000000..4919b8762 --- /dev/null +++ b/news/572.api_change @@ -0,0 +1,2 @@ +Implicitly empty resolver arguments (e.g., `${foo:a,}`) are deprecated in favor of explicit quoted strings (e.g., `${foo:a,""}`) + diff --git a/omegaconf/grammar_visitor.py b/omegaconf/grammar_visitor.py index 8f8b87863..e25d62fbb 100644 --- a/omegaconf/grammar_visitor.py +++ b/omegaconf/grammar_visitor.py @@ -250,12 +250,13 @@ def visitSequence( # (element (COMMA element?)*) | (COMMA element?)+ assert ctx.getChildCount() >= 1 + # DEPRECATED: remove in 2.2 (revert #571) def empty_str_warning() -> None: txt = ctx.getText() warnings.warn( f"In the sequence `{txt}` some elements are missing: please replace " - f"them with empty strings (\"\" or '') since this will not be supported " - f"anymore in the future.", + f"them with empty quoted strings. " + f"See https://github.com/omry/omegaconf/issues/572 for details.", category=UserWarning, ) diff --git a/tests/test_grammar.py b/tests/test_grammar.py index 28f5b07b8..f585e632f 100644 --- a/tests/test_grammar.py +++ b/tests/test_grammar.py @@ -1,8 +1,9 @@ import math +import re from typing import Any, Callable, List, Optional, Tuple import antlr4 -from pytest import mark, param, raises +from pytest import mark, param, raises, warns from omegaconf import ( DictConfig, @@ -369,6 +370,30 @@ def test_config_value( parse_tree, expected_visit = self._parse("configValue", definition, expected) self._visit_with_config(parse_tree, expected_visit) + @parametrize_from( + [ + ("trailing_comma", "${test:a,b,}", ["a", "b", ""]), + ("empty_middle", "${test:a,,b}", ["a", "", "b"]), + ("empty_first", "${test:,a,b}", ["", "a", "b"]), + ("single_comma", "${test:,}", ["", ""]), + ( + "mixed_with_ws", + "${test: ,a,b,\t,,c, \t \t ,d,, \t}", + ["", "a", "b", "", "", "c", "", "d", "", ""], + ), + ] + ) + def test_deprecated_empty_args( + self, restore_resolvers: Any, definition: str, expected: Any + ) -> None: + OmegaConf.register_new_resolver("test", self._resolver_test) + + parse_tree, expected_visit = self._parse("singleElement", definition, expected) + with warns( + UserWarning, match=re.escape("https://github.com/omry/omegaconf/issues/572") + ): + self._visit_with_config(parse_tree, expected_visit) + def _check_is_same_type(self, value: Any, expected: Any) -> None: """ Helper function to validate that types of `value` and `expected are the same.