[Python-checkins] bpo-38208: Simplify string.Template by using __init_subclass__(). (GH-16256)

Serhiy Storchaka webhook-mailer at python.org
Mon Oct 21 02:36:25 EDT 2019


https://github.com/python/cpython/commit/919f0bc8c904d3aa13eedb2dd1fe9c6b0555a591
commit: 919f0bc8c904d3aa13eedb2dd1fe9c6b0555a591
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-10-21T09:36:21+03:00
summary:

bpo-38208: Simplify string.Template by using __init_subclass__(). (GH-16256)

files:
M Lib/string.py

diff --git a/Lib/string.py b/Lib/string.py
index b423ff5dc6f69..489777b10c25d 100644
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -54,30 +54,7 @@ def capwords(s, sep=None):
 
 _sentinel_dict = {}
 
-class _TemplateMetaclass(type):
-    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):
+class Template:
     """A string class for supporting $-substitutions."""
 
     delimiter = '$'
@@ -89,6 +66,24 @@ class Template(metaclass=_TemplateMetaclass):
     braceidpattern = None
     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):
         self.template = template
 
@@ -146,6 +141,9 @@ def convert(mo):
                              self.pattern)
         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__()
 
 
 ########################################################################



More information about the Python-checkins mailing list