Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address review feedback from serhiy-storchaka
- Use nonlocal close_source instead of _closed flag
- Bind warnings.warn as default parameter in __del__
- Use assertWarns(ResourceWarning) instead of adding close() calls
- Use support.gc_collect() for consistent test behavior
- Remove broad exception handling

Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
  • Loading branch information
osamakader committed Oct 26, 2025
commit e6c11de1ba59c128c2711374cd53f8eba3891c12
30 changes: 16 additions & 14 deletions Lib/test/test_xml_etree.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,14 +696,15 @@ def test_iterparse(self):
next(it)
self.assertEqual(str(cm.exception),
'junk after document element: line 1, column 12')
it.close() # Close to avoid ResourceWarning
del cm, it
with self.assertWarns(ResourceWarning):
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
del cm, it
support.gc_collect()

# Deleting iterator without close() should emit ResourceWarning (bpo-43292)
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
it = iterparse(SIMPLE_XMLFILE)
del it
import gc
gc.collect() # Ensure previous iterator is cleaned up
with self.assertWarns(ResourceWarning):
it = iterparse(SIMPLE_XMLFILE)
del it
support.gc_collect()

# Explicitly calling close() should not emit warning
with warnings_helper.check_no_resource_warning(self):
Expand All @@ -712,11 +713,12 @@ def test_iterparse(self):
del it

# Not closing before del should emit ResourceWarning
it = iterparse(SIMPLE_XMLFILE)
action, elem = next(it)
self.assertEqual((action, elem.tag), ('end', 'element'))
del it, elem
gc.collect() # Ensure previous iterator is cleaned up
with self.assertWarns(ResourceWarning):
it = iterparse(SIMPLE_XMLFILE)
action, elem = next(it)
self.assertEqual((action, elem.tag), ('end', 'element'))
del it, elem
support.gc_collect()

with warnings_helper.check_no_resource_warning(self):
it = iterparse(SIMPLE_XMLFILE)
Expand All @@ -743,7 +745,7 @@ def create_unclosed():
# Don't close - should warn

create_unclosed()
gc.collect()
support.gc_collect()

resource_warnings = [x for x in w
if issubclass(x.category, ResourceWarning)]
Expand All @@ -760,7 +762,7 @@ def create_closed():
context.close()

create_closed()
gc.collect()
support.gc_collect()

resource_warnings = [x for x in w
if issubclass(x.category, ResourceWarning)]
Expand All @@ -778,7 +780,7 @@ def create_with_fileobj():
# Don't close - file object managed externally

create_with_fileobj()
gc.collect()
support.gc_collect()

resource_warnings = [x for x in w
if issubclass(x.category, ResourceWarning)]
Expand Down
28 changes: 7 additions & 21 deletions Lib/xml/etree/ElementTree.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,35 +1261,21 @@ def iterator(source):
gen = iterator(source)
class IterParseIterator(collections.abc.Iterator):
__next__ = gen.__next__

def close(self):
nonlocal close_source
if close_source:
source.close()
gen.close()
self._closed = True
close_source = False

def __del__(self):
if close_source and not getattr(self, '_closed', False):
try:
warnings.warn(
f"unclosed file {source!r}",
ResourceWarning,
stacklevel=2,
source=self
)
except:
# Ignore errors during warning emission in __del__
# This can happen during interpreter shutdown
pass
def __del__(self, _warn=warnings.warn):
if close_source:
try:
source.close()
except:
# Ignore errors when closing during __del__
pass
_warn(f"unclosed file {source!r}",
ResourceWarning, source=self)
source.close()

it = IterParseIterator()
it._closed = False
it.root = None
wr = weakref.ref(it)
return it
Expand Down
Loading