Skip to content

Commit 2da9969

Browse files
committed
Narrow union disambiguation to str, preserving the structural-ambiguity guard
The general exact-type tie-break removed the guard that makes structurally- identical union variants (e.g. Union[A, B] dataclasses, Union[int, UnsignedInt]) raise on to_literal -- they would then be indistinguishable on read-back. Keep that guard; only a bare string prefers the str variant over an enum-by-value. Signed-off-by: 1fanwang <1fannnw@gmail.com>
1 parent ef75c06 commit 2da9969

2 files changed

Lines changed: 5 additions & 6 deletions

File tree

‎flytekit/core/type_engine.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,9 +2097,9 @@ async def async_to_literal(
20972097
raise TypeTransformerFailedError(f"Cannot convert from {python_val} to {python_type}")
20982098

20992099
if len(matches) > 1:
2100-
# More than one variant matched. Prefer the one whose type is exactly the value's type -- e.g. for
2101-
# Union[str, Color] and "red", both str and Color (which accepts a matching string) match, but str wins.
2102-
exact = [m for m in matches if type(python_val) is m[0]]
2100+
# A bare string matches both `str` and an enum whose values include it -- prefer `str` (the exact type).
2101+
# Every other multi-variant match stays ambiguous: structurally-identical variants are a read-back hazard.
2102+
exact = [m for m in matches if m[0] is str] if type(python_val) is str else []
21032103
if len(exact) != 1:
21042104
raise TypeError(
21052105
"Ambiguous choice of variant for union type.\n"

‎tests/flytekit/unit/core/test_type_engine.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,9 +2047,8 @@ def to_python_value(self, ctx: FlyteContext, lv: Literal, expected_python_type:
20472047
assert union_type_tags_unique(lt)
20482048

20492049
ctx = FlyteContextManager.current_context()
2050-
# int and UnsignedInt both accept 3, but int is the value's exact type, so it wins without ambiguity.
2051-
lv = TypeEngine.to_literal(ctx, 3, pt, lt)
2052-
assert lv.scalar.union.stored_type.structure.tag == "int"
2050+
with pytest.raises(TypeError, match="Ambiguous choice of variant for union type"):
2051+
TypeEngine.to_literal(ctx, 3, pt, lt)
20532052

20542053
del TypeEngine._REGISTRY[UnsignedInt]
20552054

0 commit comments

Comments
 (0)