fix: handle generic type aliases in final_output_as - #4793
Conversation
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
I think the except TypeError here is broader than the generic-alias case this change is trying to handle.
isinstance(obj, cls) can invoke a legitimate class's metaclass __instancecheck__, and that implementation is allowed to raise TypeError itself. Before this change that error propagated to the caller. With this blanket catch, the SDK converts it into UserError("final_output_as cannot validate generic type ...") and advises disabling validation, even though cls may be an ordinary class and the failure came from its runtime type semantics rather than from a parameterized generic.
For example, a class using a custom metaclass whose __instancecheck__ raises TypeError would now be misclassified as a generic-type limitation.
Could we identify the unsupported generic/typing form before translating the exception (for example via typing.get_origin() / the supported alias cases), and otherwise preserve the original TypeError? A regression with a custom __instancecheck__ that raises would pin that normal class behaviour is not swallowed while list[str] still gets the new actionable error.
This pull request fixes a bug where calling RunResult.final_output_as(cls, raise_if_incorrect_type=True) with a generic alias (e.g., list[str] or dict[str, int]) crashes with an unhandled internal TypeError.
Because isinstance(obj, list[str]) is not supported in Python, it raises a TypeError which the SDK previously failed to catch, preventing users from receiving a clean, actionable error message. Additionally, it attempted to access cls.name which is invalid on generic aliases.
This PR: