From ea1eb1a597f7d926973992db57d40e524d7d057c Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Fri, 19 Sep 2025 14:12:11 +0000 Subject: [PATCH 01/11] Change the minimum python version to 3.10 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d5d999a..f71b86a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "dissect.cstruct" description = "A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy" readme = "README.md" -requires-python = "~=3.9" +requires-python = ">=3.10" license.text = "Apache License 2.0" authors = [ {name = "Dissect Team", email = "dissect@fox-it.com"} From 3498599760c521a4b6b9f5fc51f147f19e49bca9 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Fri, 19 Sep 2025 14:48:15 +0000 Subject: [PATCH 02/11] Update deprecated license settings --- pyproject.toml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f71b86a..b18492f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [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] @@ -7,7 +7,8 @@ name = "dissect.cstruct" description = "A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy" readme = "README.md" requires-python = ">=3.10" -license.text = "Apache License 2.0" +license = "Apache-2.0" +license-files = ["LICENSE", "COPYRIGHT"] authors = [ {name = "Dissect Team", email = "dissect@fox-it.com"} ] @@ -91,9 +92,6 @@ ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM1 known-first-party = ["dissect.cstruct"] known-third-party = ["dissect"] -[tool.setuptools] -license-files = ["LICENSE", "COPYRIGHT"] - [tool.setuptools.packages.find] include = ["dissect.*"] From 67dc2228931d09ce4606b6ab4a4bc7aa43ef6fb5 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Fri, 19 Sep 2025 15:39:05 +0000 Subject: [PATCH 03/11] remove 'License :: OSI approved' from specifiers --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b18492f..604545a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,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", From 163325a40a6163664e0adb0b6e4b8d7816e5c136 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Mon, 22 Sep 2025 09:31:22 +0000 Subject: [PATCH 04/11] Change vermin minimum version to python3.10 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 6dc6854..37e8d90 100644 --- a/tox.ini +++ b/tox.ini @@ -45,7 +45,7 @@ deps = commands = ruff format --check dissect tests ruff check dissect tests - vermin -t=3.9- --no-tips --lint dissect tests + vermin -t=3.10- --no-tips --lint dissect tests [testenv:docs-build] allowlist_externals = make From e1091d118c307a3b8dd3183c2090279e25e24c4f Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Tue, 23 Sep 2025 09:19:55 +0000 Subject: [PATCH 05/11] Update lint and fix steps tox.ini --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 37e8d90..24a8c12 100644 --- a/tox.ini +++ b/tox.ini @@ -34,8 +34,8 @@ package = skip deps = ruff==0.12.4 commands = - ruff format dissect tests ruff check --fix dissect tests + ruff format dissect tests [testenv:lint] package = skip @@ -43,8 +43,8 @@ deps = ruff==0.12.4 vermin commands = - ruff format --check dissect tests ruff check dissect tests + ruff format --check dissect tests vermin -t=3.10- --no-tips --lint dissect tests [testenv:docs-build] From 998ed3d789a8990859c74564d084b3d1af93485a Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Tue, 23 Sep 2025 09:31:56 +0000 Subject: [PATCH 06/11] Bump ruff version --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 24a8c12..827d58c 100644 --- a/tox.ini +++ b/tox.ini @@ -32,7 +32,7 @@ commands = [testenv:fix] package = skip deps = - ruff==0.12.4 + ruff==0.13.1 commands = ruff check --fix dissect tests ruff format dissect tests @@ -40,7 +40,7 @@ commands = [testenv:lint] package = skip deps = - ruff==0.12.4 + ruff==0.13.1 vermin commands = ruff check dissect tests From fc4216feb918089027c2276dfbf413d6c75d94c1 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Mon, 22 Sep 2025 11:14:29 +0000 Subject: [PATCH 07/11] Fix linting for python3.10 --- dissect/cstruct/cstruct.py | 3 +-- dissect/cstruct/expression.py | 4 +++- dissect/cstruct/types/base.py | 4 +++- dissect/cstruct/types/structure.py | 6 +++--- tests/test_basic.py | 2 +- tests/test_parser.py | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dissect/cstruct/cstruct.py b/dissect/cstruct/cstruct.py index 96f7ed5..2907734 100644 --- a/dissect/cstruct/cstruct.py +++ b/dissect/cstruct/cstruct.py @@ -30,8 +30,7 @@ if TYPE_CHECKING: from collections.abc import Iterable - - from typing_extensions import TypeAlias + from typing import TypeAlias T = TypeVar("T", bound=BaseType) diff --git a/dissect/cstruct/expression.py b/dissect/cstruct/expression.py index 0bb194f..88b9457 100644 --- a/dissect/cstruct/expression.py +++ b/dissect/cstruct/expression.py @@ -1,11 +1,13 @@ from __future__ import annotations import string -from typing import TYPE_CHECKING, Callable, ClassVar +from typing import TYPE_CHECKING, ClassVar from dissect.cstruct.exceptions import ExpressionParserError, ExpressionTokenizerError if TYPE_CHECKING: + from collections.abc import Callable + from dissect.cstruct import cstruct diff --git a/dissect/cstruct/types/base.py b/dissect/cstruct/types/base.py index 90c466c..d27f00b 100644 --- a/dissect/cstruct/types/base.py +++ b/dissect/cstruct/types/base.py @@ -2,12 +2,14 @@ import functools from io import BytesIO -from typing import TYPE_CHECKING, Any, BinaryIO, Callable, ClassVar, TypeVar +from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar, TypeVar from dissect.cstruct.exceptions import ArraySizeError from dissect.cstruct.expression import Expression if TYPE_CHECKING: + from collections.abc import Callable + from typing_extensions import Self from dissect.cstruct.cstruct import cstruct diff --git a/dissect/cstruct/types/structure.py b/dissect/cstruct/types/structure.py index 8d6d61b..f2e8e03 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 MutableMapping +from collections.abc import Callable, MutableMapping from contextlib import contextmanager from enum import Enum from functools import lru_cache @@ -10,7 +10,7 @@ from operator import attrgetter from textwrap import dedent from types import FunctionType -from typing import TYPE_CHECKING, Any, BinaryIO, Callable +from typing import TYPE_CHECKING, Any, BinaryIO from dissect.cstruct.bitbuffer import BitBuffer from dissect.cstruct.types.base import ( @@ -467,7 +467,7 @@ def __call__(cls, *args, **kwargs) -> Self: # type: ignore # User (partial) initialization, rebuild the union # First user-provided field is the one used to rebuild the union - arg_fields = (field._name for _, field in zip(args, cls.__fields__)) + arg_fields = (field._name for _, field in zip(args, cls.__fields__, strict=False)) kwarg_fields = (name for name in kwargs if name in cls.lookup) if (first_field := next(chain(arg_fields, kwarg_fields), None)) is not None: obj._rebuild(first_field) diff --git a/tests/test_basic.py b/tests/test_basic.py index b4ef34d..bb0dd47 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -77,7 +77,7 @@ def test_load_init_kwargs_only() -> None: """ # kwargs only check - with pytest.raises(TypeError, match="takes from .* positional arguments but .* were given"): + with pytest.raises(TypeError, match=r"takes from .* positional arguments but .* were given"): cs = cstruct(cdef, ">") cs = cstruct(cdef, endian=">") diff --git a/tests/test_parser.py b/tests/test_parser.py index f77da47..85a7906 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -282,7 +282,7 @@ def test_conditional_parsing_error(cs: cstruct) -> None: }; #endif """ - with pytest.raises(ParserError, match="line 8: unexpected token .+ENDIF"): + with pytest.raises(ParserError, match=r"line 8: unexpected token .+ENDIF"): cs.load(cdef) cdef = """ From c99d5ce8bbd8af2eb5658c5cb2a9ba84fc11af80 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Mon, 22 Sep 2025 11:16:00 +0000 Subject: [PATCH 08/11] Update the stub generation to import from typing instead of typing_extensions --- dissect/cstruct/tools/stubgen.py | 3 +-- tests/test_tools_stubgen.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dissect/cstruct/tools/stubgen.py b/dissect/cstruct/tools/stubgen.py index 75694e3..02aaebb 100644 --- a/dissect/cstruct/tools/stubgen.py +++ b/dissect/cstruct/tools/stubgen.py @@ -39,10 +39,9 @@ def generate_file_stub(path: Path, base: Path) -> str: header = [ "# 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", ] body = [] diff --git a/tests/test_tools_stubgen.py b/tests/test_tools_stubgen.py index 5790d90..52e4f82 100644 --- a/tests/test_tools_stubgen.py +++ b/tests/test_tools_stubgen.py @@ -376,10 +376,9 @@ def test_generate_file_stub(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, cap expected = """ # 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_structure(__cs__.cstruct): class Test(__cs__.Structure): From c121771133c10ac77a94cf8b18927c05f6df81b9 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Tue, 23 Sep 2025 13:43:44 +0000 Subject: [PATCH 09/11] Update project to use dependency groups --- pyproject.toml | 21 +++++++++++++++++++++ tox.ini | 14 +++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 604545a..444a2b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,27 @@ dev = [ "typing_extensions" ] +[dependency-groups] +test = [ + "pytest", +] +lint = [ + "ruff==0.13.1", + "typing_extensions", + "vermin", +] +build = [ + "build", +] +debug = [ + "ipdb", +] +dev = [ + {include-group = "test"}, + {include-group = "lint"}, + {include-group = "debug"}, +] + [project.scripts] cstruct-stubgen = "dissect.cstruct.tools.stubgen:main" diff --git a/tox.ini b/tox.ini index 827d58c..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,24 +24,20 @@ commands = [testenv:build] package = skip -deps = - build +dependency_groups = build commands = pyproject-build [testenv:fix] package = skip -deps = - ruff==0.13.1 +dependency_groups = lint commands = ruff check --fix dissect tests ruff format dissect tests [testenv:lint] package = skip -deps = - ruff==0.13.1 - vermin +dependency_groups = lint commands = ruff check dissect tests ruff format --check dissect tests From 6d24f97791b56ebaa0edfd37bd19a9a213e9bb79 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Wed, 24 Sep 2025 12:38:14 +0000 Subject: [PATCH 10/11] Changing required ruff version to ">=0.13.1" --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 444a2b8..9885573 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ cstruct-stubgen = "dissect.cstruct.tools.stubgen:main" [tool.ruff] line-length = 120 -required-version = ">=0.12.0" +required-version = ">=0.13.1" [tool.ruff.format] docstring-code-format = true From de33074efde0ccf0587efd7704e32b539df1657b Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Wed, 24 Sep 2025 14:03:27 +0000 Subject: [PATCH 11/11] Remove python3.9 compat --- dissect/cstruct/types/base.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dissect/cstruct/types/base.py b/dissect/cstruct/types/base.py index d27f00b..d5ca7db 100644 --- a/dissect/cstruct/types/base.py +++ b/dissect/cstruct/types/base.py @@ -62,10 +62,6 @@ def __bool__(cls) -> bool: def __len__(cls) -> int: """Return the byte size of the type.""" - # Python 3.9 compat thing for bound type vars - if cls is BaseType: - return 0 - if cls.size is None: raise TypeError("Dynamic size")