Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support forward references #108

Open
eigenein opened this issue Feb 16, 2023 · 0 comments
Open

Support forward references #108

eigenein opened this issue Feb 16, 2023 · 0 comments
Assignees
Labels

Comments

@eigenein
Copy link
Owner

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 eigenein self-assigned this Feb 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant