Skip to content

xml.etree.ElementTree.iterparse() should emit ResourceWarning when not explicitly closed #140601

@osamakader

Description

@osamakader

Feature or enhancement

Proposal:

Description

The iterparse() function in xml.etree.ElementTree has a TODO comment (line 1270) requesting that a ResourceWarning be emitted when the iterator is garbage collected without being explicitly closed:

def __del__(self):
    # TODO: Emit a ResourceWarning if it was not explicitly closed.
    # (When the close() method will be supported in all maintained Python versions.)
    if close_source:
        source.close()

The close() method has been available for many years now, so this TODO can be implemented.

Problem

When iterparse() opens a file by filename (rather than accepting a pre-opened file object), it manages the file internally. If the iterator is not explicitly closed, the file handle remains open until garbage collection, which can lead to:

  • File descriptor leaks
  • Files remaining locked on Windows
  • Resource exhaustion in long-running programs

Currently, no warning is issued to alert developers of this problem.

Proposed Solution

Implement the TODO by:

  1. Adding a _closed flag to track whether close() has been called
  2. Emitting a ResourceWarning in __del__() if the iterator was not closed and had opened a file internally (close_source == True)
  3. The warning should only apply when iterparse() opened the file itself (filename passed), not when a file object was provided

Example

Current behavior (no warning):

import xml.etree.ElementTree as ET

# This leaks a file handle but gives no warning
context = ET.iterparse('data.xml')
next(context)
# Iterator goes out of scope without close()

Expected behavior (with fix):

import xml.etree.ElementTree as ET

# This should emit ResourceWarning
context = ET.iterparse('data.xml')
next(context)
# ResourceWarning: unclosed file <_io.BufferedReader name='data.xml'>

# Proper usage (no warning):
context = ET.iterparse('data.xml')
next(context)
context.close()  # Explicit close

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-XMLtype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions