Skip to content

Commit eaa7e14

Browse files
committed
refactor(robot): remove unnecessary finalizers and dispose chain
Remove redundant _release_watchers_finalizer from _ImportEntry — file watcher cleanup is already handled explicitly by _remove_file_watcher() during invalidation and by server_shutdown() at LS shutdown. Remove the _dispose_finalizer/dispose() chain through ImportsManager, DocumentsCacheHelper, RobotFrameworkLanguageProvider, CodeAnalyzer, and CLI. With the per-entry finalizers gone, these only cleared dicts that Python already cleans up at process exit. Fix broken finalizer in Workspace.add_file_watchers() where the closure captured the entry object, preventing it from ever being garbage collected. Set atexit=False on sentinel finalizers so they only fire during normal GC (needed for LS live cleanup), not at interpreter shutdown.
1 parent 9b89623 commit eaa7e14

File tree

3 files changed

+18
-37
lines changed

3 files changed

+18
-37
lines changed

packages/analyze/src/robotcode/analyze/code/cli.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,13 +398,14 @@ def code(
398398

399399
result_collector = ResultCollector(mask)
400400
result_collector.start()
401+
analyzer = CodeAnalyzer(
402+
app=app,
403+
analysis_config=analyzer_config.to_workspace_analysis_config(),
404+
robot_profile=robot_profile,
405+
root_folder=root_folder,
406+
)
401407
try:
402-
for e in CodeAnalyzer(
403-
app=app,
404-
analysis_config=analyzer_config.to_workspace_analysis_config(),
405-
robot_profile=robot_profile,
406-
root_folder=root_folder,
407-
).run(paths=paths, filter=filter):
408+
for e in analyzer.run(paths=paths, filter=filter):
408409
result_collector.add_diagnostics_report(e)
409410

410411
for e in result_collector.diagnostics:

packages/language_server/src/robotcode/language_server/common/parts/workspace.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,6 @@ def _done(f: Task[None]) -> None:
415415
# TODO: implement own filewatcher if not supported by language server client
416416
self._logger.warning("client did not support workspace/didChangeWatchedFiles.")
417417

418-
def remove() -> None:
419-
try:
420-
self.remove_file_watcher_entry(entry)
421-
except RuntimeError:
422-
pass
423-
424-
weakref.finalize(entry, remove)
425-
426418
self._file_watchers.add(entry)
427419

428420
return entry

packages/robot/src/robotcode/robot/diagnostics/imports_manager.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -113,30 +113,15 @@ def __init__(self, parent: "ImportsManager") -> None:
113113
self.references: weakref.WeakSet[Any] = weakref.WeakSet()
114114
self.file_watchers: List[FileWatcherEntry] = []
115115
self._lock = RLock(default_timeout=120, name="ImportEntryLock")
116-
self._release_watchers_finalizer = weakref.finalize(
117-
self,
118-
_ImportEntry._release_watchers,
119-
self.file_watchers,
120-
parent.file_watcher_manager,
121-
)
122-
123-
@staticmethod
124-
def _release_watchers(
125-
watchers: List[FileWatcherEntry],
126-
manager: FileWatcherManagerBase,
127-
) -> None:
128-
for watcher in watchers:
129-
try:
130-
manager.remove_file_watcher_entry(watcher)
131-
except RuntimeError:
132-
pass
133-
watchers.clear()
134116

135117
def _remove_file_watcher(self) -> None:
136118
if self.file_watchers:
137119
for watcher in self.file_watchers:
138-
self.parent.file_watcher_manager.remove_file_watcher_entry(watcher)
139-
self.file_watchers.clear()
120+
try:
121+
self.parent.file_watcher_manager.remove_file_watcher_entry(watcher)
122+
except RuntimeError:
123+
pass
124+
self.file_watchers.clear()
140125

141126
@abstractmethod
142127
def check_file_changed(self, changes: List[FileEvent]) -> Optional[FileChangeType]: ...
@@ -1429,7 +1414,8 @@ def get_libdoc_for_library_import(
14291414
entry = self._libaries[entry_key]
14301415

14311416
if not entry.ignore_reference and sentinel is not None and sentinel not in entry.references:
1432-
weakref.finalize(sentinel, self.__remove_library_entry, entry_key, entry)
1417+
fin = weakref.finalize(sentinel, self.__remove_library_entry, entry_key, entry)
1418+
fin.atexit = False # type: ignore[misc]
14331419
entry.references.add(sentinel)
14341420

14351421
return entry.get_libdoc()
@@ -1660,7 +1646,8 @@ def get_libdoc_for_variables_import(
16601646

16611647
if sentinel is not None and sentinel not in entry.references:
16621648
entry.references.add(sentinel)
1663-
weakref.finalize(sentinel, self.__remove_variables_entry, entry_key, entry)
1649+
fin = weakref.finalize(sentinel, self.__remove_variables_entry, entry_key, entry)
1650+
fin.atexit = False # type: ignore[misc]
16641651

16651652
return entry.get_libdoc()
16661653

@@ -1687,7 +1674,8 @@ def _get_entry_for_resource_import(
16871674

16881675
if sentinel is not None and sentinel not in entry.references:
16891676
entry.references.add(sentinel)
1690-
weakref.finalize(sentinel, self.__remove_resource_entry, entry_key, entry)
1677+
fin = weakref.finalize(sentinel, self.__remove_resource_entry, entry_key, entry)
1678+
fin.atexit = False # type: ignore[misc]
16911679

16921680
return entry
16931681

0 commit comments

Comments
 (0)