22
33from __future__ import annotations
44
5+ import contextlib
56import typing as tp
67import typing_extensions as te
78
8- from typelib .py import refs
9+ from typelib .py import inspection , refs
910
1011ValueT = tp .TypeVar ("ValueT" )
12+ DefaultT = tp .TypeVar ("DefaultT" )
1113KeyT = te .TypeAliasType ("KeyT" , "type | refs.ForwardRef" )
1214
1315
1416class TypeContext (dict [KeyT , ValueT ], tp .Generic [ValueT ]):
1517 """A key-value mapping which can map between forward references and real types."""
1618
19+ def get (self , key : KeyT , default : ValueT | DefaultT = None ) -> ValueT | DefaultT :
20+ with contextlib .suppress (KeyError ):
21+ return self [key ]
22+
23+ return default
24+
1725 def __missing__ (self , key : type | refs .ForwardRef ):
1826 """Hook to handle missing type references.
1927
20- Allows for sharing lookup results between forward references and real types.
28+ Allows for sharing lookup results between forward references, type aliases, real types.
2129
2230 Args:
2331 key: The type or reference.
@@ -26,5 +34,12 @@ def __missing__(self, key: type | refs.ForwardRef):
2634 if isinstance (key , refs .ForwardRef ):
2735 raise KeyError (key )
2836
37+ unwrapped = inspection .unwrap (key )
38+ if unwrapped in self :
39+ val = self [unwrapped ]
40+ # Store the value at the original key to short-circuit in future
41+ self [key ] = val
42+ return val
43+
2944 ref = refs .forwardref (key )
3045 return self [ref ]
0 commit comments