1919"""
2020
2121from abc import abstractmethod , ABCMeta
22- import annotationlib
23- from annotationlib import ForwardRef
2422import collections
2523from collections import defaultdict
2624import collections .abc
163161 'Unpack' ,
164162]
165163
164+ class _LazyAnnotationLib :
165+ def __getattr__ (self , attr ):
166+ global _lazy_annotationlib
167+ import annotationlib
168+ _lazy_annotationlib = annotationlib
169+ return getattr (annotationlib , attr )
170+
171+ _lazy_annotationlib = _LazyAnnotationLib ()
172+
166173
167174def _type_convert (arg , module = None , * , allow_special_forms = False ):
168175 """For converting None to type(None), and strings to ForwardRef."""
@@ -246,7 +253,7 @@ def _type_repr(obj):
246253 if isinstance (obj , tuple ):
247254 # Special case for `repr` of types with `ParamSpec`:
248255 return '[' + ', ' .join (_type_repr (t ) for t in obj ) + ']'
249- return annotationlib .value_to_string (obj )
256+ return _lazy_annotationlib .value_to_string (obj )
250257
251258
252259def _collect_type_parameters (args , * , enforce_default_ordering : bool = True ):
@@ -423,7 +430,7 @@ def __repr__(self):
423430
424431
425432def _eval_type (t , globalns , localns , type_params = _sentinel , * , recursive_guard = frozenset (),
426- format = annotationlib . Format . VALUE , owner = None ):
433+ format = None , owner = None ):
427434 """Evaluate all forward references in the given type t.
428435
429436 For use of globalns and localns see the docstring for get_type_hints().
@@ -433,7 +440,7 @@ def _eval_type(t, globalns, localns, type_params=_sentinel, *, recursive_guard=f
433440 if type_params is _sentinel :
434441 _deprecation_warning_for_no_type_params_passed ("typing._eval_type" )
435442 type_params = ()
436- if isinstance (t , ForwardRef ):
443+ if isinstance (t , _lazy_annotationlib . ForwardRef ):
437444 # If the forward_ref has __forward_module__ set, evaluate() infers the globals
438445 # from the module, and it will probably pick better than the globals we have here.
439446 if t .__forward_module__ is not None :
@@ -930,7 +937,7 @@ def run(arg: Child | Unrelated):
930937
931938
932939def _make_forward_ref (code , ** kwargs ):
933- forward_ref = ForwardRef (code , ** kwargs )
940+ forward_ref = _lazy_annotationlib . ForwardRef (code , ** kwargs )
934941 # For compatibility, eagerly compile the forwardref's code.
935942 forward_ref .__forward_code__
936943 return forward_ref
@@ -943,7 +950,7 @@ def evaluate_forward_ref(
943950 globals = None ,
944951 locals = None ,
945952 type_params = None ,
946- format = annotationlib . Format . VALUE ,
953+ format = None ,
947954 _recursive_guard = frozenset (),
948955):
949956 """Evaluate a forward reference as a type hint.
@@ -965,10 +972,11 @@ def evaluate_forward_ref(
965972 evaluating the forward reference. This parameter should be provided (though
966973 it may be an empty tuple) if *owner* is not given and the forward reference
967974 does not already have an owner set. *format* specifies the format of the
968- annotation and is a member of the annotationlib.Format enum.
975+ annotation and is a member of the annotationlib.Format enum, defaulting to
976+ VALUE.
969977
970978 """
971- if format == annotationlib .Format .STRING :
979+ if format == _lazy_annotationlib .Format .STRING :
972980 return forward_ref .__forward_arg__
973981 if forward_ref .__forward_arg__ in _recursive_guard :
974982 return forward_ref
@@ -977,7 +985,7 @@ def evaluate_forward_ref(
977985 value = forward_ref .evaluate (globals = globals , locals = locals ,
978986 type_params = type_params , owner = owner )
979987 except NameError :
980- if format == annotationlib .Format .FORWARDREF :
988+ if format == _lazy_annotationlib .Format .FORWARDREF :
981989 return forward_ref
982990 else :
983991 raise
@@ -2257,7 +2265,7 @@ def greet(name: str) -> None:
22572265
22582266
22592267def get_type_hints (obj , globalns = None , localns = None , include_extras = False ,
2260- * , format = annotationlib . Format . VALUE ):
2268+ * , format = None ):
22612269 """Return type hints for an object.
22622270
22632271 This is often the same as obj.__annotations__, but it handles
@@ -2290,12 +2298,15 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
22902298 """
22912299 if getattr (obj , '__no_type_check__' , None ):
22922300 return {}
2301+ Format = _lazy_annotationlib .Format
2302+ if format is None :
2303+ format = Format .VALUE
22932304 # Classes require a special treatment.
22942305 if isinstance (obj , type ):
22952306 hints = {}
22962307 for base in reversed (obj .__mro__ ):
2297- ann = annotationlib .get_annotations (base , format = format )
2298- if format == annotationlib . Format .STRING :
2308+ ann = _lazy_annotationlib .get_annotations (base , format = format )
2309+ if format == Format .STRING :
22992310 hints .update (ann )
23002311 continue
23012312 if globalns is None :
@@ -2319,12 +2330,12 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
23192330 value = _eval_type (value , base_globals , base_locals , base .__type_params__ ,
23202331 format = format , owner = obj )
23212332 hints [name ] = value
2322- if include_extras or format == annotationlib . Format .STRING :
2333+ if include_extras or format == Format .STRING :
23232334 return hints
23242335 else :
23252336 return {k : _strip_annotations (t ) for k , t in hints .items ()}
23262337
2327- hints = annotationlib .get_annotations (obj , format = format )
2338+ hints = _lazy_annotationlib .get_annotations (obj , format = format )
23282339 if (
23292340 not hints
23302341 and not isinstance (obj , types .ModuleType )
@@ -2333,7 +2344,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
23332344 and not hasattr (obj , '__annotate__' )
23342345 ):
23352346 raise TypeError (f"{ obj !r} is not a module, class, or callable." )
2336- if format == annotationlib . Format .STRING :
2347+ if format == Format .STRING :
23372348 return hints
23382349
23392350 if globalns is None :
@@ -2850,10 +2861,10 @@ def _make_eager_annotate(types):
28502861 for key , val in types .items ()}
28512862 def annotate (format ):
28522863 match format :
2853- case annotationlib .Format .VALUE | annotationlib .Format .FORWARDREF :
2864+ case _lazy_annotationlib .Format .VALUE | _lazy_annotationlib .Format .FORWARDREF :
28542865 return checked_types
2855- case annotationlib .Format .STRING :
2856- return annotationlib .annotations_to_string (types )
2866+ case _lazy_annotationlib .Format .STRING :
2867+ return _lazy_annotationlib .annotations_to_string (types )
28572868 case _:
28582869 raise NotImplementedError (format )
28592870 return annotate
@@ -2884,16 +2895,18 @@ def __new__(cls, typename, bases, ns):
28842895 annotate = _make_eager_annotate (types )
28852896 elif "__annotate__" in ns :
28862897 original_annotate = ns ["__annotate__" ]
2887- types = annotationlib .call_annotate_function (original_annotate , annotationlib .Format .FORWARDREF )
2898+ types = _lazy_annotationlib .call_annotate_function (
2899+ original_annotate , _lazy_annotationlib .Format .FORWARDREF )
28882900 field_names = list (types )
28892901
28902902 # For backward compatibility, type-check all the types at creation time
28912903 for typ in types .values ():
28922904 _type_check (typ , "field annotation must be a type" )
28932905
28942906 def annotate (format ):
2895- annos = annotationlib .call_annotate_function (original_annotate , format )
2896- if format != annotationlib .Format .STRING :
2907+ annos = _lazy_annotationlib .call_annotate_function (
2908+ original_annotate , format )
2909+ if format != _lazy_annotationlib .Format .STRING :
28972910 return {key : _type_check (val , f"field { key } annotation must be a type" )
28982911 for key , val in annos .items ()}
28992912 return annos
@@ -3069,8 +3082,8 @@ def __new__(cls, name, bases, ns, total=True):
30693082 own_annotations = ns ["__annotations__" ]
30703083 elif "__annotate__" in ns :
30713084 own_annotate = ns ["__annotate__" ]
3072- own_annotations = annotationlib .call_annotate_function (
3073- own_annotate , annotationlib .Format .FORWARDREF , owner = tp_dict
3085+ own_annotations = _lazy_annotationlib .call_annotate_function (
3086+ own_annotate , _lazy_annotationlib .Format .FORWARDREF , owner = tp_dict
30743087 )
30753088 else :
30763089 own_annotate = None
@@ -3137,18 +3150,20 @@ def __annotate__(format):
31373150 base_annotate = base .__annotate__
31383151 if base_annotate is None :
31393152 continue
3140- base_annos = annotationlib .call_annotate_function (base .__annotate__ , format , owner = base )
3153+ base_annos = _lazy_annotationlib .call_annotate_function (
3154+ base .__annotate__ , format , owner = base )
31413155 annos .update (base_annos )
31423156 if own_annotate is not None :
3143- own = annotationlib .call_annotate_function (own_annotate , format , owner = tp_dict )
3144- if format != annotationlib .Format .STRING :
3157+ own = _lazy_annotationlib .call_annotate_function (
3158+ own_annotate , format , owner = tp_dict )
3159+ if format != _lazy_annotationlib .Format .STRING :
31453160 own = {
31463161 n : _type_check (tp , msg , module = tp_dict .__module__ )
31473162 for n , tp in own .items ()
31483163 }
3149- elif format == annotationlib .Format .STRING :
3150- own = annotationlib .annotations_to_string (own_annotations )
3151- elif format in (annotationlib .Format .FORWARDREF , annotationlib .Format .VALUE ):
3164+ elif format == _lazy_annotationlib .Format .STRING :
3165+ own = _lazy_annotationlib .annotations_to_string (own_annotations )
3166+ elif format in (_lazy_annotationlib .Format .FORWARDREF , _lazy_annotationlib .Format .VALUE ):
31523167 own = own_checked_annotations
31533168 else :
31543169 raise NotImplementedError (format )
@@ -3732,7 +3747,9 @@ def __getattr__(attr):
37323747 Soft-deprecated objects which are costly to create
37333748 are only created on-demand here.
37343749 """
3735- if attr in {"Pattern" , "Match" }:
3750+ if attr == "ForwardRef" :
3751+ obj = _lazy_annotationlib .ForwardRef
3752+ elif attr in {"Pattern" , "Match" }:
37363753 import re
37373754 obj = _alias (getattr (re , attr ), 1 )
37383755 elif attr in {"ContextManager" , "AsyncContextManager" }:
0 commit comments