Skip to content

Commit f7ab3de

Browse files
authored
fix(unpack+pack): parsing and building with dynamic offsets
- Merge pull request #58 from MatrixEditor/fix/dynamic-offsets - Move all parsing and building related functions (pack*, unpack*, sizeof) into a separate file for easy import handling.
2 parents 2d244a7 + fece147 commit f7ab3de

7 files changed

Lines changed: 688 additions & 595 deletions

File tree

src/caterpillar/context.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import warnings
2222

2323
from typing import Annotated, Callable, Any, Generic, Protocol, get_origin
24-
from typing_extensions import Final, Literal, Self, Sized, overload, override, TypeVar
24+
from typing_extensions import Buffer, Final, Literal, Self, Sized, overload, override, TypeVar
2525
from types import FrameType, TracebackType
2626
from dataclasses import dataclass
2727

@@ -105,7 +105,7 @@ def __getattribute__(self, key: Literal["_parent"]) -> _ContextLike: ...
105105
@overload
106106
def __getattribute__(self, key: Literal["_obj"]) -> _ContextLike: ...
107107
@overload
108-
def __getattribute__(self, key: Literal["_offsets"]) -> dict[int, int]: ...
108+
def __getattribute__(self, key: Literal["_offsets"]) -> dict[int, Buffer]: ...
109109
@overload
110110
def __getattribute__(self, key: Literal["_io"]) -> _StreamType: ...
111111
@overload
@@ -181,7 +181,7 @@ def __getitem__(self, key: Literal["_root"], /) -> _ContextLike: ...
181181
@overload
182182
def __getitem__(self, key: Literal["_io"], /) -> _StreamType: ...
183183
@overload
184-
def __getitem__(self, key: Literal["_offsets"], /) -> dict[int, int]: ...
184+
def __getitem__(self, key: Literal["_offsets"], /) -> dict[int, Buffer]: ...
185185
@overload
186186
def __getitem__(self, key: Literal["_index"], /) -> int: ...
187187
@overload
@@ -621,7 +621,7 @@ def __getattribute__(self, key: Literal["_obj"]) -> ContextPath[_ContextLike]: .
621621
@overload
622622
def __getattribute__(
623623
self, key: Literal["_offsets"]
624-
) -> ContextPath[dict[int, int]]: ...
624+
) -> ContextPath[dict[int, Buffer]]: ...
625625
@overload
626626
def __getattribute__(self, key: Literal["_io"]) -> ContextPath[_StreamType]: ...
627627
@overload

src/caterpillar/fields/_base.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,13 @@ def offset(self) -> _ContextLambda[int] | int:
214214
@offset.setter
215215
def offset(self, value: _ContextLambda[int] | int):
216216
self.__offset = value
217-
self._has_offset = value not in (-1, None)
217+
# _ContextLambda is ExprMixin so `__eq__` is overridden
218+
# and `Tuple.__contains__` isn't correct. If value is an
219+
# instance of _ContextLambda we may assume it is not
220+
# -1 or None
221+
self._has_offset = value not in (-1, None) or isinstance(value, _ContextLambda)
218222
self._offset_is_lambda = callable(value)
219-
self._keep_pos = value in (-1, None)
223+
self._keep_pos = value in (-1, None) and not isinstance(value, _ContextLambda)
220224

221225
@property
222226
def amount(self) -> _LengthT | None:

src/caterpillar/model/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818
struct,
1919
UnionHook,
2020
union,
21-
unpack,
22-
unpack_file,
23-
pack,
24-
pack_into,
25-
pack_file,
26-
sizeof,
2721
Invisible,
2822
StructDefMixin,
2923
struct_factory,
@@ -46,6 +40,14 @@
4640
BitfieldDefMixin,
4741
)
4842
from ._template import istemplate, template, TemplateTypeVar, derive
43+
from .provider import (
44+
unpack,
45+
unpack_file,
46+
pack,
47+
pack_into,
48+
pack_file,
49+
sizeof,
50+
)
4951

5052
__all__ = [
5153
"Sequence",

0 commit comments

Comments
 (0)