bpo-38208: Simplify string.Template by using __init_subclass__(). (GH-16256)
This commit is contained in:
parent
06cd5b6acd
commit
919f0bc8c9
|
@ -54,30 +54,7 @@ from collections import ChainMap as _ChainMap
|
||||||
|
|
||||||
_sentinel_dict = {}
|
_sentinel_dict = {}
|
||||||
|
|
||||||
class _TemplateMetaclass(type):
|
class Template:
|
||||||
pattern = r"""
|
|
||||||
%(delim)s(?:
|
|
||||||
(?P<escaped>%(delim)s) | # Escape sequence of two delimiters
|
|
||||||
(?P<named>%(id)s) | # delimiter and a Python identifier
|
|
||||||
{(?P<braced>%(bid)s)} | # delimiter and a braced identifier
|
|
||||||
(?P<invalid>) # Other ill-formed delimiter exprs
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(cls, name, bases, dct):
|
|
||||||
super(_TemplateMetaclass, cls).__init__(name, bases, dct)
|
|
||||||
if 'pattern' in dct:
|
|
||||||
pattern = cls.pattern
|
|
||||||
else:
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
class Template(metaclass=_TemplateMetaclass):
|
|
||||||
"""A string class for supporting $-substitutions."""
|
"""A string class for supporting $-substitutions."""
|
||||||
|
|
||||||
delimiter = '$'
|
delimiter = '$'
|
||||||
|
@ -89,6 +66,24 @@ class Template(metaclass=_TemplateMetaclass):
|
||||||
braceidpattern = None
|
braceidpattern = None
|
||||||
flags = _re.IGNORECASE
|
flags = _re.IGNORECASE
|
||||||
|
|
||||||
|
def __init_subclass__(cls):
|
||||||
|
super().__init_subclass__()
|
||||||
|
if 'pattern' in cls.__dict__:
|
||||||
|
pattern = cls.pattern
|
||||||
|
else:
|
||||||
|
delim = _re.escape(cls.delimiter)
|
||||||
|
id = cls.idpattern
|
||||||
|
bid = cls.braceidpattern or cls.idpattern
|
||||||
|
pattern = fr"""
|
||||||
|
{delim}(?:
|
||||||
|
(?P<escaped>{delim}) | # Escape sequence of two delimiters
|
||||||
|
(?P<named>{id}) | # delimiter and a Python identifier
|
||||||
|
{{(?P<braced>{bid})}} | # delimiter and a braced identifier
|
||||||
|
(?P<invalid>) # Other ill-formed delimiter exprs
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
cls.pattern = _re.compile(pattern, cls.flags | _re.VERBOSE)
|
||||||
|
|
||||||
def __init__(self, template):
|
def __init__(self, template):
|
||||||
self.template = template
|
self.template = template
|
||||||
|
|
||||||
|
@ -146,6 +141,9 @@ class Template(metaclass=_TemplateMetaclass):
|
||||||
self.pattern)
|
self.pattern)
|
||||||
return self.pattern.sub(convert, self.template)
|
return self.pattern.sub(convert, self.template)
|
||||||
|
|
||||||
|
# Initialize Template.pattern. __init_subclass__() is automatically called
|
||||||
|
# only for subclasses, not for the Template class itself.
|
||||||
|
Template.__init_subclass__()
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
Loading…
Reference in New Issue