dissect.cstruct 5.0.dev9__tar.gz → 5.0.dev10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/PKG-INFO +1 -1
  2. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/PKG-INFO +1 -1
  3. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/scm_file_list.json +48 -48
  4. dissect_cstruct-5.0.dev10/dissect.cstruct.egg-info/scm_version.json +8 -0
  5. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_benchmark.py +179 -0
  6. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tox.ini +2 -0
  7. dissect_cstruct-5.0.dev9/dissect.cstruct.egg-info/scm_version.json +0 -8
  8. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/.git-blame-ignore-revs +0 -0
  9. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/.gitattributes +0 -0
  10. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/CHANGELOG.md +0 -0
  11. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/COPYRIGHT +0 -0
  12. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/LICENSE +0 -0
  13. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/MANIFEST.in +0 -0
  14. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/README.md +0 -0
  15. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/__init__.py +0 -0
  16. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/bitbuffer.py +0 -0
  17. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/compiler.py +0 -0
  18. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/cstruct.py +0 -0
  19. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/exception.py +0 -0
  20. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/expression.py +0 -0
  21. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/lexer.py +0 -0
  22. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/parser.py +0 -0
  23. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/tools/__init__.py +0 -0
  24. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/tools/stubgen.py +0 -0
  25. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/__init__.py +0 -0
  26. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/base.py +0 -0
  27. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/char.py +0 -0
  28. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/enum.py +0 -0
  29. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/flag.py +0 -0
  30. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/int.py +0 -0
  31. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/leb128.py +0 -0
  32. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/packed.py +0 -0
  33. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/pointer.py +0 -0
  34. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/structure.py +0 -0
  35. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/void.py +0 -0
  36. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/types/wchar.py +0 -0
  37. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect/cstruct/util.py +0 -0
  38. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/SOURCES.txt +0 -0
  39. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/dependency_links.txt +0 -0
  40. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/entry_points.txt +0 -0
  41. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/requires.txt +0 -0
  42. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/dissect.cstruct.egg-info/top_level.txt +0 -0
  43. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/examples/disk.py +0 -0
  44. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/examples/mirai.py +0 -0
  45. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/examples/pe.py +0 -0
  46. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/examples/protobuf.py +0 -0
  47. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/examples/secdesc.py +0 -0
  48. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/pyproject.toml +0 -0
  49. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/setup.cfg +0 -0
  50. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/__init__.py +0 -0
  51. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/_data/testdef.txt +0 -0
  52. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/_docs/Makefile +0 -0
  53. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/_docs/__init__.py +0 -0
  54. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/_docs/conf.py +0 -0
  55. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/_docs/index.rst +0 -0
  56. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/conftest.py +0 -0
  57. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_align.py +0 -0
  58. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_annotations.py +0 -0
  59. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_basic.py +0 -0
  60. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_bitbuffer.py +0 -0
  61. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_bitfield.py +0 -0
  62. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_compiler.py +0 -0
  63. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_ctypes.py +0 -0
  64. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_expression.py +0 -0
  65. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_lexer.py +0 -0
  66. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_parser.py +0 -0
  67. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_tools_stubgen.py +0 -0
  68. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_base.py +0 -0
  69. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_char.py +0 -0
  70. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_custom.py +0 -0
  71. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_enum.py +0 -0
  72. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_flag.py +0 -0
  73. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_int.py +0 -0
  74. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_leb128.py +0 -0
  75. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_packed.py +0 -0
  76. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_pointer.py +0 -0
  77. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_structure.py +0 -0
  78. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_union.py +0 -0
  79. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_void.py +0 -0
  80. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_types_wchar.py +0 -0
  81. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/test_utils.py +0 -0
  82. {dissect_cstruct-5.0.dev9 → dissect_cstruct-5.0.dev10}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dissect.cstruct
3
- Version: 5.0.dev9
3
+ Version: 5.0.dev10
4
4
  Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dissect.cstruct
3
- Version: 5.0.dev9
3
+ Version: 5.0.dev10
4
4
  Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License-Expression: Apache-2.0
@@ -1,78 +1,78 @@
1
1
  {
2
2
  "files": [
3
- "LICENSE",
4
- "tox.ini",
5
- "CHANGELOG.md",
6
- "README.md",
7
- ".gitattributes",
8
3
  ".git-blame-ignore-revs",
9
- "MANIFEST.in",
10
- ".gitignore",
11
- "COPYRIGHT",
12
- "pyproject.toml",
4
+ ".gitattributes",
13
5
  ".github/pull_request_template.md",
14
6
  ".github/workflows/dissect-ci.yml",
15
- "dissect/cstruct/cstruct.py",
16
- "dissect/cstruct/parser.py",
17
- "dissect/cstruct/lexer.py",
7
+ ".gitignore",
8
+ "CHANGELOG.md",
9
+ "COPYRIGHT",
10
+ "LICENSE",
11
+ "MANIFEST.in",
12
+ "README.md",
13
+ "dissect/cstruct/__init__.py",
14
+ "dissect/cstruct/bitbuffer.py",
18
15
  "dissect/cstruct/compiler.py",
16
+ "dissect/cstruct/cstruct.py",
19
17
  "dissect/cstruct/exception.py",
20
18
  "dissect/cstruct/expression.py",
21
- "dissect/cstruct/__init__.py",
22
- "dissect/cstruct/bitbuffer.py",
23
- "dissect/cstruct/util.py",
19
+ "dissect/cstruct/lexer.py",
20
+ "dissect/cstruct/parser.py",
24
21
  "dissect/cstruct/tools/__init__.py",
25
22
  "dissect/cstruct/tools/stubgen.py",
23
+ "dissect/cstruct/types/__init__.py",
26
24
  "dissect/cstruct/types/base.py",
27
- "dissect/cstruct/types/pointer.py",
25
+ "dissect/cstruct/types/char.py",
26
+ "dissect/cstruct/types/enum.py",
28
27
  "dissect/cstruct/types/flag.py",
29
- "dissect/cstruct/types/wchar.py",
30
- "dissect/cstruct/types/leb128.py",
31
- "dissect/cstruct/types/structure.py",
32
28
  "dissect/cstruct/types/int.py",
33
- "dissect/cstruct/types/__init__.py",
34
- "dissect/cstruct/types/char.py",
29
+ "dissect/cstruct/types/leb128.py",
35
30
  "dissect/cstruct/types/packed.py",
31
+ "dissect/cstruct/types/pointer.py",
32
+ "dissect/cstruct/types/structure.py",
36
33
  "dissect/cstruct/types/void.py",
37
- "dissect/cstruct/types/enum.py",
34
+ "dissect/cstruct/types/wchar.py",
35
+ "dissect/cstruct/util.py",
38
36
  "examples/disk.py",
37
+ "examples/mirai.py",
39
38
  "examples/pe.py",
40
39
  "examples/protobuf.py",
41
40
  "examples/secdesc.py",
42
- "examples/mirai.py",
43
- "tests/test_utils.py",
44
- "tests/test_lexer.py",
41
+ "pyproject.toml",
42
+ "tests/__init__.py",
43
+ "tests/_data/testdef.txt",
44
+ "tests/_docs/Makefile",
45
+ "tests/_docs/__init__.py",
46
+ "tests/_docs/conf.py",
47
+ "tests/_docs/index.rst",
48
+ "tests/conftest.py",
49
+ "tests/test_align.py",
50
+ "tests/test_annotations.py",
51
+ "tests/test_basic.py",
45
52
  "tests/test_benchmark.py",
53
+ "tests/test_bitbuffer.py",
54
+ "tests/test_bitfield.py",
55
+ "tests/test_compiler.py",
56
+ "tests/test_ctypes.py",
57
+ "tests/test_expression.py",
58
+ "tests/test_lexer.py",
46
59
  "tests/test_parser.py",
47
60
  "tests/test_tools_stubgen.py",
48
- "tests/test_types_enum.py",
49
- "tests/test_types_structure.py",
50
61
  "tests/test_types_base.py",
51
- "tests/test_types_void.py",
52
- "tests/test_types_packed.py",
53
- "tests/test_types_pointer.py",
54
- "tests/__init__.py",
55
62
  "tests/test_types_char.py",
56
- "tests/test_types_leb128.py",
57
63
  "tests/test_types_custom.py",
58
- "tests/test_compiler.py",
59
- "tests/test_align.py",
60
- "tests/test_basic.py",
61
- "tests/test_types_wchar.py",
62
- "tests/test_bitfield.py",
63
- "tests/test_types_union.py",
64
+ "tests/test_types_enum.py",
64
65
  "tests/test_types_flag.py",
65
- "tests/conftest.py",
66
66
  "tests/test_types_int.py",
67
- "tests/test_expression.py",
68
- "tests/test_annotations.py",
69
- "tests/test_ctypes.py",
70
- "tests/test_bitbuffer.py",
67
+ "tests/test_types_leb128.py",
68
+ "tests/test_types_packed.py",
69
+ "tests/test_types_pointer.py",
70
+ "tests/test_types_structure.py",
71
+ "tests/test_types_union.py",
72
+ "tests/test_types_void.py",
73
+ "tests/test_types_wchar.py",
74
+ "tests/test_utils.py",
71
75
  "tests/utils.py",
72
- "tests/_docs/__init__.py",
73
- "tests/_docs/conf.py",
74
- "tests/_docs/index.rst",
75
- "tests/_docs/Makefile",
76
- "tests/_data/testdef.txt"
76
+ "tox.ini"
77
77
  ]
78
78
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "5.0.dev0",
3
+ "distance": 10,
4
+ "node": "ge5261d5fa176890243eded2be0a28327fda617b3",
5
+ "dirty": true,
6
+ "branch": "main",
7
+ "node_date": "2026-10-28"
8
+ }
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import io
3
4
  from functools import partial
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -48,6 +49,43 @@ def test_benchmark_union(cs: cstruct, compiled: bool, benchmark: BenchmarkFixtur
48
49
  benchmark(lambda: cs.test(b"\x01\x02\x03\x04\x05\x06\x07\x08"))
49
50
 
50
51
 
52
+ @pytest.mark.benchmark
53
+ def test_benchmark_union_nested(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
54
+ """Benchmark the parsing of a union with nested structures with both the compiled and interpreted backends."""
55
+ cdef = """
56
+ union test {
57
+ struct {
58
+ uint32 offset;
59
+ uint32 block;
60
+ } lsn;
61
+ struct {
62
+ uint16 low;
63
+ uint16 mid;
64
+ uint32 high;
65
+ } parts;
66
+ uint64 value;
67
+ };
68
+ """
69
+ cs.load(cdef, compiled=compiled)
70
+
71
+ benchmark(lambda: cs.test(b"\x01\x02\x03\x04\x05\x06\x07\x08"))
72
+
73
+
74
+ @pytest.mark.benchmark
75
+ def test_benchmark_union_array(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
76
+ """Benchmark the parsing of an array of unions with both the compiled and interpreted backends."""
77
+ cdef = """
78
+ union test {
79
+ uint32 a;
80
+ char b[4];
81
+ };
82
+ """
83
+ cs.load(cdef, compiled=compiled)
84
+
85
+ buf = bytes(range(64))
86
+ benchmark(lambda: cs.test[16](buf))
87
+
88
+
51
89
  @pytest.mark.benchmark
52
90
  def test_benchmark_attribute_access(cs: cstruct, benchmark: BenchmarkFixture) -> None:
53
91
  """Benchmark the attribute access of a parsed struct."""
@@ -200,3 +238,144 @@ def test_benchmark_lexer_and_parser(cs: cstruct, benchmark: BenchmarkFixture) ->
200
238
  cs.add_type = partial(cs.add_type, replace=True)
201
239
 
202
240
  benchmark(lambda: cs.load(_BENCHMARK_CDEF))
241
+
242
+
243
+ @pytest.mark.benchmark
244
+ def test_benchmark_nested_dynamic(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
245
+ """Benchmark the parsing of a realistic struct with nested structs and dynamically sized arrays."""
246
+ cs.load(_BENCHMARK_CDEF, compiled=compiled)
247
+
248
+ buf = (
249
+ b"\x01\x00\x00\x00" # Mask
250
+ b"\x03\x00\x00\x00" # Flags
251
+ + bytes(range(16)) # ObjectType
252
+ + bytes(range(16)) # InheritedObjectType
253
+ + b"\x01\x04\x00\x00\x00\x00\x00\x05" # Sid
254
+ + b"\x15\x00\x00\x00" * 4 # Sid.SubAuthority
255
+ )
256
+
257
+ benchmark(lambda: cs.ACCESS_ALLOWED_OBJECT_ACE(buf))
258
+
259
+
260
+ @pytest.mark.benchmark
261
+ def test_benchmark_enum_flag_bits(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
262
+ """Benchmark the parsing of a struct with enums, flags and bit fields."""
263
+ cdef = """
264
+ enum Type : uint16 {
265
+ A = 1,
266
+ B = 2,
267
+ };
268
+
269
+ flag Flags : uint16 {
270
+ X = 1,
271
+ Y = 2,
272
+ Z = 4,
273
+ };
274
+
275
+ struct test {
276
+ Type type;
277
+ Flags flags;
278
+ uint16 a : 4;
279
+ uint16 b : 12;
280
+ uint32 c;
281
+ };
282
+ """
283
+ cs.load(cdef, compiled=compiled)
284
+
285
+ benchmark(lambda: cs.test(b"\x01\x00\x05\x00\x34\x12\x01\x00\x00\x00"))
286
+
287
+
288
+ @pytest.mark.benchmark
289
+ def test_benchmark_flag_operators(cs: cstruct, benchmark: BenchmarkFixture) -> None:
290
+ """Benchmark bitwise operations on flags."""
291
+ cdef = """
292
+ flag Flags : uint16 {
293
+ X = 1,
294
+ Y = 2,
295
+ Z = 4,
296
+ };
297
+ """
298
+ cs.load(cdef)
299
+ value = cs.Flags.X | cs.Flags.Z
300
+
301
+ benchmark(lambda: (value & cs.Flags.X, value | cs.Flags.Y, value & 0x4))
302
+
303
+
304
+ @pytest.mark.benchmark
305
+ def test_benchmark_strings(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
306
+ """Benchmark the parsing of a struct with fixed size and null-terminated strings."""
307
+ cdef = """
308
+ struct test {
309
+ wchar name[8];
310
+ char path[];
311
+ wchar description[];
312
+ };
313
+ """
314
+ cs.load(cdef, compiled=compiled)
315
+
316
+ buf = (
317
+ "filename".encode("utf-16-le") # name
318
+ + b"some/path/to/a/file\x00" # path
319
+ + "A description".encode("utf-16-le") # description
320
+ + b"\x00\x00"
321
+ )
322
+
323
+ benchmark(lambda: cs.test(buf))
324
+
325
+
326
+ @pytest.mark.benchmark
327
+ @pytest.mark.parametrize("kind", ["bytes", "memoryview", "stream"])
328
+ def test_benchmark_primitive(cs: cstruct, kind: str, benchmark: BenchmarkFixture) -> None:
329
+ """Benchmark the parsing of a primitive type from different kinds of input."""
330
+ buf = b"\x01\x02\x03\x04"
331
+
332
+ if kind == "stream":
333
+ fh = io.BytesIO(buf)
334
+
335
+ def read() -> int:
336
+ fh.seek(0)
337
+ return cs.uint32(fh)
338
+
339
+ benchmark(read)
340
+ else:
341
+ obj = memoryview(buf) if kind == "memoryview" else buf
342
+ benchmark(lambda: cs.uint32(obj))
343
+
344
+
345
+ @pytest.mark.benchmark
346
+ def test_benchmark_array(cs: cstruct, benchmark: BenchmarkFixture) -> None:
347
+ """Benchmark the parsing of an array type created at runtime."""
348
+ buf = bytes(range(64))
349
+
350
+ benchmark(lambda: cs.uint32[16](buf))
351
+
352
+
353
+ @pytest.mark.benchmark
354
+ def test_benchmark_dumps(cs: cstruct, benchmark: BenchmarkFixture) -> None:
355
+ """Benchmark the writing of a simple struct."""
356
+ cdef = """
357
+ struct test {
358
+ uint32 a;
359
+ uint64 b;
360
+ uint16 c;
361
+ uint8 d;
362
+ };
363
+ """
364
+ cs.load(cdef)
365
+ obj = cs.test(b"\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x04")
366
+
367
+ benchmark(lambda: obj.dumps())
368
+
369
+
370
+ @pytest.mark.benchmark
371
+ def test_benchmark_load_and_read(cs: cstruct, compiled: bool, benchmark: BenchmarkFixture) -> None:
372
+ """Benchmark loading struct definitions and reading one struct, which includes any (lazy) compilation."""
373
+ cs.add_type = partial(cs.add_type, replace=True)
374
+
375
+ buf = b"\x02\x01\x00\x00\x00\x00\x00\x05" + b"\x15\x00\x00\x00" * 2
376
+
377
+ def load_and_read() -> None:
378
+ cs.load(_BENCHMARK_CDEF, compiled=compiled)
379
+ cs.LDAP_SID(buf)
380
+
381
+ benchmark(load_and_read)
@@ -24,6 +24,8 @@ commands =
24
24
 
25
25
  [testenv:benchmark]
26
26
  deps =
27
+ # Until pytest-codspeed is compatible with 9.2
28
+ pytest<9.2
27
29
  pytest-benchmark
28
30
  pytest-codspeed
29
31
  dependency_groups = test
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "5.0.dev0",
3
- "distance": 9,
4
- "node": "g46b850fa9cd023a9de583149caa5e9ba31254cf1",
5
- "dirty": true,
6
- "branch": "main",
7
- "node_date": "2026-08-07"
8
- }