@@ -94,7 +94,7 @@ def __delitem__(self, key: KT) -> None:
94
94
# and discover later on that we need to re-add all this infrastructure...
95
95
# _GENERIC_TYPES_CACHE = DeepChainMap(GenericTypesCache(), LimitedDict())
96
96
97
- _GENERIC_TYPES_CACHE = GenericTypesCache ( )
97
+ _GENERIC_TYPES_CACHE : ContextVar [ GenericTypesCache | None ] = ContextVar ( '_GENERIC_TYPES_CACHE' , default = None )
98
98
99
99
100
100
class PydanticGenericMetadata (typing_extensions .TypedDict ):
@@ -453,14 +453,24 @@ def get_cached_generic_type_early(parent: type[BaseModel], typevar_values: Any)
453
453
during validation, I think it is worthwhile to ensure that types that are functionally equivalent are actually
454
454
equal.
455
455
"""
456
- return _GENERIC_TYPES_CACHE .get (_early_cache_key (parent , typevar_values ))
456
+ generic_types_cache = _GENERIC_TYPES_CACHE .get ()
457
+ if generic_types_cache is None :
458
+ generic_types_cache = GenericTypesCache ()
459
+ _GENERIC_TYPES_CACHE .set (generic_types_cache )
460
+ return generic_types_cache .get (_early_cache_key (parent , typevar_values ))
457
461
458
462
459
463
def get_cached_generic_type_late (
460
464
parent : type [BaseModel ], typevar_values : Any , origin : type [BaseModel ], args : tuple [Any , ...]
461
465
) -> type [BaseModel ] | None :
462
466
"""See the docstring of `get_cached_generic_type_early` for more information about the two-stage cache lookup."""
463
- cached = _GENERIC_TYPES_CACHE .get (_late_cache_key (origin , args , typevar_values ))
467
+ generic_types_cache = _GENERIC_TYPES_CACHE .get ()
468
+ if (
469
+ generic_types_cache is None
470
+ ): # pragma: no cover (early cache is guaranteed to run first and initialize the cache)
471
+ generic_types_cache = GenericTypesCache ()
472
+ _GENERIC_TYPES_CACHE .set (generic_types_cache )
473
+ cached = generic_types_cache .get (_late_cache_key (origin , args , typevar_values ))
464
474
if cached is not None :
465
475
set_cached_generic_type (parent , typevar_values , cached , origin , args )
466
476
return cached
@@ -476,11 +486,17 @@ def set_cached_generic_type(
476
486
"""See the docstring of `get_cached_generic_type_early` for more information about why items are cached with
477
487
two different keys.
478
488
"""
479
- _GENERIC_TYPES_CACHE [_early_cache_key (parent , typevar_values )] = type_
489
+ generic_types_cache = _GENERIC_TYPES_CACHE .get ()
490
+ if (
491
+ generic_types_cache is None
492
+ ): # pragma: no cover (cache lookup is guaranteed to run first and initialize the cache)
493
+ generic_types_cache = GenericTypesCache ()
494
+ _GENERIC_TYPES_CACHE .set (generic_types_cache )
495
+ generic_types_cache [_early_cache_key (parent , typevar_values )] = type_
480
496
if len (typevar_values ) == 1 :
481
- _GENERIC_TYPES_CACHE [_early_cache_key (parent , typevar_values [0 ])] = type_
497
+ generic_types_cache [_early_cache_key (parent , typevar_values [0 ])] = type_
482
498
if origin and args :
483
- _GENERIC_TYPES_CACHE [_late_cache_key (origin , args , typevar_values )] = type_
499
+ generic_types_cache [_late_cache_key (origin , args , typevar_values )] = type_
484
500
485
501
486
502
def _union_orderings_key (typevar_values : Any ) -> Any :
0 commit comments