protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

Support forward references

Open eigenein opened this issue 2 years ago • 0 comments

Test case

diff --git a/pure_protobuf/message.py b/pure_protobuf/message.py
index 81813ca..acc0b1e 100644
--- a/pure_protobuf/message.py
+++ b/pure_protobuf/message.py
@@ -53,6 +53,7 @@ class BaseMessage(ABC):
         cls.__PROTOBUF_FIELDS_BY_NAME__ = {}
 
         type_hints: Dict[str, Any] = get_annotations(cls, eval_str=True)
+
         for name, hint in type_hints.items():
             descriptor = _FieldDescriptor.from_attribute(cls, hint)
             if descriptor is not None:
diff --git a/tests/definitions.py b/tests/definitions.py
index 4468da0..a1d9053 100644
--- a/tests/definitions.py
+++ b/tests/definitions.py
@@ -21,3 +21,13 @@ class ExampleEnum(IntEnum):
 class RecursiveMessage(BaseMessage):
     payload: Annotated[uint, Field(1)]
     inner: Annotated[Optional[Self], Field(2)] = None
+
+
+@dataclass
+class CyclicMessageA(BaseMessage):
+    inner: Annotated[Optional["CyclicMessageB"], Field(1)]
+
+
+@dataclass
+class CyclicMessageB(BaseMessage):
+    inner: Annotated[Optional["CyclicMessageA"], Field(1)]
diff --git a/tests/descriptors/test_field.py b/tests/descriptors/test_field.py
index f6423cf..58247bd 100644
--- a/tests/descriptors/test_field.py
+++ b/tests/descriptors/test_field.py
@@ -9,7 +9,7 @@ from pure_protobuf.exceptions import IncorrectAnnotationError
 from pure_protobuf.io.wrappers import to_bytes
 from pure_protobuf.message import BaseMessage
 from tests import pytest_test_id
-from tests.definitions import ExampleEnum, RecursiveMessage
+from tests.definitions import ExampleEnum, RecursiveMessage, CyclicMessageA, CyclicMessageB
 
 
 @mark.parametrize("hint", [int, Annotated[int, ...]])
@@ -45,7 +45,7 @@ def test_from_inner_hint_incorrect(hint: Any) -> None:
             b"\xd2\x02\x06\x08\x01\x12\x02\x08\x02",
         ),
         (Annotated[List[uint], Field(1, packed=False)], [1, 2], b"\x08\x01\x08\x02"),
-        # TODO: what about messages with cyclic dependencies?
+        (Annotated[CyclicMessageA, Field(2)], CyclicMessageA(CyclicMessageB(None)), b""),
     ],
     ids=pytest_test_id,
 )

eigenein avatar Feb 16 '23 15:02 eigenein