Page MenuHomePhabricator

open_archive() does not behave consistently as a context manager for 7z files
Closed, ResolvedPublicBUG REPORT

Description

open_archive() does not behave consistently as a context manager for 7z files

Problem

open_archive() returns file-like objects for all supported archive formats. For regular files, gzip, bzip2, and lzma/xz archives, the returned objects implement the context manager protocol, so the following works as expected:

with open_archive(filename) as f:
    ...

The file object is automatically closed when leaving the with block.

For 7z archives, however, open_archive() returns process.stdout from a subprocess.Popen() instance:

process = subprocess.Popen(
    ['7za', 'e', '-bd', '-so', filename],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)
binary = process.stdout

When the caller exits the with block, only stdout is closed. The associated Popen object is no longer accessible, so the child process itself cannot be explicitly waited for.

This makes the resource management for 7z archives different from the other archive formats.

Proposed solution

Introduce a dedicated context manager for the 7z case and convert open_archive() itself into a context manager:

with open_archive(filename) as f:
    ...

would continue to work unchanged for callers, but all underlying resources, including the 7za subprocess, would be guaranteed to be cleaned up properly.

Alternatively, a lightweight wrapper object for the 7z case could be introduced which implements close(), __enter__(), and __exit__() and calls process.wait() when leaving the context.

Benefits

  • Consistent behaviour across all archive types.
  • Proper cleanup of the 7za subprocess.
  • Safer resource management.
  • No API change for existing callers already using with open_archive(...).
This task and its solution is proposed by AI/LLM

Details

Related Changes in Gerrit:

Event Timeline

Xqt triaged this task as Low priority.Jun 6 2026, 11:03 AM
Xqt updated the task description. (Show Details)

This may also solve the RessourceWarning in tests.tools_tests.OpenArchiveTestCase.test_open_archive_7z:

2026-06-02T12:53:03.0089614Z test_open_archive_7z (tests.tools_tests.OpenArchiveTestCase.test_open_archive_7z)
2026-06-02T12:53:03.0533032Z Test open_archive with 7za if installed. ... /opt/hostedtoolcache/Python/3.14.5/x64/lib/python3.14/subprocess.py:1139: ResourceWarning: subprocess 3807 is still running
2026-06-02T12:53:03.0534225Z   _warn("subprocess %s is still running" % self.pid,
2026-06-02T12:53:03.0534803Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-06-02T12:53:03.1034805Z /opt/hostedtoolcache/Python/3.14.5/x64/lib/python3.14/subprocess.py:1139: ResourceWarning: subprocess 3808 is still running
2026-06-02T12:53:03.1035613Z   _warn("subprocess %s is still running" % self.pid,
2026-06-02T12:53:03.1036233Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-06-02T12:53:03.1068874Z /opt/hostedtoolcache/Python/3.14.5/x64/lib/python3.14/subprocess.py:1139: ResourceWarning: subprocess 3809 is still running
2026-06-02T12:53:03.1069661Z   _warn("subprocess %s is still running" % self.pid,
2026-06-02T12:53:03.1070248Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
Xqt changed the task status from Open to In Progress.Jun 8 2026, 10:18 AM

Change #1300091 had a related patch set uploaded (by Xqt; author: Xqt):

[pywikibot/core@master] Introduce SevenZipFile class for open_archive()

https://gerrit.wikimedia.org/r/1300091

Xqt changed the subtype of this task from "Task" to "Bug Report".

Change #1300091 merged by Xqt:

[pywikibot/core@master] Introduce SevenZipFile class for open_archive()

https://gerrit.wikimedia.org/r/1300091