Fix FunctionInputOutputTypeChecker crash on list[int] | None annotations - #1736
Merged
Merged
Conversation
4 of 7 tasks
htypes.check_instance looked up `__origin__` to detect unions, but PEP 604 unions (types.UnionType) have none on Python 3.10-3.13, so the function fell through to isinstance(obj, list[int] | None), which raises "TypeError: isinstance() argument 2 cannot be a parameterized generic". With FunctionInputOutputTypeChecker enabled, any node annotated with such a union (input or return) crashed the run even when the value was correct. Check each member of a types.UnionType, as is already done for typing.Union. Generated-by: Claude Code (Claude Opus 5.5) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
skrawcz
force-pushed
the
fix/check-instance-pep604-union
branch
from
September 26, 2026 18:57
25e5184 to
6e4ec8f
Compare
skrawcz
approved these changes
Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With
lifecycle.FunctionInputOutputTypeCheckerenabled, any node whose input or return annotation is a PEP 604 union with a parameterized member, such aslist[int] | None, crashes the run. This happens even when the value is correct.htypes.check_instancedetects unions throughtype_.__origin__ is Union. Atypes.UnionType(theX | Yform) has no__origin__on Python 3.10-3.13, so it skips the union branch and reachesisinstance(obj, type_).isinstanceraises when a union member is a parameterized generic.Optional[list[int]]works because it is atyping.Union, so only the|spelling crashes. On 3.14,X | YandUnion[X, Y]are the same type, so it no longer crashes there.Changes
hamilton/htypes.py: incheck_instance, check each member of atypes.UnionTyperecursively, the same waytyping.Unionis already handled.tests/test_type_utils.py:test_check_instance_with_pep604_union_of_generics. It covers matching and non-matching values forlist[int] | Noneanddict[str, int] | list[int].tests/lifecycle/test_default.py: two driver tests withFunctionInputOutputTypeChecker. The first useslist[int] | Noneas a node's return type and as a downstream input, for both a list andNone. The second checks that a wrong result (["not", "ints"]) is still rejected with the adapter's ownTypeError.How I tested this
main(4f4c48fe, Python 3.12): all 3 new tests fail withTypeError: isinstance() argument 2 cannot be a parameterized generic.pytest tests/test_type_utils.py tests/test_hamilton_driver.py tests/test_end_to_end.py tests/test_async_driver.py tests/test_graph.py tests/function_modifiers tests/test_function_modifiers.py tests/lifecycle tests/test_base.py tests/execution tests/io tests/caching tests/test_default_data_quality.py tests/test_node.py tests/test_ad_hoc_utils.py tests/test_parallel_graceful.pyon Python 3.12: 1185 passed, 42 failed. The same 42 fail onmainwithout this change (1182 passed): thetest_graph.pydisplay tests needgraphviz, and thetest_fingerprinting.pyhash tests fail in my local env. None of them touch this code.ruff checkandruff format --check(0.16.9, the pre-commit pin) are clean.git diff --checkis clean.Notes
A companion PR, #1735, fixes
htypes.check_input_typerejectingdictinputs forMapping[...]parameters. The two PRs touch different functions and do not conflict.Checklist
AI disclosure (per the ASF Generative Tooling guidance): this change was written with an AI coding tool (Claude Code, Claude Opus 5.5) working through the
breken-aiaccount. The tool found the bug, wrote the fix and the tests, and wrote this description. The commit carries aGenerated-by:trailer. The diff is a small original change to existing Hamilton code and includes no third-party material. The red/green runs above are real and can be re-run from the diff. If you would rather not take AI-assisted contributions here, say so and I will close this.🤖 Generated with Claude Code