summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/string.py4
-rw-r--r--Lib/test/test_string.py24
2 files changed, 27 insertions, 1 deletions
diff --git a/Lib/string.py b/Lib/string.py
index bc9508c1e6..b46e60c38f 100644
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -57,7 +57,7 @@ class _TemplateMetaclass(type):
%(delim)s(?:
(?P<escaped>%(delim)s) | # Escape sequence of two delimiters
(?P<named>%(id)s) | # delimiter and a Python identifier
- {(?P<braced>%(id)s)} | # delimiter and a braced identifier
+ {(?P<braced>%(bid)s)} | # delimiter and a braced identifier
(?P<invalid>) # Other ill-formed delimiter exprs
)
"""
@@ -70,6 +70,7 @@ class _TemplateMetaclass(type):
pattern = _TemplateMetaclass.pattern % {
'delim' : _re.escape(cls.delimiter),
'id' : cls.idpattern,
+ 'bid' : cls.braceidpattern or cls.idpattern,
}
cls.pattern = _re.compile(pattern, cls.flags | _re.VERBOSE)
@@ -79,6 +80,7 @@ class Template(metaclass=_TemplateMetaclass):
delimiter = '$'
idpattern = r'[_a-z][_a-z0-9]*'
+ braceidpattern = None
flags = _re.IGNORECASE
def __init__(self, template):
diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py
index a7b8aad8ab..6e241ac72a 100644
--- a/Lib/test/test_string.py
+++ b/Lib/test/test_string.py
@@ -282,6 +282,30 @@ class TestTemplate(unittest.TestCase):
s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what')
self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
+ def test_idpattern_override_inside_outside(self):
+ # bpo-1198569: Allow the regexp inside and outside braces to be
+ # different when deriving from Template.
+ class MyPattern(Template):
+ idpattern = r'[a-z]+'
+ braceidpattern = r'[A-Z]+'
+ flags = 0
+ m = dict(foo='foo', BAR='BAR')
+ s = MyPattern('$foo ${BAR}')
+ self.assertEqual(s.substitute(m), 'foo BAR')
+
+ def test_idpattern_override_inside_outside_invalid_unbraced(self):
+ # bpo-1198569: Allow the regexp inside and outside braces to be
+ # different when deriving from Template.
+ class MyPattern(Template):
+ idpattern = r'[a-z]+'
+ braceidpattern = r'[A-Z]+'
+ flags = 0
+ m = dict(foo='foo', BAR='BAR')
+ s = MyPattern('$FOO')
+ self.assertRaises(ValueError, s.substitute, m)
+ s = MyPattern('${bar}')
+ self.assertRaises(ValueError, s.substitute, m)
+
def test_pattern_override(self):
class MyPattern(Template):
pattern = r"""