Move the VM-independent bzip2 stream owner into a `bz2`-gated
`rustpython-common` module beside the zlib and lzma engines, and keep
`rustpython-stdlib` as the Python object and exception adapter. The adapter no
longer names the `bzip2` crate; the `bz2` feature carries it.
`_bz2` was the last user of the generic `DecompressState` / `DecompressStatus` /
`Decompressor` machinery in `stdlib/src/compression.rs`, so that goes with it;
`DecompressArgs` stays for zlib and lzma. The decompressor feeds the stream
through the existing `Chunker`, so buffered and freshly supplied input are no
longer joined into a new allocation first.
`test_decompress_after_data_error` passes on the ported engine, so its
`expectedFailure` marker goes.
Assisted-by: Grok
* bz2: return streaming output from BZ2Compressor.compress()
Return output produced during compression instead of waiting for flush().
Constraint: Preserve encoder state without flushing the BZ2 stream
Confidence: high
Scope-risk: narrow
Directive: Do not flush merely to retrieve partial output
Tested: test_bz2; stdlib_bz2.py; prek run --all-files
Assisted-by: Codex:gpt-5.6-sol
* bz2: remove redundant streaming-output snippet
CPython splits PathLike resolution across two layers: _io.FileIO
preserves the raw argument on .name (low-level contract), while
the high-level open() wrapper resolves it via os.fspath before
delegating. RustPython's io_open skipped that step, so
builtins.open(PathLike).name returned the PathLike object instead
of the resolved str/bytes.
Match Lib/_pyio.py:193-194 by resolving non-int inputs at the
io_open boundary, leaving _io.FileIO unchanged.