-import re
import sys
-import copy
import types
import inspect
import keyword
import annotationlib
import abc
from reprlib import recursive_repr
+lazy import copy
+lazy import re
__all__ = ['dataclass',
_POST_INIT_NAME = '__post_init__'
# String regex that string annotations for ClassVar or InitVar must match.
-# Allows "identifier.identifier[" or "identifier[".
-# https://bugs.python.org/issue33453 for details.
-_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
+# This regular expression is compiled on demand so that 're' module can be imported lazily
+_MODULE_IDENTIFIER_RE = None
# Atomic immutable types which don't require any recursive handling and for which deepcopy
# returns the same object. We can provide a fast-path for these types in asdict and astuple.
# a eval() penalty for every single field of every dataclass
# that's defined. It was judged not worth it.
- match = _MODULE_IDENTIFIER_RE.match(annotation)
+ # String regex that string annotations for ClassVar or InitVar must match.
+ # Allows "identifier.identifier[" or "identifier[".
+ # https://github.com/python/cpython/issues/77634 for details.
+ global _MODULE_IDENTIFIER_RE
+ if _MODULE_IDENTIFIER_RE is None:
+ _MODULE_IDENTIFIER_RE = re.compile(r'(?:\s*(\w+)\s*\.)?\s*(\w+)')
+
+ match = _MODULE_IDENTIFIER_RE.prefixmatch(annotation)
if match:
ns = None
- module_name = match.group(1)
+ module_name = match[1]
if not module_name:
# No module name, assume the class's module did
# "from dataclasses import InitVar".
module = sys.modules.get(cls.__module__)
if module and module.__dict__.get(module_name) is a_module:
ns = sys.modules.get(a_type.__module__).__dict__
- if ns and is_type_predicate(ns.get(match.group(2)), a_module):
+ if ns and is_type_predicate(ns.get(match[2]), a_module):
return True
return False