88import tempfile
99import threading
1010import uuid
11+ import weakref
1112from dataclasses import dataclass
1213from pathlib import Path
1314from typing import Any , Protocol
@@ -290,6 +291,16 @@ class _SessionEntry:
290291 session : _DeclarationQuerySession
291292
292293
294+ def _close_declaration_sessions (
295+ sessions : dict [LeanEnvironment , _SessionEntry ],
296+ session_locks : dict [LeanEnvironment , threading .Lock ],
297+ ) -> None :
298+ """Release declaration sessions retained past their backend's lifetime."""
299+ for environment , entry in list (sessions .items ()):
300+ with session_locks [environment ]:
301+ entry .session .close ()
302+
303+
293304class LeanSubprocessDeclarationBackend :
294305 """Reuse one catalog across bounded processes for each validated environment."""
295306
@@ -312,6 +323,12 @@ def __init__(
312323 self ._session_locks = {
313324 environment : threading .Lock () for environment in LeanEnvironment
314325 }
326+ self ._finalizer = weakref .finalize (
327+ self ,
328+ _close_declaration_sessions ,
329+ self ._sessions ,
330+ self ._session_locks ,
331+ )
315332
316333 def environment_digest (self , environment : LeanEnvironment ) -> str :
317334 try :
@@ -450,6 +467,7 @@ def close(self) -> None:
450467 for environment , lock in self ._session_locks .items ():
451468 with lock :
452469 self ._discard_session (environment )
470+ self ._finalizer .detach ()
453471
454472 def _start_session (
455473 self ,
0 commit comments