mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-118761: Optimise import time for `string` (#132037)
				
					
				
			Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
		
							parent
							
								
									53908bd790
								
							
						
					
					
						commit
						ee3657209b
					
				
					 2 changed files with 32 additions and 15 deletions
				
			
		|  | @ -49,11 +49,18 @@ def capwords(s, sep=None): | |||
| 
 | ||||
| 
 | ||||
| #################################################################### | ||||
| import re as _re | ||||
| from collections import ChainMap as _ChainMap | ||||
| 
 | ||||
| _sentinel_dict = {} | ||||
| 
 | ||||
| 
 | ||||
| class _TemplatePattern: | ||||
|     # This descriptor is overwritten in ``Template._compile_pattern()``. | ||||
|     def __get__(self, instance, cls=None): | ||||
|         if cls is None: | ||||
|             return self | ||||
|         return cls._compile_pattern() | ||||
| _TemplatePattern = _TemplatePattern() | ||||
| 
 | ||||
| 
 | ||||
| class Template: | ||||
|     """A string class for supporting $-substitutions.""" | ||||
| 
 | ||||
|  | @ -64,14 +71,21 @@ class Template: | |||
|     # See https://bugs.python.org/issue31672 | ||||
|     idpattern = r'(?a:[_a-z][_a-z0-9]*)' | ||||
|     braceidpattern = None | ||||
|     flags = _re.IGNORECASE | ||||
|     flags = None  # default: re.IGNORECASE | ||||
| 
 | ||||
|     pattern = _TemplatePattern  # use a descriptor to compile the pattern | ||||
| 
 | ||||
|     def __init_subclass__(cls): | ||||
|         super().__init_subclass__() | ||||
|         if 'pattern' in cls.__dict__: | ||||
|             pattern = cls.pattern | ||||
|         else: | ||||
|             delim = _re.escape(cls.delimiter) | ||||
|         cls._compile_pattern() | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _compile_pattern(cls): | ||||
|         import re  # deferred import, for performance | ||||
| 
 | ||||
|         pattern = cls.__dict__.get('pattern', _TemplatePattern) | ||||
|         if pattern is _TemplatePattern: | ||||
|             delim = re.escape(cls.delimiter) | ||||
|             id = cls.idpattern | ||||
|             bid = cls.braceidpattern or cls.idpattern | ||||
|             pattern = fr""" | ||||
|  | @ -82,7 +96,10 @@ def __init_subclass__(cls): | |||
|               (?P<invalid>)             # Other ill-formed delimiter exprs | ||||
|             ) | ||||
|             """ | ||||
|         cls.pattern = _re.compile(pattern, cls.flags | _re.VERBOSE) | ||||
|         if cls.flags is None: | ||||
|             cls.flags = re.IGNORECASE | ||||
|         pat = cls.pattern = re.compile(pattern, cls.flags | re.VERBOSE) | ||||
|         return pat | ||||
| 
 | ||||
|     def __init__(self, template): | ||||
|         self.template = template | ||||
|  | @ -105,7 +122,8 @@ def substitute(self, mapping=_sentinel_dict, /, **kws): | |||
|         if mapping is _sentinel_dict: | ||||
|             mapping = kws | ||||
|         elif kws: | ||||
|             mapping = _ChainMap(kws, mapping) | ||||
|             from collections import ChainMap | ||||
|             mapping = ChainMap(kws, mapping) | ||||
|         # Helper function for .sub() | ||||
|         def convert(mo): | ||||
|             # Check the most common path first. | ||||
|  | @ -124,7 +142,8 @@ def safe_substitute(self, mapping=_sentinel_dict, /, **kws): | |||
|         if mapping is _sentinel_dict: | ||||
|             mapping = kws | ||||
|         elif kws: | ||||
|             mapping = _ChainMap(kws, mapping) | ||||
|             from collections import ChainMap | ||||
|             mapping = ChainMap(kws, mapping) | ||||
|         # Helper function for .sub() | ||||
|         def convert(mo): | ||||
|             named = mo.group('named') or mo.group('braced') | ||||
|  | @ -170,10 +189,6 @@ def get_identifiers(self): | |||
|                     self.pattern) | ||||
|         return ids | ||||
| 
 | ||||
| # Initialize Template.pattern.  __init_subclass__() is automatically called | ||||
| # only for subclasses, not for the Template class itself. | ||||
| Template.__init_subclass__() | ||||
| 
 | ||||
| 
 | ||||
| ######################################################################## | ||||
| # the Formatter class | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Adam Turner
						Adam Turner