From e96e53d1069797779d0d13fbb638d405b03630e9 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 | 21 +++++++++++++++++++++ omegaconf/config.py | 2 +- omegaconf/omegaconf.py | 17 ++++++++++++++++- tests/test_base_config.py | 17 +++++++++++++++++ tests/test_interpolation.py | 25 ++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 3 deletions(-) diff --git a/docs/source/usage.rst b/docs/source/usage.rst index e383efbf5..d58aba5c6 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -255,6 +255,27 @@ This example creates a resolver that adds 10 the the given value. 1000 +Custom resolvers also support variadic argument lists. Commas designate the boundaries between arguments. +Any you can escape them using the :code:`\` character. The strings will get stripped on both ends unles you escape +the whitespace with :code:`\` + +.. doctest:: + + >>> OmegaConf.register_resolver("concat", lambda x,y: x+y) + >>> c = OmegaConf.create({ + ... 'key': '${concat:Hello\ ,World}' + ... 'no_escape': '${concat:Hello, World}' + ... 'escape_whitespace': '${concat:Hello,\ World}' + ... }) + >>> c.key + "Hello World" + >>> c.no_escape + "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..256cfef1b 100644 --- a/omegaconf/config.py +++ b/omegaconf/config.py @@ -416,7 +416,7 @@ 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)) + match_list = list(re.finditer(r"\${(\w+:)?(.+?)?}", value)) if len(match_list) == 0: return value diff --git a/omegaconf/omegaconf.py b/omegaconf/omegaconf.py index e00b6bef5..df66a2b25 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,20 @@ def merge(*others): target.merge_with(*others[1:]) return target + @staticmethod + def _unescape_word_boundary(match): + if match.start() == 0 or match.end() == len(match.string): + return '' + return match.group(0) + + @staticmethod + def _tokenize_args(string): + if string is None or string == '': + return [] + escaped = re.split(r'(?