Skip to content

fix: allow union types in streaming_action.pydantic stream_type parameter#732

Open
mvanhorn wants to merge 2 commits intoapache:mainfrom
mvanhorn:fix/stream-type-union-support
Open

fix: allow union types in streaming_action.pydantic stream_type parameter#732
mvanhorn wants to merge 2 commits intoapache:mainfrom
mvanhorn:fix/stream-type-union-support

Conversation

@mvanhorn
Copy link
Copy Markdown

@mvanhorn mvanhorn commented Apr 8, 2026

Python 3.10+ union syntax (MyModel1 | MyModel2) creates a types.UnionType, which the stream_type parameter rejected because it only accepted Type[BaseModel] or Type[dict].

Added types.UnionType to the accepted types in three places:

  • burr/integrations/pydantic.py: PartialType alias (line 272)
  • burr/integrations/pydantic.py: _validate_and_extract_signature_types_streaming parameter (line 293)
  • burr/core/action.py: streaming_action.pydantic parameter (line 1514)

Before:

stream_type=MyModel1 | MyModel2  # TypeError

After:

stream_type=MyModel1 | MyModel2  # works

Both files already import types, so no new imports needed. types.UnionType is 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).

…eter

Accept types.UnionType in stream_type so Python 3.10+ union syntax
(MyModel1 | MyModel2) works with streaming_action.pydantic decorator.

Fixes apache#607
@skrawcz
Copy link
Copy Markdown
Contributor

skrawcz commented Apr 10, 2026

Thanks! Can you validate that pyright doesn't complain? That's the litmus test here.

@mvanhorn
Copy link
Copy Markdown
Author

Ran pyright (1.1.408) against the two changed files and compared to main:

  • burr/core/action.py: 38 errors on both main and this branch (0 new)
  • burr/integrations/pydantic.py: 11 errors on both main and this branch (0 new)

No new pyright issues introduced by the types.UnionType additions.

@skrawcz
Copy link
Copy Markdown
Contributor

skrawcz commented Apr 10, 2026

@mvanhorn all the test failures are related to this change. can you run the unit tests locally please?

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'
ERROR tests/core/test_graphviz_display.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_implementations.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_parallelism.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_persistence.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_state.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/core/test_validation.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integration_tests/test_app.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/serde/test_langchain.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/serde/test_pandas.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/serde/test_pickle.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/serde/test_pydantic.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_hamilton.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_haystack.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_opentelemetry.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_pydantic.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_pydantic_future_annotations.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_burr_ray.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/integrations/test_opentelemetry.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/test_end_to_end.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/tracking/test_common_models.py - AttributeError: module 'types' has no attribute 'UnionType'
ERROR tests/tracking/test_local_tracking_client.py - AttributeError: module 'types' has no attribute 'UnionType'

Otherwise, can you create an example that has:

stream_type=MyModel1 | MyModel2 # works

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>
@github-actions github-actions bot added area/core Application, State, Graph, Actions area/integrations External integrations (LLMs, frameworks) area/typing Mypy, type hints, pydantic labels Apr 11, 2026
@mvanhorn
Copy link
Copy Markdown
Author

@skrawcz good catch - that's a Python 3.9 import-time failure. types.UnionType was added in 3.10, and burr supports >=3.9 per pyproject.toml, so any 3.9 run hit AttributeError at test collection time before any test could run. Pyright was happy because I was running it on 3.10+, which is why I missed it.

Fixed in 6776e86: introduced a _UnionType compatibility alias in burr/core/action.py (types.UnionType on 3.10+, a placeholder sentinel class on 3.9) and replaced every types.UnionType reference in both burr/core/action.py and burr/integrations/pydantic.py. PEP 604 syntax doesn't exist on 3.9 so no real union can reach those call sites anyway - the sentinel path is just there to keep the annotations well-formed at import time.

Ran the full tests/core/{test_action,test_application,test_graph}.py suites in a clean venv: 250 passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Application, State, Graph, Actions area/integrations External integrations (LLMs, frameworks) area/typing Mypy, type hints, pydantic

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming Event type, type hint, should support union type

2 participants