@@ -212,6 +212,21 @@ def _bind_scope(
212212 stack .close ()
213213
214214
215+ class _SealedScopeCache (MutableMapping [Any , Any ]):
216+ __slots__ = ()
217+
218+ @staticmethod
219+ def guard (* args : Any , ** kwargs : Any ) -> NoReturn :
220+ raise ScopeError ("Can't access cache of an exited scope." )
221+
222+ __delitem__ = __getitem__ = __iter__ = __len__ = __setitem__ = guard
223+
224+
225+ _sealed_cache = _SealedScopeCache ()
226+
227+ del _SealedScopeCache
228+
229+
215230@runtime_checkable
216231class Scope (Protocol ):
217232 __slots__ = ()
@@ -227,14 +242,13 @@ def enter[T](self, context_manager: ContextManager[T]) -> T:
227242 raise NotImplementedError
228243
229244
230- @dataclass (repr = False , frozen = True , slots = True )
245+ @dataclass (repr = False , eq = False , slots = True )
231246class BaseScope [T ](Scope , ABC ):
232247 delegate : T
233- cache : MutableMapping [SlotKey [Any ], Any ] = field (
234- default_factory = dict ,
235- init = False ,
236- hash = False ,
237- )
248+ cache : MutableMapping [SlotKey [Any ], Any ] = field (default_factory = dict , init = False )
249+
250+ def close (self ) -> None :
251+ self .cache = _sealed_cache
238252
239253
240254class AsyncScope (BaseScope [AsyncExitStack ]):
@@ -253,6 +267,7 @@ async def __aexit__(
253267 exc_value : BaseException | None ,
254268 traceback : TracebackType | None ,
255269 ) -> Any :
270+ self .close ()
256271 return await self .delegate .__aexit__ (exc_type , exc_value , traceback )
257272
258273 async def aenter [T ](self , context_manager : AsyncContextManager [T ]) -> T :
@@ -278,6 +293,7 @@ def __exit__(
278293 exc_value : BaseException | None ,
279294 traceback : TracebackType | None ,
280295 ) -> Any :
296+ self .close ()
281297 return self .delegate .__exit__ (exc_type , exc_value , traceback )
282298
283299 async def aenter [T ](self , context_manager : AsyncContextManager [T ]) -> NoReturn :
0 commit comments