1- import re
21import sys
3- import copy
42import types
53import inspect
64import keyword
75import itertools
86import annotationlib
97import abc
108from reprlib import recursive_repr
9+ lazy import copy
10+ lazy import re
1111
1212
1313__all__ = ['dataclass' ,
@@ -217,9 +217,8 @@ def __repr__(self):
217217_POST_INIT_NAME = '__post_init__'
218218
219219# String regex that string annotations for ClassVar or InitVar must match.
220- # Allows "identifier.identifier[" or "identifier[".
221- # https://bugs.python.org/issue33453 for details.
222- _MODULE_IDENTIFIER_RE = re .compile (r'^(?:\s*(\w+)\s*\.)?\s*(\w+)' )
220+ # This regular expression is compiled on demand so that 're' module can be imported lazily
221+ _MODULE_IDENTIFIER_RE = None
223222
224223# Atomic immutable types which don't require any recursive handling and for which deepcopy
225224# returns the same object. We can provide a fast-path for these types in asdict and astuple.
@@ -804,10 +803,17 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
804803 # a eval() penalty for every single field of every dataclass
805804 # that's defined. It was judged not worth it.
806805
807- match = _MODULE_IDENTIFIER_RE .match (annotation )
806+ # String regex that string annotations for ClassVar or InitVar must match.
807+ # Allows "identifier.identifier[" or "identifier[".
808+ # https://github.com/python/cpython/issues/77634 for details.
809+ global _MODULE_IDENTIFIER_RE
810+ if _MODULE_IDENTIFIER_RE is None :
811+ _MODULE_IDENTIFIER_RE = re .compile (r'(?:\s*(\w+)\s*\.)?\s*(\w+)' )
812+
813+ match = _MODULE_IDENTIFIER_RE .prefixmatch (annotation )
808814 if match :
809815 ns = None
810- module_name = match . group ( 1 )
816+ module_name = match [ 1 ]
811817 if not module_name :
812818 # No module name, assume the class's module did
813819 # "from dataclasses import InitVar".
@@ -817,7 +823,7 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
817823 module = sys .modules .get (cls .__module__ )
818824 if module and module .__dict__ .get (module_name ) is a_module :
819825 ns = sys .modules .get (a_type .__module__ ).__dict__
820- if ns and is_type_predicate (ns .get (match . group ( 2 ) ), a_module ):
826+ if ns and is_type_predicate (ns .get (match [ 2 ] ), a_module ):
821827 return True
822828 return False
823829
0 commit comments