Skip to content

Support PEP 604 unions (int | str) as output types#1932

Merged
RobinPicard merged 1 commit into
dottxt-ai:mainfrom
sohumt123:fix-pep604-union-types
Jul 20, 2026
Merged

Support PEP 604 unions (int | str) as output types#1932
RobinPicard merged 1 commit into
dottxt-ai:mainfrom
sohumt123:fix-pep604-union-types

Conversation

@sohumt123

Copy link
Copy Markdown
Contributor

What this PR does

Fixes python_types_to_terms rejecting PEP 604 unions as output types. Passing int | str, str | None, or a nested form like list[int | str] currently raises:

TypeError: Type int | str is currently not supported. Please open an issue: https://github.com/dottxt-ai/outlines/issues

while the semantically identical typing.Union[int, str] / Optional[str] work fine.

Root cause

is_union in src/outlines/types/utils.py only checks get_origin(value) is typing.Union. For a PEP 604 union, get_origin(int | str) returns types.UnionType instead, so is_union returns False and python_types_to_terms (src/outlines/types/dsl.py) falls through every handler into the generic unsupported-type error.

Fix

Make is_union also accept types.UnionType instances:

def is_union(value: Any) -> bool:
    return get_origin(value) is Union or isinstance(value, types.UnionType)

No version guard is needed: pyproject.toml requires Python >=3.10 and types.UnionType exists since 3.10. get_args already treats both union forms identically, so _handle_union needs no changes — PEP 604 unions now produce terms string-identical to their typing.Union/Optional equivalents.

Tests

  • tests/types/test_types_utils.py::test_is_union: added is_union(int | str) and is_union(str | None) assertions.
  • tests/types/test_dsl.py::test_dsl_python_types_to_terms: added assertions that int | str, str | None, and list[int | str] dispatch identically to Union[int, str], Optional[str], and list[Union[int, str]].

Both tests fail on main without the one-line fix and pass with it. Full pytest tests/types/ passes: 232 passed.

python_types_to_terms raised "Type int | str is currently not
supported" for PEP 604 unions (int | str, str | None, list[int | str])
while the equivalent typing.Union/Optional forms worked, because
is_union only checked get_origin(value) is typing.Union and
get_origin of a types.UnionType returns types.UnionType.

Make is_union also accept types.UnionType instances. No version guard
is needed since requires-python is >=3.10 and types.UnionType exists
since Python 3.10. get_args already handles both forms identically, so
_handle_union needs no changes.
@github-actions

Copy link
Copy Markdown

📚 Documentation preview: https://dottxt-ai.github.io/outlines/pr-preview/pr-1932/

Preview updates automatically with each commit.

@RobinPicard RobinPicard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good addition, thanks for opening a PR!

@RobinPicard
RobinPicard merged commit 571c5a3 into dottxt-ai:main Jul 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants