Skip to content

Commit 97011be

Browse files
committed
Replace zstd with stdlib and backports zstd
1 parent 0c89766 commit 97011be

File tree

5 files changed

+15
-13
lines changed

5 files changed

+15
-13
lines changed

dissect/hypervisor/disk/qcow2.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# - https://github.com/qemu/qemu/blob/master/docs/interop/qcow2.txt
44
from __future__ import annotations
55

6+
import sys
67
import zlib
78
from functools import cached_property, lru_cache
89
from io import BytesIO
@@ -28,8 +29,10 @@
2829
from collections.abc import Iterator
2930

3031
try:
31-
import zstandard as zstd
32-
32+
if sys.version_info >= (3, 14):
33+
from compression import zstd
34+
else:
35+
from backports import zstd
3336
HAS_ZSTD = True
3437
except ImportError:
3538
HAS_ZSTD = False
@@ -384,16 +387,8 @@ def _decompress(self, buf: bytes) -> bytes:
384387
return dctx.decompress(buf, self.qcow2.cluster_size)
385388

386389
if self.qcow2.compression_type == c_qcow2.QCOW2_COMPRESSION_TYPE_ZSTD:
387-
result = []
388-
389390
dctx = zstd.ZstdDecompressor()
390-
reader = dctx.stream_reader(BytesIO(buf))
391-
while reader.tell() < self.qcow2.cluster_size:
392-
chunk = reader.read(self.qcow2.cluster_size - reader.tell())
393-
if not chunk:
394-
break
395-
result.append(chunk)
396-
return b"".join(result)
391+
return dctx.decompress(buf, self.qcow2.cluster_size)
397392

398393
raise Error(f"Invalid compression type: {self.qcow2.compression_type}")
399394

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ repository = "https://github.com/fox-it/dissect.hypervisor"
3939
[project.optional-dependencies]
4040
full = [
4141
"pycryptodome",
42+
"backports.zstd; python_version < '3.14'",
4243
]
4344
dev = [
4445
"dissect.hypervisor[full]",
11.1 KB
Binary file not shown.

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ def basic_qcow2() -> Iterator[BinaryIO]:
8989
yield from open_file_gz("_data/disk/qcow2/basic.qcow2.gz")
9090

9191

92+
@pytest.fixture
93+
def basic_zstd_qcow2() -> Iterator[BinaryIO]:
94+
yield from open_file_gz("_data/disk/qcow2/basic-zstd.qcow2.gz")
95+
96+
9297
@pytest.fixture
9398
def data_file_qcow2() -> Path:
9499
return absolute_path("_data/disk/qcow2/data-file.qcow2.gz")

tests/disk/test_qcow2.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ def mock_open_gz(self: Path, *args, **kwargs) -> BinaryIO:
1616
return gzip.open(self if self.suffix.lower() == ".gz" else self.with_suffix(self.suffix + ".gz"))
1717

1818

19-
def test_basic(basic_qcow2: BinaryIO) -> None:
20-
qcow2 = QCow2(basic_qcow2)
19+
@pytest.mark.parametrize("name", ["basic_qcow2", "basic_zstd_qcow2"])
20+
def test_basic(name: str, request: pytest.FixtureRequest) -> None:
21+
qcow2 = QCow2(request.getfixturevalue(name))
2122

2223
assert qcow2.backing_file is None
2324
assert qcow2.data_file is qcow2.fh

0 commit comments

Comments
 (0)