From 2b6a9809ad9f836f56b4087f6aaa0634bd6e2f73 Mon Sep 17 00:00:00 2001 From: wbi Date: Wed, 18 Mar 2026 15:30:38 +0100 Subject: [PATCH 1/2] Ruff linting --- dissect/cstruct/__init__.py | 2 ++ dissect/cstruct/compiler.py | 4 +++- dissect/cstruct/cstruct.py | 7 +++++-- dissect/cstruct/exceptions.py | 3 +++ dissect/cstruct/expression.py | 1 - dissect/cstruct/parser.py | 13 ++++++------- dissect/cstruct/types/__init__.py | 2 ++ dissect/cstruct/types/enum.py | 3 ++- dissect/cstruct/types/structure.py | 6 +++--- pyproject.toml | 25 ++++++++++++++++++++++--- tests/_docs/conf.py | 2 ++ tests/test_types_union.py | 6 +++--- 12 files changed, 53 insertions(+), 21 deletions(-) diff --git a/dissect/cstruct/__init__.py b/dissect/cstruct/__init__.py index 4acb0790..4d5934bd 100644 --- a/dissect/cstruct/__init__.py +++ b/dissect/cstruct/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dissect.cstruct.bitbuffer import BitBuffer from dissect.cstruct.cstruct import cstruct, ctypes, ctypes_type from dissect.cstruct.exceptions import ( diff --git a/dissect/cstruct/compiler.py b/dissect/cstruct/compiler.py index d9445b4f..328b9646 100644 --- a/dissect/cstruct/compiler.py +++ b/dissect/cstruct/compiler.py @@ -11,7 +11,6 @@ from dissect.cstruct.bitbuffer import BitBuffer from dissect.cstruct.types import ( Array, - BaseType, Char, CharArray, Flag, @@ -34,6 +33,9 @@ from types import MethodType from dissect.cstruct.cstruct import cstruct + from dissect.cstruct.types import ( + BaseType, + ) from dissect.cstruct.types.structure import Field SUPPORTED_TYPES = ( diff --git a/dissect/cstruct/cstruct.py b/dissect/cstruct/cstruct.py index 2907734c..8b8fd4b6 100644 --- a/dissect/cstruct/cstruct.py +++ b/dissect/cstruct/cstruct.py @@ -12,12 +12,10 @@ from dissect.cstruct.parser import CStyleParser, TokenParser from dissect.cstruct.types import ( LEB128, - Array, BaseArray, BaseType, Char, Enum, - Field, Flag, Int, Packed, @@ -32,6 +30,11 @@ from collections.abc import Iterable from typing import TypeAlias + from dissect.cstruct.types import ( + Array, + Field, + ) + T = TypeVar("T", bound=BaseType) diff --git a/dissect/cstruct/exceptions.py b/dissect/cstruct/exceptions.py index e899d7a7..b742c020 100644 --- a/dissect/cstruct/exceptions.py +++ b/dissect/cstruct/exceptions.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + class Error(Exception): pass diff --git a/dissect/cstruct/expression.py b/dissect/cstruct/expression.py index 88b94578..92a96359 100644 --- a/dissect/cstruct/expression.py +++ b/dissect/cstruct/expression.py @@ -225,7 +225,6 @@ def is_number(self, token: str) -> bool: def evaluate(self, cs: cstruct, context: dict[str, int] | None = None) -> int: """Evaluates an expression using a Shunting-Yard implementation.""" - self.stack = [] self.queue = [] operators = set(self.binary_operators.keys()) | set(self.unary_operators.keys()) diff --git a/dissect/cstruct/parser.py b/dissect/cstruct/parser.py index 32e23f03..bfb72f62 100644 --- a/dissect/cstruct/parser.py +++ b/dissect/cstruct/parser.py @@ -11,10 +11,11 @@ ParserError, ) from dissect.cstruct.expression import Expression -from dissect.cstruct.types import BaseArray, BaseType, Field, Structure +from dissect.cstruct.types import BaseArray, Field, Structure if TYPE_CHECKING: from dissect.cstruct import cstruct + from dissect.cstruct.types import BaseType class Parser: @@ -37,10 +38,9 @@ def parse(self, data: str) -> None: class TokenParser(Parser): - """ - Args: - cs: An instance of cstruct. - compiled: Whether structs should be compiled or not. + """Args: + cs: An instance of cstruct. + compiled: Whether structs should be compiled or not. """ def __init__(self, cs: cstruct, compiled: bool = True, align: bool = False): @@ -421,8 +421,7 @@ def _replacer(match: re.Match) -> str: @staticmethod def _lineno(tok: Token) -> int: - """Quick and dirty line number calculator""" - + """Quick and dirty line number calculator.""" match = tok.match return match.string.count("\n", 0, match.start()) + 1 diff --git a/dissect/cstruct/types/__init__.py b/dissect/cstruct/types/__init__.py index 4d86d347..e61e2900 100644 --- a/dissect/cstruct/types/__init__.py +++ b/dissect/cstruct/types/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dissect.cstruct.types.base import Array, BaseArray, BaseType, MetaType from dissect.cstruct.types.char import Char, CharArray from dissect.cstruct.types.enum import Enum diff --git a/dissect/cstruct/types/enum.py b/dissect/cstruct/types/enum.py index d1f6bcb8..87b33d7a 100644 --- a/dissect/cstruct/types/enum.py +++ b/dissect/cstruct/types/enum.py @@ -5,12 +5,13 @@ from enum import EnumMeta, IntEnum, IntFlag from typing import TYPE_CHECKING, Any, BinaryIO, TypeVar, overload -from dissect.cstruct.types.base import Array, BaseType, MetaType +from dissect.cstruct.types.base import BaseType, MetaType if TYPE_CHECKING: from typing_extensions import Self from dissect.cstruct.cstruct import cstruct + from dissect.cstruct.types.base import Array PY_311 = sys.version_info >= (3, 11, 0) diff --git a/dissect/cstruct/types/structure.py b/dissect/cstruct/types/structure.py index f2e8e037..b86c4b50 100644 --- a/dissect/cstruct/types/structure.py +++ b/dissect/cstruct/types/structure.py @@ -2,7 +2,7 @@ import io from collections import ChainMap -from collections.abc import Callable, MutableMapping +from collections.abc import MutableMapping from contextlib import contextmanager from enum import Enum from functools import lru_cache @@ -23,7 +23,7 @@ from dissect.cstruct.types.pointer import Pointer if TYPE_CHECKING: - from collections.abc import Iterator, Mapping + from collections.abc import Callable, Iterator, Mapping from types import FunctionType from typing_extensions import Self @@ -139,7 +139,7 @@ def _update_fields( if cls.__compiled__: # If the previous class was compiled try to compile this too - from dissect.cstruct import compiler # noqa: PLC0415 + from dissect.cstruct import compiler try: classdict["_read"] = compiler.Compiler(cls.cs).compile_read(fields, cls.__name__, align=cls.__align__) diff --git a/pyproject.toml b/pyproject.toml index f1965d4c..eb555929 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ select = [ "SLOT", "SIM", "TID", - "TCH", + "TC", "PTH", "PLC", "TRY", @@ -102,16 +102,35 @@ select = [ "PERF", "FURB", "RUF", + "D" ] -ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003"] + +ignore = [ + "E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003", "PLC0415", + # Ignore some pydocstyle rules for now as they require a larger cleanup + "D1", + "D205", + "D301", + "D417", + # Seems bugged: https://github.com/astral-sh/ruff/issues/16824 + "D402", +] +future-annotations = true + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.lint.flake8-type-checking] +strict = true [tool.ruff.lint.per-file-ignores] -"tests/**" = ["S101", "PLC0415"] +"tests/**" = ["S101"] "tests/_docs/**" = ["INP001"] [tool.ruff.lint.isort] known-first-party = ["dissect.cstruct"] known-third-party = ["dissect"] +required-imports = ["from __future__ import annotations"] [tool.setuptools.packages.find] include = ["dissect.*"] diff --git a/tests/_docs/conf.py b/tests/_docs/conf.py index 599ed324..b751a646 100644 --- a/tests/_docs/conf.py +++ b/tests/_docs/conf.py @@ -1,3 +1,5 @@ +from __future__ import annotations + project = "dissect.cstruct" extensions = [ diff --git a/tests/test_types_union.py b/tests/test_types_union.py index 660684ff..70a8e119 100644 --- a/tests/test_types_union.py +++ b/tests/test_types_union.py @@ -444,7 +444,7 @@ def test_union_default(cs: cstruct) -> None: def test_union_default_dynamic(cs: cstruct) -> None: - """initialization of a dynamic union is not yet supported""" + """Initialization of a dynamic union is not yet supported.""" cdef = """ union test { uint8 x; @@ -472,7 +472,7 @@ def test_union_default_dynamic(cs: cstruct) -> None: def test_union_partial_initialization(cs: cstruct) -> None: - """partial initialization of a union should fill in the rest with appropriate values""" + """Partial initialization of a union should fill in the rest with appropriate values.""" cdef = """ union test { uint8 a; @@ -518,7 +518,7 @@ def test_union_partial_initialization(cs: cstruct) -> None: def test_union_partial_initialization_dynamic(cs: cstruct) -> None: - """partial initialization of a dynamic union should fill in the rest with appropriate values""" + """Partial initialization of a dynamic union should fill in the rest with appropriate values.""" cdef = """ union test { uint8 x; From 33c83282381ccd1adad0ab7c886d74dce220afac Mon Sep 17 00:00:00 2001 From: wbi Date: Thu, 19 Mar 2026 09:57:15 +0100 Subject: [PATCH 2/2] Add comments. --- dissect/cstruct/parser.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dissect/cstruct/parser.py b/dissect/cstruct/parser.py index bfb72f62..303333ab 100644 --- a/dissect/cstruct/parser.py +++ b/dissect/cstruct/parser.py @@ -38,9 +38,11 @@ def parse(self, data: str) -> None: class TokenParser(Parser): - """Args: - cs: An instance of cstruct. - compiled: Whether structs should be compiled or not. + """Definition parser for C-like structure syntax. + + Args: + cs: An instance of cstruct. + compiled: Whether structs should be compiled or not. """ def __init__(self, cs: cstruct, compiled: bool = True, align: bool = False): @@ -473,7 +475,7 @@ def parse(self, data: str) -> None: class CStyleParser(Parser): - """Definition parser for C-like structure syntax. + """Definition parser for C-like structure syntax (legacy parser). Args: cs: An instance of cstruct