eclipse-cyclonedds / eclipse-cyclonedds/cyclonedds-python
Postponed Evaluation of Annotations causes TypeError in cyclonedds/idl/_type_normalize.py
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 110
- Forks
- 68
- Avg merge
- 1h 8m
- Merged PRs (30d)
- 1
Description
Postponed evaluation of annotations is characterized by the following import statement:
from __future__ import annotations
This is sometimes required for type-hints (e.g. allowing writing union types as X | Y in Python 3.10).
My issue is that I get the following stack-trace when including the above import statement while trying to instantiate cyclonedds.topic.Topic:
0.437 Traceback (most recent call last):
0.437 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 38, in _strip_unextended_type
0.437 return _strip_unextended_type(modulename, getattr(pymodule, typename))
0.437 AttributeError: module '__main__' has no attribute 'str'
0.437
0.437 During handling of the above exception, another exception occurred:
0.437
0.437 Traceback (most recent call last):
0.437 File "<stdin>", line 14, in <module>
0.437 File "/usr/local/lib/python3.10/site-packages/cyclonedds/topic.py", line 54, in __init__
0.438 data_type.__idl__.populate()
0.438 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_main.py", line 89, in populate
0.438 for name, _ in get_extended_type_hints(self.datatype).items():
0.438 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 106, in get_extended_type_hints
0.438 _normalize_idl_class(cls)
0.438 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 93, in _normalize_idl_class
0.439 cls.__idl_type_annotations__ = _make_extended_type_hints(cls)
0.439 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 84, in _make_extended_type_hints
0.439 return {k: _strip_unextended_type(cls.__module__, v) for k, v in hints.items() if not k.startswith("__")}
0.439 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 84, in <dictcomp>
0.439 return {k: _strip_unextended_type(cls.__module__, v) for k, v in hints.items() if not k.startswith("__")}
0.439 File "/usr/local/lib/python3.10/site-packages/cyclonedds/idl/_type_normalize.py", line 40, in _strip_unextended_type
0.439 raise TypeError(f"Type {_type} as used in {module} cannot be resolved.")
0.439 TypeError: Type str as used in __main__ cannot be resolved.
Here's a Dockerfile for reproducing this bug (the Python code is derived from the cyclonedds Python API docs here):
FROM python:3.10-alpine3.22 AS base
RUN <<EOF
apk update
pip install --upgrade pip
pip install cyclonedds=="0.10.5"
EOF
FROM base AS works
RUN python3 <<EOF
from cyclonedds.domain import DomainParticipant
from cyclonedds.topic import Topic
from cyclonedds.pub import DataWriter
from dataclasses import dataclass
from cyclonedds.idl import IdlStruct
@dataclass
class Message(IdlStruct):
text: str
participant = DomainParticipant()
topic = Topic(participant, "someTopic", Message)
writer = DataWriter(participant, topic)
writer.write(Message(text="some text"))
EOF
FROM base AS fails
RUN python3 <<EOF
from __future__ import annotations # <--- THIS CAUSES ERROR
from cyclonedds.domain import DomainParticipant
from cyclonedds.topic import Topic
from cyclonedds.pub import DataWriter
from dataclasses import dataclass
from cyclonedds.idl import IdlStruct
@dataclass
class Message(IdlStruct):
text: str
participant = DomainParticipant()
topic = Topic(participant, "someTopic", Message)
writer = DataWriter(participant, topic)
writer.write(Message(text="some text"))
EOF
With the above Dockerfile in your current directory, the works target can be successfully built by running:
docker build --target works .
Whereas building the fails target will result in the above stack-trace (the only difference between the two is the from __future__ import annotations import statement):
docker build --target fails .
Although postponed evaluation of annotations isn't necessary in this example code, I've found it is necessary for correct type-hinting in some circumstances. In any-case it's good to bring some attention to this bug (I couldn't see any other issues flagging it) and the work-around for dealing with it at time of writing.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with the Dockerfile's fails target, then inspect cyclonedds/idl/_type_normalize.py along the reported _strip_unextended_type and get_extended_type_hints stack. Compare the behavior with the works target and verify that the same Message example succeeds when postponed annotations are enabled without raising the shown TypeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100