From 3c053c4fa1476bbeecb11842b70fcd9821ba7cd7 Mon Sep 17 00:00:00 2001 From: swist Date: Wed, 23 Oct 2019 17:37:56 +0100 Subject: [PATCH] Loosen up regex requirements in resolve single OmegaConf's templating language allows very few characters. There are some use cases where you'd want to have special characters so that your custom resolver can handle resolution there (kind of like embedding a templating language inside of OmegaConfs). This allows such behaviour without seemingly breaking anything too majorly --- docs/source/usage.rst | 20 ++++++++++++++++++++ omegaconf/config.py | 4 +++- omegaconf/omegaconf.py | 16 +++++++++++++++- tests/test_base_config.py | 17 +++++++++++++++++ tests/test_interpolation.py | 17 ++++++++++++++++- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/docs/source/usage.rst b/docs/source/usage.rst index e383efbf5..6a5270214 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -255,6 +255,26 @@ This example creates a resolver that adds 10 the the given value. 1000 +Custom resolvers support variadic argument lists in the form of a comma separated list of zero or more values (coming in OmegaConf 1.3.1). +Whitespaces are stripped from both ends of each value ("foo,bar" is the same as "foo, bar "). +You can use literal commas and spaces anywhere by escaping (:code:`\,` and :code:`\ `). +.. doctest:: + + >>> OmegaConf.register_resolver("concat", lambda x,y: x+y) + >>> c = OmegaConf.create({ + ... 'key1': '${concat:Hello,World}', + ... 'key_trimmed': '${concat:Hello , World}', + ... 'escape_whitespace': '${concat:Hello,\ World}', + ... }) + >>> c.key1 + 'HelloWorld' + >>> c.key_trimmed + 'HelloWorld' + >>> c.escape_whitespace + 'Hello World' + + + Merging configurations ---------------------- Merging configurations enables the creation of reusable configuration files for each logical component diff --git a/omegaconf/config.py b/omegaconf/config.py index 11d5499ba..0a8995d40 100644 --- a/omegaconf/config.py +++ b/omegaconf/config.py @@ -416,7 +416,9 @@ def _resolve_value(root_node, inter_type, inter_key): return ret def _resolve_single(self, value): - match_list = list(re.finditer(r"\${(\w+:)?([\w\.%_-]+?)}", value)) + key_prefix = r"\${(\w+:)?" + legal_characters = r"([\w\.%_ \\,-]*?)}" + match_list = list(re.finditer(key_prefix+legal_characters, value)) if len(match_list) == 0: return value diff --git a/omegaconf/omegaconf.py b/omegaconf/omegaconf.py index e00b6bef5..03e908b70 100644 --- a/omegaconf/omegaconf.py +++ b/omegaconf/omegaconf.py @@ -2,6 +2,7 @@ import copy import io import os +import re import sys import warnings from contextlib import contextmanager @@ -137,6 +138,19 @@ def merge(*others): target.merge_with(*others[1:]) return target + + @staticmethod + def _tokenize_args(string): + if string is None or string == '': + return [] + def _unescape_word_boundary(match): + if match.start() == 0 or match.end() == len(match.string): + return '' + return match.group(0) + escaped = re.split(r'(?