From 28feec3a3f602b35e1e662092e255d9c2ecc6bcb Mon Sep 17 00:00:00 2001 From: Vishnu Kannaujia Date: Sun, 14 Jun 2026 21:49:32 -0700 Subject: [PATCH 1/2] Force GC in WSIReader tests to suppress ResourceWarning for unclosed files The WSI reader tests emit ResourceWarning ("unclosed file <_io.FileIO ...>" / BufferedReader) for the temp TIFFs they exercise (e.g. the CMU-1 generic TIFF). All direct `reader.read(...)` call sites in this test module already either use `with` or call `obj.close()` explicitly, so they are not the leak source. The remaining leak comes from `LoadImage.__call__`, which calls `reader.read(filename)` and `reader.get_data(img)`, then returns `img_array` while letting the reader-returned `img` (the backend handle) fall out of scope without `close()`. The two `test_with_dataloader*` tests in this module reach `LoadImage` via `LoadImaged(reader=WSIReader, ...)` and inherit that leak, so the temp TIFF handles are only closed when the garbage collector eventually runs - frequently after the warning has already been emitted. Add `gc.collect()` to `tearDown` of the shared `WSIReaderTests.Tests` base class. Each of `TiffFile.__del__` / `OpenSlide.__del__` / `CuImage.__del__` closes the underlying file descriptor, so running gc explicitly at the end of every test invokes those finalizers deterministically and eliminates the warning. This is a focused test-hygiene change with no impact on production code paths. Fixes #5461. Signed-off-by: Vishnu Kannaujia --- tests/utils/enums/test_wsireader.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/utils/enums/test_wsireader.py b/tests/utils/enums/test_wsireader.py index 2c6498234e..22723f36c3 100644 --- a/tests/utils/enums/test_wsireader.py +++ b/tests/utils/enums/test_wsireader.py @@ -11,6 +11,7 @@ from __future__ import annotations +import gc import os import unittest from pathlib import Path @@ -474,6 +475,16 @@ class WSIReaderTests: class Tests(unittest.TestCase): backend = None + def tearDown(self): + # Force deterministic cleanup of any backend WSI handles that may have + # leaked through `LoadImage` (which calls `reader.read` and discards the + # returned object after `get_data`). Without this, the temp TIFFs used + # by these tests can survive past test teardown long enough for the + # interpreter to emit ResourceWarning ("unclosed file ..."). Running gc + # here invokes `TiffFile.__del__` / `OpenSlide.__del__` / `CuImage.__del__`, + # all of which close the underlying handle. + gc.collect() + @parameterized.expand([TEST_CASE_WHOLE_0]) def test_read_whole_image(self, file_path, level, expected_shape): reader = WSIReader(self.backend, level=level) From 63e0e5a8bbea15f1846682edc9722dbf6096aa57 Mon Sep 17 00:00:00 2001 From: Vishnu Kannaujia Date: Sun, 14 Jun 2026 22:07:59 -0700 Subject: [PATCH 2/2] Convert tearDown comment into a docstring Convert the inline comment on the new ``tearDown`` into a Google-style docstring so the method satisfies the repository's docstring guideline, without changing behavior. Signed-off-by: Vishnu Kannaujia --- tests/utils/enums/test_wsireader.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/utils/enums/test_wsireader.py b/tests/utils/enums/test_wsireader.py index 22723f36c3..ee6462b579 100644 --- a/tests/utils/enums/test_wsireader.py +++ b/tests/utils/enums/test_wsireader.py @@ -476,13 +476,18 @@ class Tests(unittest.TestCase): backend = None def tearDown(self): - # Force deterministic cleanup of any backend WSI handles that may have - # leaked through `LoadImage` (which calls `reader.read` and discards the - # returned object after `get_data`). Without this, the temp TIFFs used - # by these tests can survive past test teardown long enough for the - # interpreter to emit ResourceWarning ("unclosed file ..."). Running gc - # here invokes `TiffFile.__del__` / `OpenSlide.__del__` / `CuImage.__del__`, - # all of which close the underlying handle. + """Force deterministic cleanup of any backend WSI handles. + + ``LoadImage`` calls ``reader.read`` and then discards the returned + object after ``get_data`` (see ``monai/transforms/io/array.py``); + for WSI readers that object is a ``TiffFile`` / ``OpenSlide`` / + ``CuImage`` instance that owns an open file descriptor. Without + forcing a collection here, the temp TIFFs used by these tests + stay open long enough for the interpreter to emit + ``ResourceWarning: unclosed file ...``. Running ``gc.collect`` + invokes the corresponding ``__del__`` finalizers, which all close + the underlying handle. + """ gc.collect() @parameterized.expand([TEST_CASE_WHOLE_0])