fix: allow union types in streaming_action.pydantic stream_type parameter#732
fix: allow union types in streaming_action.pydantic stream_type parameter#732mvanhorn wants to merge 3 commits into
Conversation
…eter Accept types.UnionType in stream_type so Python 3.10+ union syntax (MyModel1 | MyModel2) works with streaming_action.pydantic decorator. Fixes apache#607
|
Thanks! Can you validate that pyright doesn't complain? That's the litmus test here. |
|
Ran pyright (1.1.408) against the two changed files and compared to main:
No new pyright issues introduced by the |
|
@mvanhorn all the test failures are related to this change. can you run the unit tests locally please?
Otherwise, can you create an example that has:
and that pyright doesn't complain about? |
`types.UnionType` was added in Python 3.10 to represent PEP 604 `X | Y`
union syntax. Burr supports Python >= 3.9, so on 3.9 any module that
references `types.UnionType` at import time hits an AttributeError at
collection time, which is why CI was showing:
ERROR tests/core/test_action.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_application.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_graph.py - AttributeError: module 'types' has no attribute 'UnionType'
Introduce a `_UnionType` compatibility alias in `burr/core/action.py`:
`types.UnionType` on Python >= 3.10, a placeholder sentinel class on
Python < 3.10. Replace every `types.UnionType` reference in
`burr/core/action.py` and `burr/integrations/pydantic.py` with that
alias. `pydantic.py` imports it from `burr.core.action`, matching the
convention used for the other shared symbols imported from that module.
Since PEP 604 syntax doesn't exist on Python 3.9, no real union type can
reach those call sites on 3.9 anyway, so the sentinel path is
never hit at runtime. 3.10+ behavior is unchanged.
Verified with full test run under a clean venv:
tests/core/test_action.py + test_application.py + test_graph.py: 250 passed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@skrawcz good catch - that's a Python 3.9 import-time failure. Fixed in 6776e86: introduced a Ran the full |
There was a problem hiding this comment.
tks @mvanhorn
LGTM after adding at least one test that exercises stream_type=Model1 | Model2 in Python 3.10+.
Optional but appreciated: fix the return-type annotation in _validate_and_extract_signature_types_streaming and consider renaming _UnionType to a public name.
Per @andreahlert's review on PR apache#732: - Add test_streaming_pydantic_action_union_stream_type exercising stream_type=Model1 | Model2 (PEP 604), guarded with sys.version_info >= (3, 10) skip for 3.9 compatibility. - Widen the _validate_and_extract_signature_types_streaming return type to Union[Type[dict], Type[pydantic.BaseModel], _UnionType] so the annotation matches the runtime values returned in the union case. Verified: pytest tests/integrations/test_burr_pydantic.py - 34 passed (Python 3.12).
|
Done in 5c81fc8:
Verified: Skipped the |
Python 3.10+ union syntax (
MyModel1 | MyModel2) creates atypes.UnionType, which thestream_typeparameter rejected because it only acceptedType[BaseModel]orType[dict].Added
types.UnionTypeto the accepted types in three places:burr/integrations/pydantic.py:PartialTypealias (line 272)burr/integrations/pydantic.py:_validate_and_extract_signature_types_streamingparameter (line 293)burr/core/action.py:streaming_action.pydanticparameter (line 1514)Before:
After:
Both files already import
types, so no new imports needed.types.UnionTypeis available in Python 3.10+; on 3.9, the|syntax isn't available anyway so the added type is inert.Fixes #607
This contribution was developed with AI assistance (Claude Code).