diff --git a/dissect/thumbcache/__init__.py b/dissect/thumbcache/__init__.py index 0ed5f51..5cc3f2f 100644 --- a/dissect/thumbcache/__init__.py +++ b/dissect/thumbcache/__init__.py @@ -6,8 +6,8 @@ __all__ = [ "Error", "IndexEntry", - "ThumbnailIndex", - "ThumbcacheFile", - "ThumbcacheEntry", "Thumbcache", + "ThumbcacheEntry", + "ThumbcacheFile", + "ThumbnailIndex", ] diff --git a/dissect/thumbcache/c_thumbcache.py b/dissect/thumbcache/c_thumbcache.py index 1948127..98bca20 100644 --- a/dissect/thumbcache/c_thumbcache.py +++ b/dissect/thumbcache/c_thumbcache.py @@ -1,6 +1,8 @@ +from __future__ import annotations + from dissect.cstruct import cstruct -thumbcache_index_def = """ +thumbcache_def = """ struct INDEX_HEADER_V1 { char Signature[4]; // 0x00 uint32 Version; // 0x04 @@ -75,4 +77,4 @@ uint32 Unknown; // 0x28 }; // 0x2C """ -c_thumbcache_index = cstruct().load(thumbcache_index_def) +c_thumbcache = cstruct().load(thumbcache_def) diff --git a/dissect/thumbcache/exceptions.py b/dissect/thumbcache/exceptions.py index 33501f6..41670e0 100644 --- a/dissect/thumbcache/exceptions.py +++ b/dissect/thumbcache/exceptions.py @@ -1,22 +1,14 @@ class Error(Exception): """A generic exception for the thumbcache module.""" - pass - class NotAnIndexFileError(Error): """Raises if a thumbnail index signature could not be found.""" - pass - class InvalidSignatureError(Error): """Raises if the signature does not match the expected value.""" - pass - class UnknownThumbnailTypeError(Error): """Raises if an unknown thumbnail type was found.""" - - pass diff --git a/dissect/thumbcache/index.py b/dissect/thumbcache/index.py index c6e3b7e..586ce2f 100644 --- a/dissect/thumbcache/index.py +++ b/dissect/thumbcache/index.py @@ -1,14 +1,17 @@ from __future__ import annotations -from datetime import datetime -from typing import BinaryIO, Iterator +from typing import TYPE_CHECKING, BinaryIO from dissect.util import ts -from dissect.thumbcache.c_thumbcache import c_thumbcache_index +from dissect.thumbcache.c_thumbcache import c_thumbcache from dissect.thumbcache.exceptions import NotAnIndexFileError from dissect.thumbcache.util import ThumbnailType +if TYPE_CHECKING: + from collections.abc import Iterator + from datetime import datetime + INDEX_ENTRIES = { ThumbnailType.WINDOWS_7: 5, ThumbnailType.WINDOWS_81: 11, @@ -29,12 +32,12 @@ def __init__(self, fh: BinaryIO) -> None: self._header = None @property - def header(self) -> c_thumbcache_index.INDEX_HEADER_V1 | c_thumbcache_index.INDEX_HEADER_V2: + def header(self) -> c_thumbcache.INDEX_HEADER_V1 | c_thumbcache.INDEX_HEADER_V2: if self._header is None: self._header = self._find_header(self.fh) return self._header - def _find_header(self, fh: BinaryIO) -> c_thumbcache_index.INDEX_HEADER_V1 | c_thumbcache_index.INDEX_HEADER_V2: + def _find_header(self, fh: BinaryIO) -> c_thumbcache.INDEX_HEADER_V1 | c_thumbcache.INDEX_HEADER_V2: """Searches for the header signature, and puts ``fh`` at the correct position. From Windows 8.1 onward, the two fields seem to use a 64-bit format field @@ -44,19 +47,19 @@ def _find_header(self, fh: BinaryIO) -> c_thumbcache_index.INDEX_HEADER_V1 | c_t fh: The file to read the header and indexes from. Returns: - A c_thumbcache_index.INDEX_HEADER structure. + A c_thumbcache.INDEX_HEADER structure. Raises: NotAThumbnailIndexFileError: If the ``IMMM`` signature could not be found. """ position = fh.tell() - buffer = fh.read(len(c_thumbcache_index.INDEX_HEADER_V1)) + buffer = fh.read(len(c_thumbcache.INDEX_HEADER_V1)) offset = buffer.find(self._signature) if offset == MAX_IMM_OFFSET: fh.seek(position) - header = c_thumbcache_index.INDEX_HEADER_V2(fh) + header = c_thumbcache.INDEX_HEADER_V2(fh) # From looking at the index files, it has a specific amount of information. # It is alligned in the follwing way: # INDEX_HEADER_V2 @@ -68,19 +71,18 @@ def _find_header(self, fh: BinaryIO) -> c_thumbcache_index.INDEX_HEADER_V1 | c_t # Read one index entry from the file till only zero bytes entry = IndexEntry(fh, header.Version) - entry.header - entry.cache_offsets + _ = entry.header + _ = entry.cache_offsets # Read offset to first entry zero_bytes = len(entry.header) + INDEX_ENTRIES.get(header.Version) * BYTES_IN_NUMBER - len(header) fh.read(zero_bytes) return header - elif offset == 0: - return c_thumbcache_index.INDEX_HEADER_V1(buffer) - else: - raise NotAnIndexFileError( - f"The index file signature {self._signature!r} could not be found at the expected location." - ) + if offset == 0: + return c_thumbcache.INDEX_HEADER_V1(buffer) + raise NotAnIndexFileError( + f"The index file signature {self._signature!r} could not be found at the expected location." + ) @property def version(self) -> int: @@ -102,8 +104,8 @@ def entries(self) -> Iterator[IndexEntry]: """Returns all index entries that are actually used.""" for _ in range(self.total_entries): entry = IndexEntry(self.fh, self.type) - entry.header - entry.cache_offsets + _ = entry.header + _ = entry.cache_offsets if entry.in_use(): yield entry @@ -119,21 +121,20 @@ def __init__(self, fh: BinaryIO, type: ThumbnailType) -> None: @property def header( self, - ) -> c_thumbcache_index.VISTA_ENTRY | c_thumbcache_index.WINDOWS7_ENTRY | c_thumbcache_index.WINDOWS8_ENTRY: + ) -> c_thumbcache.VISTA_ENTRY | c_thumbcache.WINDOWS7_ENTRY | c_thumbcache.WINDOWS8_ENTRY: if not self._header: self._header = self._select_header() return self._header def _select_header( self, - ) -> c_thumbcache_index.VISTA_ENTRY | c_thumbcache_index.WINDOWS7_ENTRY | c_thumbcache_index.WINDOWS8_ENTRY: + ) -> c_thumbcache.VISTA_ENTRY | c_thumbcache.WINDOWS7_ENTRY | c_thumbcache.WINDOWS8_ENTRY: """Selects header version according to the thumbnailtype.""" if self.type == ThumbnailType.WINDOWS_VISTA: - return c_thumbcache_index.VISTA_ENTRY(self.fh) - elif self.type == ThumbnailType.WINDOWS_7: - return c_thumbcache_index.WINDOWS7_ENTRY(self.fh) - else: - return c_thumbcache_index.WINDOWS8_ENTRY(self.fh) + return c_thumbcache.VISTA_ENTRY(self.fh) + if self.type == ThumbnailType.WINDOWS_7: + return c_thumbcache.WINDOWS7_ENTRY(self.fh) + return c_thumbcache.WINDOWS8_ENTRY(self.fh) def in_use(self) -> bool: return self.identifier != b"\x00" * IDENTIFIER_BYTES @@ -156,7 +157,7 @@ def cache_offsets(self) -> list[int]: """ if not self._data: size = INDEX_ENTRIES.get(self.type) - self._data = c_thumbcache_index.uint32[size](self.fh) + self._data = c_thumbcache.uint32[size](self.fh) if self.type > ThumbnailType.WINDOWS_7: # Alignment step self.fh.read((size % 2) * BYTES_IN_NUMBER) diff --git a/dissect/thumbcache/thumbcache.py b/dissect/thumbcache/thumbcache.py index e3a5e87..ec1353e 100644 --- a/dissect/thumbcache/thumbcache.py +++ b/dissect/thumbcache/thumbcache.py @@ -1,9 +1,14 @@ -from pathlib import Path -from typing import Iterator +from __future__ import annotations + +from typing import TYPE_CHECKING from dissect.thumbcache.index import IndexEntry, ThumbnailIndex from dissect.thumbcache.thumbcache_file import ThumbcacheEntry, ThumbcacheFile +if TYPE_CHECKING: + from collections.abc import Iterator + from pathlib import Path + class Thumbcache: """This class combines the thumbnailindex and thumbcachefile. @@ -50,8 +55,7 @@ def entries(self) -> Iterator[tuple[Path, ThumbcacheEntry]]: def index_entries(self) -> Iterator[IndexEntry]: """Iterates through all the index entries that are in use.""" with self.index_file.open("rb") as i_file: - for entry in ThumbnailIndex(i_file).entries(): - yield entry + yield from ThumbnailIndex(i_file).entries() def _entries_from_offsets(self, offsets: list[int]) -> Iterator[tuple[Path, ThumbcacheEntry]]: """Retrieves Thumbcache entries from a ThumbcacheFile using offsets.""" diff --git a/dissect/thumbcache/thumbcache_file.py b/dissect/thumbcache/thumbcache_file.py index c11c10b..c721823 100644 --- a/dissect/thumbcache/thumbcache_file.py +++ b/dissect/thumbcache/thumbcache_file.py @@ -1,27 +1,30 @@ from __future__ import annotations -from typing import Any, BinaryIO +from typing import TYPE_CHECKING, Any, BinaryIO -from dissect.thumbcache.c_thumbcache import c_thumbcache_index +from dissect.thumbcache.c_thumbcache import c_thumbcache from dissect.thumbcache.exceptions import ( InvalidSignatureError, UnknownThumbnailTypeError, ) from dissect.thumbcache.util import ThumbnailType, seek_and_return +if TYPE_CHECKING: + from collections.abc import Iterator + UNKNOWN_BYTES = 8 class ThumbcacheFile: __slots__ = [ - "fh", + "_cached_entries", + "_entries", "_header", + "fh", + "offset", "signature", - "type", "size", - "offset", - "_entries", - "_cached_entries", + "type", ] """ @@ -39,8 +42,8 @@ def __init__(self, fh: BinaryIO) -> None: self._header = self._get_header_type(self.fh) self._cached_entries: dict[int, ThumbcacheEntry] = {} - def _get_header_type(self, fh: BinaryIO) -> c_thumbcache_index.CACHE_HEADER_VISTA | c_thumbcache_index.CACHE_HEADER: - tmp_header = c_thumbcache_index.CACHE_HEADER(fh) + def _get_header_type(self, fh: BinaryIO) -> c_thumbcache.CACHE_HEADER_VISTA | c_thumbcache.CACHE_HEADER: + tmp_header = c_thumbcache.CACHE_HEADER(fh) if self._signature != tmp_header.Signature: raise InvalidSignatureError( @@ -48,12 +51,11 @@ def _get_header_type(self, fh: BinaryIO) -> c_thumbcache_index.CACHE_HEADER_VIST ) if tmp_header.Version <= ThumbnailType.WINDOWS_7: - return c_thumbcache_index.CACHE_HEADER_VISTA(tmp_header.dumps()) - else: - return tmp_header + return c_thumbcache.CACHE_HEADER_VISTA(tmp_header.dumps()) + return tmp_header @property - def header(self) -> c_thumbcache_index.CACHE_HEADER_VISTA | c_thumbcache_index.CACHE_HEADER: + def header(self) -> c_thumbcache.CACHE_HEADER_VISTA | c_thumbcache.CACHE_HEADER: return self._header @property @@ -72,15 +74,15 @@ def __getitem__(self, key: int) -> ThumbcacheEntry: self._cached_entries[key] = item return item - def __getattribute__(self, __name: str) -> Any: + def __getattribute__(self, name: str) -> Any: try: - return object.__getattribute__(self, __name) + return object.__getattribute__(self, name) except AttributeError: pass - return getattr(self.header, __name.capitalize()) + return getattr(self.header, name.capitalize()) - def entries(self) -> list[ThumbcacheEntry]: + def entries(self) -> Iterator[ThumbcacheEntry]: with seek_and_return(self.fh, self.fh.tell()): try: while True: @@ -123,10 +125,10 @@ def __init__(self, fh: BinaryIO, type: ThumbnailType) -> None: fh.read(UNKNOWN_BYTES) additional_bytes += UNKNOWN_BYTES - self.data_checksum: bytes = c_thumbcache_index.char[8](fh) - self.header_checksum: bytes = c_thumbcache_index.char[8](fh) + self.data_checksum: bytes = c_thumbcache.char[8](fh) + self.header_checksum: bytes = c_thumbcache.char[8](fh) - self.identifier: str = c_thumbcache_index.wchar[self._header.IdentifierSize // 2](fh) + self.identifier: str = c_thumbcache.wchar[self._header.IdentifierSize // 2](fh) header_size = len(self._header) + self._header.IdentifierSize + additional_bytes @@ -134,11 +136,10 @@ def __init__(self, fh: BinaryIO, type: ThumbnailType) -> None: def _get_header( self, thumbnail_type: ThumbnailType - ) -> type[c_thumbcache_index.CACHE_ENTRY_VISTA | c_thumbcache_index.CACHE_ENTRY]: + ) -> type[c_thumbcache.CACHE_ENTRY_VISTA | c_thumbcache.CACHE_ENTRY]: if thumbnail_type == ThumbnailType.WINDOWS_VISTA: - return c_thumbcache_index.CACHE_ENTRY_VISTA - else: - return c_thumbcache_index.CACHE_ENTRY + return c_thumbcache.CACHE_ENTRY_VISTA + return c_thumbcache.CACHE_ENTRY @property def hash(self) -> str: diff --git a/dissect/thumbcache/tools/extract_images.py b/dissect/thumbcache/tools/extract_images.py index bad980a..c94163a 100644 --- a/dissect/thumbcache/tools/extract_images.py +++ b/dissect/thumbcache/tools/extract_images.py @@ -1,13 +1,17 @@ #!/bin/python3 +from __future__ import annotations -from pathlib import Path +from typing import TYPE_CHECKING from dissect.thumbcache.exceptions import Error from dissect.thumbcache.thumbcache_file import ThumbcacheFile from dissect.thumbcache.tools.utils import create_argument_parser, write_entry +if TYPE_CHECKING: + from pathlib import Path -def dump_entry_data(path: Path, output_dir: Path): + +def dump_entry_data(path: Path, output_dir: Path) -> None: with path.open("rb") as file: try: cache_file = ThumbcacheFile(file) @@ -18,7 +22,7 @@ def dump_entry_data(path: Path, output_dir: Path): print(e) -def main(): +def main() -> None: parser = create_argument_parser("extract raw thumbcache entries") args = parser.parse_args() path: Path = args.cache_path diff --git a/dissect/thumbcache/tools/extract_with_index.py b/dissect/thumbcache/tools/extract_with_index.py index c1d5a1b..4f8c0be 100644 --- a/dissect/thumbcache/tools/extract_with_index.py +++ b/dissect/thumbcache/tools/extract_with_index.py @@ -1,11 +1,16 @@ -from pathlib import Path +from __future__ import annotations + +from typing import TYPE_CHECKING from dissect.thumbcache.exceptions import Error from dissect.thumbcache.thumbcache import Thumbcache from dissect.thumbcache.tools.utils import create_argument_parser, write_entry +if TYPE_CHECKING: + from pathlib import Path + -def dump_entry_data_through_index(path: Path, output_dir: Path, prefix: str): +def dump_entry_data_through_index(path: Path, output_dir: Path, prefix: str) -> None: cache = Thumbcache(path=path, prefix=prefix) try: for location_path, entry in cache.entries(): @@ -15,7 +20,7 @@ def dump_entry_data_through_index(path: Path, output_dir: Path, prefix: str): print(e) -def main(): +def main() -> None: parser = create_argument_parser("extract indexed entries") parser.add_argument( "--prefix", diff --git a/dissect/thumbcache/tools/utils.py b/dissect/thumbcache/tools/utils.py index 266a44e..5098391 100644 --- a/dissect/thumbcache/tools/utils.py +++ b/dissect/thumbcache/tools/utils.py @@ -1,18 +1,22 @@ +from __future__ import annotations + from argparse import ArgumentParser from pathlib import Path +from typing import TYPE_CHECKING -from dissect.thumbcache.thumbcache import ThumbcacheEntry +if TYPE_CHECKING: + from dissect.thumbcache.thumbcache import ThumbcacheEntry -def create_argument_parser(name: str) -> ArgumentParser(): +def create_argument_parser(name: str) -> ArgumentParser: parser = ArgumentParser(name) parser.add_argument("cache_path", type=Path) - parser.add_argument("--output-dir", "-o", type=Path, default=Path(".")) + parser.add_argument("--output-dir", "-o", type=Path, default=Path()) return parser -def write_entry(output_path: Path, entry: ThumbcacheEntry, file_prefix: str): +def write_entry(output_path: Path, entry: ThumbcacheEntry, file_prefix: str) -> None: output_file = (output_path / f"{entry.hash}/{entry.identifier}_{file_prefix}").with_suffix(".bmp") output_file.parent.mkdir(parents=True, exist_ok=True) with output_file.open("wb") as output: diff --git a/dissect/thumbcache/util.py b/dissect/thumbcache/util.py index 38f38b2..8fa1b49 100644 --- a/dissect/thumbcache/util.py +++ b/dissect/thumbcache/util.py @@ -1,6 +1,11 @@ +from __future__ import annotations + import enum from contextlib import contextmanager -from typing import BinaryIO +from typing import TYPE_CHECKING, BinaryIO + +if TYPE_CHECKING: + from collections.abc import Iterator class ThumbnailType(enum.IntEnum): @@ -11,7 +16,7 @@ class ThumbnailType(enum.IntEnum): @contextmanager -def seek_and_return(fh: BinaryIO, position: int) -> BinaryIO: +def seek_and_return(fh: BinaryIO, position: int) -> Iterator[BinaryIO]: current_position = fh.tell() try: fh.seek(position) diff --git a/pyproject.toml b/pyproject.toml index fd563c3..f3b92cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,13 +45,56 @@ dev = [ thumbcache-extract = "dissect.thumbcache.tools.extract_images:main" thumbcache-extract-indexed = "dissect.thumbcache.tools.extract_with_index:main" -[tool.black] +[tool.ruff] line-length = 120 +required-version = ">=0.9.0" -[tool.isort] -profile = "black" -known_first_party = ["dissect.thumbcache"] -known_third_party = ["dissect"] +[tool.ruff.format] +docstring-code-format = true + +[tool.ruff.lint] +select = [ + "F", + "E", + "W", + "I", + "UP", + "YTT", + "ANN", + "B", + "C4", + "DTZ", + "T10", + "FA", + "ISC", + "G", + "INP", + "PIE", + "PYI", + "PT", + "Q", + "RSE", + "RET", + "SLOT", + "SIM", + "TID", + "TCH", + "PTH", + "PLC", + "TRY", + "FLY", + "PERF", + "FURB", + "RUF", +] +ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003"] + +[tool.ruff.lint.per-file-ignores] +"tests/docs/**" = ["INP001"] + +[tool.ruff.lint.isort] +known-first-party = ["dissect.thumbcache"] +known-third-party = ["dissect"] [tool.setuptools] license-files = ["LICENSE", "COPYRIGHT"] diff --git a/tests/test_index.py b/tests/test_index.py index ee63143..e73a399 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import io from pathlib import Path from unittest.mock import Mock @@ -8,12 +10,12 @@ from dissect.thumbcache.index import IndexEntry, ThumbnailIndex, ThumbnailType -def test_index(): +def test_index() -> None: ThumbnailIndex(fh=Mock) @pytest.mark.parametrize( - "path, expected_type", + ("path", "expected_type"), [ (Path("data/windows_vista/thumbcache_idx.db"), ThumbnailType.WINDOWS_VISTA), (Path("data/windows_7/thumbcache_idx.db"), ThumbnailType.WINDOWS_7), @@ -25,7 +27,7 @@ def test_index(): def test_index_type( path: Path, expected_type: ThumbnailType, -): +) -> None: index_path = Path(__file__).parent / path with index_path.open("rb") as ifile: @@ -33,13 +35,12 @@ def test_index_type( assert index.type == expected_type -def test_index_unknown(): +def test_index_unknown() -> None: with pytest.raises(NotAnIndexFileError): - index = ThumbnailIndex(io.BytesIO(b"UNKNOWN_DATA")) - index.header + _ = ThumbnailIndex(io.BytesIO(b"UNKNOWN_DATA")).header -def test_index_entry(): +def test_index_entry() -> None: index_entry = IndexEntry(io.BytesIO(b"\x00" * 20), ThumbnailType.WINDOWS_VISTA) assert not index_entry.in_use() @@ -54,7 +55,7 @@ def test_index_entry(): "data/windows_vista/thumbcache_idx.db", ], ) -def test_get_index_entries(path: str): +def test_get_index_entries(path: str) -> None: idx_file = Path(__file__).parent / path with idx_file.open("rb") as index_file: index = ThumbnailIndex(index_file) diff --git a/tests/test_thumbcache.py b/tests/test_thumbcache.py index c47861c..ab3cd96 100644 --- a/tests/test_thumbcache.py +++ b/tests/test_thumbcache.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from pathlib import Path import pytest @@ -11,12 +13,12 @@ def thumbcache(path: str) -> Thumbcache: return Thumbcache(file) -def test_thumbcache(): +def test_thumbcache() -> None: assert Thumbcache(Path(__file__).parent / "data/windows_7") @pytest.mark.parametrize( - "path, expected_mapping", + ("path", "expected_mapping"), [ ("data/windows_vista", {0: "32", 1: "96", 2: "256", 3: "1024", 4: "sr"}), ( @@ -60,13 +62,13 @@ def test_thumbcache(): ), ], ) -def test_thumbcache_mapping(thumbcache: Thumbcache, expected_mapping: dict): +def test_thumbcache_mapping(thumbcache: Thumbcache, expected_mapping: dict) -> None: for key, value in expected_mapping.items(): assert value in thumbcache.mapping[key].name @pytest.mark.parametrize( - "path, nr_of_entries", + ("path", "nr_of_entries"), [ ( "data/windows_7", @@ -78,16 +80,16 @@ def test_thumbcache_mapping(thumbcache: Thumbcache, expected_mapping: dict): ), ], ) -def test_thumbcache_entries(thumbcache: Thumbcache, nr_of_entries: int): +def test_thumbcache_entries(thumbcache: Thumbcache, nr_of_entries: int) -> None: assert len(list(thumbcache.entries())) == nr_of_entries @pytest.mark.parametrize( - "path, offsets, expected_entries", + ("path", "offsets", "expected_entries"), [ ("data/windows_7", [0xFFFFFFFF, 0xFFFFFFFF, 152, 0xFFFFFFFF, 0xFFFFFFFF], 1), ("data/windows_7", [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], 0), ], ) -def test_entries_from_offset(thumbcache: Thumbcache, offsets, expected_entries): +def test_entries_from_offset(thumbcache: Thumbcache, offsets: list[int], expected_entries: int) -> None: assert len(list(thumbcache._entries_from_offsets(offsets))) == expected_entries diff --git a/tests/test_thumbcachefile.py b/tests/test_thumbcache_file.py similarity index 73% rename from tests/test_thumbcachefile.py rename to tests/test_thumbcache_file.py index c93321c..609efea 100644 --- a/tests/test_thumbcachefile.py +++ b/tests/test_thumbcache_file.py @@ -1,8 +1,11 @@ +from __future__ import annotations + from pathlib import Path +from typing import TYPE_CHECKING import pytest -from dissect.thumbcache.c_thumbcache import c_thumbcache_index +from dissect.thumbcache.c_thumbcache import c_thumbcache from dissect.thumbcache.exceptions import ( InvalidSignatureError, UnknownThumbnailTypeError, @@ -10,9 +13,12 @@ from dissect.thumbcache.thumbcache_file import ThumbcacheFile from dissect.thumbcache.util import ThumbnailType +if TYPE_CHECKING: + from collections.abc import Iterator + @pytest.fixture -def thumbcache_file(path: str) -> ThumbcacheFile: +def thumbcache_file(path: str) -> Iterator[ThumbcacheFile]: current_path = Path(__file__).parent / "data" / path with current_path.open("rb") as thumb_file: @@ -20,7 +26,7 @@ def thumbcache_file(path: str) -> ThumbcacheFile: @pytest.mark.parametrize( - "path, thumbnail_type", + ("path", "thumbnail_type"), [ ("windows_7/thumbcache_32.db", ThumbnailType.WINDOWS_7), ("windows_10/thumbcache_32.db", ThumbnailType.WINDOWS_10), @@ -28,25 +34,24 @@ def thumbcache_file(path: str) -> ThumbcacheFile: ("windows_81/thumbcache_32.db", ThumbnailType.WINDOWS_81), ], ) -def test_thumbcache_version(thumbcache_file: ThumbcacheFile, thumbnail_type: ThumbnailType): +def test_thumbcache_version(thumbcache_file: ThumbcacheFile, thumbnail_type: ThumbnailType) -> None: assert thumbcache_file.version == thumbnail_type assert thumbcache_file.signature == b"CMMM" -def test_thumbcache_file_failed(): +def test_thumbcache_file_failed() -> None: with pytest.raises(InvalidSignatureError): ThumbcacheFile(b"UNKNOWN" + b"\x00" * 20) -def test_unknown_thumbnail_type(): +def test_unknown_thumbnail_type() -> None: + header = c_thumbcache.CACHE_HEADER(Signature=b"CMMM", Version=0xDEADBEEF) with pytest.raises(UnknownThumbnailTypeError): - header = c_thumbcache_index.CACHE_HEADER(Signature=b"CMMM", Version=0xDEADBEEF) - cache_file = ThumbcacheFile(header.dumps()) - cache_file.version + _ = ThumbcacheFile(header.dumps()).version @pytest.mark.parametrize( - "path, entries, size", + ("path", "entries", "size"), [ ("windows_7/thumbcache_256.db", 0x3, 0x0118), ("windows_10/thumbcache_32.db", 0x6, 0), @@ -55,7 +60,7 @@ def test_unknown_thumbnail_type(): ("windows_vista/thumbcache_32.db", 0x12, 0xDDA8), ], ) -def test_thumbcache_entries(thumbcache_file: ThumbcacheFile, entries: int, size: int): +def test_thumbcache_entries(thumbcache_file: ThumbcacheFile, entries: int, size: int) -> None: assert len(list(thumbcache_file.entries())) == entries assert thumbcache_file.size == size @@ -64,7 +69,7 @@ def test_thumbcache_entries(thumbcache_file: ThumbcacheFile, entries: int, size: "path", [("windows_7/thumbcache_256.db")], ) -def test_thumbcache_get_entry(thumbcache_file: ThumbcacheFile): +def test_thumbcache_get_entry(thumbcache_file: ThumbcacheFile) -> None: assert thumbcache_file[0x18].hash == "e84eb8f951bc2409" @@ -72,6 +77,6 @@ def test_thumbcache_get_entry(thumbcache_file: ThumbcacheFile): "path", [("windows_7/thumbcache_256.db")], ) -def test_thumbcache_get_entry_failed(thumbcache_file: ThumbcacheFile): +def test_thumbcache_get_entry_failed(thumbcache_file: ThumbcacheFile) -> None: with pytest.raises(InvalidSignatureError): thumbcache_file[0x42] diff --git a/tox.ini b/tox.ini index bfcf133..17e3629 100644 --- a/tox.ini +++ b/tox.ini @@ -32,32 +32,19 @@ commands = [testenv:fix] package = skip deps = - black==23.1.0 - isort==5.11.4 + ruff==0.9.2 commands = - black dissect tests - isort dissect tests + ruff format dissect tests [testenv:lint] package = skip deps = - black==23.1.0 - flake8 - flake8-black - flake8-isort - isort==5.11.4 + ruff==0.9.2 vermin commands = - flake8 dissect tests + ruff check dissect tests vermin -t=3.9- --no-tips --lint dissect tests -[flake8] -max-line-length = 120 -extend-ignore = - # See https://github.com/PyCQA/pycodestyle/issues/373 - E203, -statistics = True - [testenv:docs-build] allowlist_externals = make deps =