diff --git a/dissect/hypervisor/disk/c_asif.pyi b/dissect/hypervisor/disk/c_asif.pyi index be0e547..948cf1c 100644 --- a/dissect/hypervisor/disk/c_asif.pyi +++ b/dissect/hypervisor/disk/c_asif.pyi @@ -1,8 +1,7 @@ # Generated by cstruct-stubgen -from typing import BinaryIO, Literal, overload +from typing import BinaryIO, Literal, TypeAlias, overload import dissect.cstruct as __cs__ -from typing_extensions import TypeAlias class _c_asif(__cs__.cstruct): ASIF_HEADER_SIGNATURE: Literal[1936221303] = ... diff --git a/dissect/hypervisor/disk/c_qcow2.pyi b/dissect/hypervisor/disk/c_qcow2.pyi index 51db133..4fee1ef 100644 --- a/dissect/hypervisor/disk/c_qcow2.pyi +++ b/dissect/hypervisor/disk/c_qcow2.pyi @@ -1,8 +1,7 @@ # Generated by cstruct-stubgen -from typing import BinaryIO, Literal, overload +from typing import BinaryIO, Literal, TypeAlias, overload import dissect.cstruct as __cs__ -from typing_extensions import TypeAlias class _c_qcow2(__cs__.cstruct): MIN_CLUSTER_BITS: Literal[9] = ... diff --git a/dissect/hypervisor/disk/vhdx.py b/dissect/hypervisor/disk/vhdx.py index 592bb47..657afad 100644 --- a/dissect/hypervisor/disk/vhdx.py +++ b/dissect/hypervisor/disk/vhdx.py @@ -7,7 +7,7 @@ import os from functools import lru_cache from pathlib import Path -from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Final +from typing import TYPE_CHECKING, Any, BinaryIO, Final from uuid import UUID from dissect.util.stream import AlignedStream @@ -29,7 +29,7 @@ from dissect.hypervisor.exceptions import InvalidSignature, InvalidVirtualDisk if TYPE_CHECKING: - from collections.abc import Iterator + from collections.abc import Callable, Iterator log = logging.getLogger(__name__) log.setLevel(os.getenv("DISSECT_LOG_VHDX", "CRITICAL")) diff --git a/dissect/hypervisor/util/vmtar.py b/dissect/hypervisor/util/vmtar.py index e52f8cc..329bdc9 100644 --- a/dissect/hypervisor/util/vmtar.py +++ b/dissect/hypervisor/util/vmtar.py @@ -62,12 +62,12 @@ def visoropen(cls, name: str, mode: str = "r", fileobj: BinaryIO | None = None, raise tarfile.TarError("visor currently only supports read mode") try: - from gzip import GzipFile + from gzip import GzipFile # noqa: PLC0415 except ImportError: raise tarfile.CompressionError("gzip module is not available") from None try: - from lzma import LZMAError, LZMAFile + from lzma import LZMAError, LZMAFile # noqa: PLC0415 except ImportError: raise tarfile.CompressionError("lzma module is not available") from None diff --git a/pyproject.toml b/pyproject.toml index bc127a6..8404869 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,14 @@ [build-system] -requires = ["setuptools>=65.5.0", "setuptools_scm[toml]>=6.4.0"] +requires = ["setuptools>=77.0.0", "setuptools_scm[toml]>=6.4.0"] build-backend = "setuptools.build_meta" [project] name = "dissect.hypervisor" description = "A Dissect module implementing parsers for various hypervisor disk, backup and configuration files" readme = "README.md" -requires-python = "~=3.9" -license.text = "Affero General Public License v3" +requires-python = ">=3.10" +license = "AGPL-3.0-or-later" +license-files = ["LICENSE", "COPYRIGHT"] authors = [ {name = "Dissect Team", email = "dissect@fox-it.com"} ] @@ -16,7 +17,6 @@ classifiers = [ "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Information Technology", - "License :: OSI Approved", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Internet :: Log Analysis", @@ -46,13 +46,33 @@ dev = [ "dissect.util>=3.0.dev,<4.0.dev", ] +[dependency-groups] +test = [ + "pytest", +] +lint = [ + "ruff==0.13.1", + "vermin", +] +build = [ + "build", +] +debug = [ + "ipdb", +] +dev = [ + {include-group = "test"}, + {include-group = "lint"}, + {include-group = "debug"}, +] + [project.scripts] envelope-decrypt = "dissect.hypervisor.tools.envelope:main" vmtar = "dissect.hypervisor.tools.vmtar:main" [tool.ruff] line-length = 120 -required-version = ">=0.11.0" +required-version = ">=0.13.1" [tool.ruff.format] docstring-code-format = true @@ -102,9 +122,6 @@ ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM1 known-first-party = ["dissect.hypervisor"] known-third-party = ["dissect"] -[tool.setuptools] -license-files = ["LICENSE", "COPYRIGHT"] - [tool.setuptools.packages.find] include = ["dissect.*"] diff --git a/tests/disk/test_hdd.py b/tests/disk/test_hdd.py index cdfc5ad..1c08b74 100644 --- a/tests/disk/test_hdd.py +++ b/tests/disk/test_hdd.py @@ -61,7 +61,7 @@ def test_split_hdd(split_hdd: Path) -> None: start = 0 - for storage, split_size in zip(storages, split_sizes): + for storage, split_size in zip(storages, split_sizes, strict=False): assert storage.start == start assert storage.end == start + split_size assert len(storage.images) == 1 diff --git a/tests/disk/test_qcow2.py b/tests/disk/test_qcow2.py index 9821600..e7d6e42 100644 --- a/tests/disk/test_qcow2.py +++ b/tests/disk/test_qcow2.py @@ -31,7 +31,7 @@ def test_basic(basic_qcow2: BinaryIO) -> None: def test_data_file(data_file_qcow2: Path) -> None: # Test with file handle with gzip.open(data_file_qcow2, "rb") as fh: - with pytest.raises(Error, match="data-file required but not provided \\(image_data_file = 'data-file.bin'\\)"): + with pytest.raises(Error, match=r"data-file required but not provided \(image_data_file = 'data-file.bin'\)"): QCow2(fh) with gzip.open(data_file_qcow2.with_name("data-file.bin.gz"), "rb") as fh_bin: @@ -47,7 +47,7 @@ def test_data_file(data_file_qcow2: Path) -> None: # Test with allow_no_data_file qcow2 = QCow2(fh, allow_no_data_file=True) assert qcow2.data_file is None - with pytest.raises(Error, match="data-file required but not provided \\(image_data_file = 'data-file.bin'\\)"): + with pytest.raises(Error, match=r"data-file required but not provided \(image_data_file = 'data-file.bin'\)"): qcow2.open() # Test with Path @@ -68,12 +68,12 @@ def test_backing_file(backing_chain_qcow2: tuple[Path, Path, Path]) -> None: # Test with file handle with gzip.open(file1, "rb") as fh1, gzip.open(file2, "rb") as fh2, gzip.open(file3, "rb") as fh3: with pytest.raises( - Error, match="backing-file required but not provided \\(auto_backing_file = 'backing-chain-2.qcow2'\\)" + Error, match=r"backing-file required but not provided \(auto_backing_file = 'backing-chain-2.qcow2'\)" ): QCow2(fh1) with pytest.raises( - Error, match="backing-file required but not provided \\(auto_backing_file = 'backing-chain-3.qcow2'\\)" + Error, match=r"backing-file required but not provided \(auto_backing_file = 'backing-chain-3.qcow2'\)" ): QCow2(fh1, backing_file=fh2) @@ -87,7 +87,7 @@ def test_backing_file(backing_chain_qcow2: tuple[Path, Path, Path]) -> None: qcow2 = QCow2(fh1, allow_no_backing_file=True) assert qcow2.backing_file is None with pytest.raises( - Error, match="backing-file required but not provided \\(auto_backing_file = 'backing-chain-2.qcow2'\\)" + Error, match=r"backing-file required but not provided \(auto_backing_file = 'backing-chain-2.qcow2'\)" ): qcow2.open() diff --git a/tox.ini b/tox.ini index 83de25b..284a4ba 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ envlist = lint, py3, pypy3 # requires if they are not available on the host system. This requires the # locally installed tox to have a minimum version 3.3.0. This means the names # of the configuration options are still according to the tox 3.x syntax. -minversion = 4.4.3 +minversion = 4.27.0 # This version of virtualenv will install setuptools version 68.2.2 and pip # 23.3.1. These versions fully support python projects defined only through a # pyproject.toml file (PEP-517/PEP-518/PEP-621). This pip version also support @@ -14,9 +14,9 @@ requires = virtualenv>=20.24.6 [testenv] extras = dev deps = - pytest pytest-cov coverage +dependency_groups = test commands = pytest --basetemp="{envtmpdir}" {posargs:--color=yes --cov=dissect --cov-report=term-missing -v tests} coverage report @@ -24,28 +24,24 @@ commands = [testenv:build] package = skip -deps = - build +dependency_groups = build commands = pyproject-build [testenv:fix] package = skip -deps = - ruff==0.11.10 +dependency_groups = lint commands = - ruff format dissect tests ruff check --fix dissect tests + ruff format dissect tests [testenv:lint] package = skip -deps = - ruff==0.11.10 - vermin +dependency_groups = lint commands = - ruff format --check dissect tests ruff check dissect tests - vermin -t=3.9- --no-tips --lint dissect tests + ruff format --check dissect tests + vermin -t=3.10- --no-tips --lint dissect tests [testenv:docs-build] allowlist_externals = make