@@ -54,30 +54,7 @@ def capwords(s, sep=None):
54
54
55
55
_sentinel_dict = {}
56
56
57
- class _TemplateMetaclass (type ):
58
- pattern = r"""
59
- %(delim)s(?:
60
- (?P<escaped>%(delim)s) | # Escape sequence of two delimiters
61
- (?P<named>%(id)s) | # delimiter and a Python identifier
62
- {(?P<braced>%(bid)s)} | # delimiter and a braced identifier
63
- (?P<invalid>) # Other ill-formed delimiter exprs
64
- )
65
- """
66
-
67
- def __init__ (cls , name , bases , dct ):
68
- super (_TemplateMetaclass , cls ).__init__ (name , bases , dct )
69
- if 'pattern' in dct :
70
- pattern = cls .pattern
71
- else :
72
- pattern = _TemplateMetaclass .pattern % {
73
- 'delim' : _re .escape (cls .delimiter ),
74
- 'id' : cls .idpattern ,
75
- 'bid' : cls .braceidpattern or cls .idpattern ,
76
- }
77
- cls .pattern = _re .compile (pattern , cls .flags | _re .VERBOSE )
78
-
79
-
80
- class Template (metaclass = _TemplateMetaclass ):
57
+ class Template :
81
58
"""A string class for supporting $-substitutions."""
82
59
83
60
delimiter = '$'
@@ -89,6 +66,24 @@ class Template(metaclass=_TemplateMetaclass):
89
66
braceidpattern = None
90
67
flags = _re .IGNORECASE
91
68
69
+ def __init_subclass__ (cls ):
70
+ super ().__init_subclass__ ()
71
+ if 'pattern' in cls .__dict__ :
72
+ pattern = cls .pattern
73
+ else :
74
+ delim = _re .escape (cls .delimiter )
75
+ id = cls .idpattern
76
+ bid = cls .braceidpattern or cls .idpattern
77
+ pattern = fr"""
78
+ { delim } (?:
79
+ (?P<escaped>{ delim } ) | # Escape sequence of two delimiters
80
+ (?P<named>{
BD6D
id } ) | # delimiter and a Python identifier
81
+ {{(?P<braced>{ bid } )}} | # delimiter and a braced identifier
82
+ (?P<invalid>) # Other ill-formed delimiter exprs
83
+ )
84
+ """
85
+ cls .pattern = _re .compile (pattern , cls .flags | _re .VERBOSE )
86
+
92
87
def __init__ (self , template ):
93
88
self .template = template
94
89
@@ -146,6 +141,9 @@ def convert(mo):
146
141
self .pattern )
147
142
return self .pattern .sub (convert , self .template )
148
143
144
+ # Initialize Template.pattern. __init_subclass__() is automatically called
145
+ # only for subclasses, not for the Template class itself.
146
+ Template .__init_subclass__ ()
149
147
150
148
151
149
########################################################################
0 commit comments