Skip to content

Commit 6c62a57

Browse files
committed
fix: iterate over the annotation chain in correct order
1 parent 8037e7e commit 6c62a57

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

libdestruct/common/struct/struct_impl.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ def _inflate_struct_attributes(
6868
) -> None:
6969
current_offset = 0
7070

71-
for name, annotation in iterate_annotation_chain(reference_type, terminate_at=struct):
72-
if name in reference_type.__dict__:
71+
for name, annotation, reference in iterate_annotation_chain(reference_type, terminate_at=struct):
72+
if name in reference.__dict__:
7373
# Field associated with the annotation
74-
attrs = getattr(reference_type, name)
74+
attrs = getattr(reference, name)
7575

7676
# If attrs is not a tuple, we need to convert it to a tuple
7777
if not isinstance(attrs, tuple):
@@ -113,10 +113,11 @@ def compute_own_size(cls: type[struct_impl], reference_type: type) -> None:
113113
"""Compute the size of the struct."""
114114
size = 0
115115

116-
for name, annotation in iterate_annotation_chain(reference_type, terminate_at=struct):
117-
if name in reference_type.__dict__:
116+
for name, annotation, reference in iterate_annotation_chain(reference_type, terminate_at=struct):
117+
print(name, annotation, reference)
118+
if name in reference.__dict__:
118119
# Field associated with the annotation
119-
attrs = getattr(reference_type, name)
120+
attrs = getattr(reference, name)
120121

121122
# If attrs is not a tuple, we need to convert it to a tuple
122123
if not isinstance(attrs, tuple):

libdestruct/common/utils.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,16 @@ def size_of(item_or_inflater: obj | callable[[Resolver], obj]) -> int:
3636
raise ValueError(f"Cannot determine the size of {item_or_inflater}")
3737

3838

39-
def iterate_annotation_chain(item: obj, terminate_at: object | None = None) -> Generator[tuple[str, Any]]:
39+
def iterate_annotation_chain(item: obj, terminate_at: object | None = None) -> Generator[tuple[str, Any, type[obj]]]:
4040
"""Iterate over the annotation chain of the provided item."""
4141
current_item = item
42+
43+
chain = []
44+
4245
while current_item is not terminate_at:
43-
yield from current_item.__annotations__.items()
46+
chain.insert(0, current_item)
4447
current_item = current_item.__base__ if hasattr(current_item, "__base__") else None
48+
49+
for reference_item in chain:
50+
for name, annotation in reference_item.__annotations__.items():
51+
yield name, annotation, reference_item

0 commit comments

Comments
 (0)