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(...).