-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: Python 3.14 compatibility for type hint representation #10528
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
fix: Python 3.14 compatibility for type hint representation #10528
Conversation
In Python 3.14, typing.Optional[T] and typing.Union[X, Y] are internally represented as UnionType (PEP 604), causing type serialization and comparison tests to fail with assertion errors. Changes: - Updated _type_name() in haystack/core/type_utils.py to normalize UnionType instances to Optional[T]/Union[X, Y] format for 2-type/multi-type unions - Updated serialize_type() in haystack/utils/type_serialization.py to convert UnionType to typing.Optional/typing.Union format for consistency - Fixed _is_union_type() to return False for bare Union/UnionType (without parameters) to maintain backward compatibility with validation logic - Updated test expectations in test_type_utils.py and test_type_serialization.py to match normalized type representations - Added sys.version_info checks to skip incompatible bare Union tests on Python 3.14+ - Updated agent tracing tests to expect normalized type format in serialized output This ensures consistent type representation across Python 3.10-3.14 and fixes 29 failing unit tests related to type hints. Fixes deepset-ai#10509
|
@veeceey is attempting to deploy a commit to the deepset Team on Vercel. A member of the Team first needs to authorize it. |
|
This PR is ready for merge, but is currently blocked by a Vercel team authorization requirement. This is an infrastructure/authorization issue and not related to the code quality or testing. The PR will proceed once the Vercel team permission is granted by the maintainers. |
Manual Test ResultsEnvironment
Test 1: _type_name() normalizes UnionType to Optional/Union - PASS# Python 3.14
from haystack.core.type_utils import _type_name
# PEP 604 Optional (T | None) -> Optional[T]
print(_type_name(int | None))
# "Optional[int]" -- PASS (before fix: "int | None")
# PEP 604 Union (T | U) -> Union[T, U]
print(_type_name(int | str))
# "Union[int, str]" -- PASS (before fix: "int | str")
# Multi-type Union
print(_type_name(int | str | float))
# "Union[int, str, float]" -- PASS (before fix: "int | str | float")
# Nested
print(_type_name(list[int | str]))
# "list[Union[int, str]]" -- PASSTest 2: serialize_type() normalizes UnionType consistently - PASS# Python 3.14
from haystack.utils.type_serialization import serialize_type
print(serialize_type(int | None))
# "typing.Optional[int]" -- PASS
print(serialize_type(int | str))
# "typing.Union[int, str]" -- PASS
print(serialize_type(list[int] | None))
# "typing.Optional[list[int]]" -- PASSTest 3: _is_union_type() rejects bare Union/UnionType - PASS# Python 3.14: Union and UnionType are now the same type
import typing
import types
from haystack.utils.type_serialization import _is_union_type
print(_is_union_type(typing.Union)) # False -- PASS (bare Union not a valid type)
print(_is_union_type(types.UnionType)) # False -- PASS (bare UnionType not valid)
print(_is_union_type(typing.Union[int, str]))# True -- PASS (parameterized Union is valid)
print(_is_union_type(int | str)) # True -- PASS (PEP 604 union is valid)
print(_is_union_type(typing.Optional[str])) # True -- PASSTest 4: Cross-version consistency - PASSConsistent output across Python versions. Test 5: Agent tracing spans use normalized types - PASS# Python 3.14 - Agent component input socket type representation
# The tools socket type: list[Tool] | Toolset | None
# Before fix: "list[haystack.tools.tool.Tool] | haystack.tools.toolset.Toolset | None"
# After fix: "typing.Optional[typing.Union[list[haystack.tools.tool.Tool], haystack.tools.toolset.Toolset]]"
# Consistent with how typing.Optional[typing.Union[...]] is representedTest 6: Previously failing tests now pass on Python 3.14 - PASSTest 7: No regression on Python 3.11 - PASSSummaryAll 29 previously failing tests now pass on Python 3.14:
Behavior is now consistent across Python 3.10, 3.11, 3.12, 3.13, and 3.14. |
|
Hey @veeceey thanks for looking into this, but we would like to tackle this internally since it is a sensitive change. Apologies since the original issue was mislabeled as being a good first issue. |
|
No worries
…________________________________
From: Sebastian Husch Lee ***@***.***>
Sent: Sunday, February 8, 2026 9:45:05 PM
To: deepset-ai/haystack ***@***.***>
Cc: Varun Chawla ***@***.***>; Mention ***@***.***>
Subject: Re: [deepset-ai/haystack] fix: Python 3.14 compatibility for type hint representation (PR #10528)
[https://avatars.githubusercontent.com/u/10526848?s=20&v=4]sjrl left a comment (deepset-ai/haystack#10528)<#10528 (comment)>
Hey @veeceey<https://github.com/veeceey> thanks for looking into this, but we would like to tackle this internally since it is a sensitive change. Apologies since the original issue was mislabeled as being a good first issue.
—
Reply to this email directly, view it on GitHub<#10528 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AIE72BHFL26I4T3DKKKFZ534LANGDAVCNFSM6AAAAACULLSMEOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTQNRZGQ3TOMRWGU>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Summary
Fixes Python 3.14 compatibility issues where 29 unit tests were failing due to changes in type hint representation. In Python 3.14,
typing.Optional[T]andtyping.Union[X, Y]are internally represented asUnionType(PEP 604), causing type serialization and comparison tests to fail with assertion errors.Changes
_type_name()to normalizeUnionTypeinstances toOptional[T]/Union[X, Y]formatserialize_type()to convertUnionTypetotyping.Optional/typing.Unionformat_is_union_type()to returnFalsefor bareUnion/UnionType(without parameters)Test Plan
All 29 previously failing tests now pass on Python 3.14:
test/core/test_type_utils.py::test_type_name- Type name representation teststest/utils/test_type_serialization.py::test_output_type_serialization_*- Type serialization teststest/components/agents/test_agent.py::TestAgentTracing::test_agent_tracing_span_*- Agent tracing teststest/components/agents/test_state_class.py::TestIsValidType::test_union_and_optional_types- State validation testsAdditional Context
This fix ensures consistent type representation across Python 3.10-3.14 by normalizing all
UnionTyperepresentations to the traditionaltyping.Optional/typing.Unionformat.Fixes #10509
This PR was created with assistance from Claude Code (Sonnet 4.5).