I'm trying to create a function that goes through Union
s and Literal
s and extracts their possible values. I'm trying to do that because I want to create a function that takes in a function and describes that passed-in function's parameters in the json-schema format (see https://platform.openai.com/docs/guides/function-calling).
The code I have right now for the function looks like this:
from typing import get_origin, get_args, Literal, Union
def traverse_union(union_type):
origin = get_origin(union_type)
if origin in {Union, Literal}:
for argument in get_args(union_type):
yield from traverse_union(argument)
return
yield union_type
print(list(traverse_union(int | float | Literal["Hello, world!"])))
# [<class 'int'>, <class 'str'>, 'Hello, world!']
I'm not quite sure how to add type annotations to it though.
Ideally I want the function to take in some kind of type like union_type: UnionType | LiteralType
and return a kind of type like -> Iterable[type | str | int | float | # and more literal types]
but nothing I do seems to be right or even work for that matter.
I think my biggest roadblock is that LiteralType
doesn't actually exist, and type[Literal]
is invalid syntax (Expected type arguments for generic class "Literal"
). From there, I think I can figure it out myself.
Could anybody help me?
After asking around a bit more (thanks @21305238/insync), I've found that what I actually want are TypeExpr
s.
In the discussion for its PEP, TypeExpr
s are described as follows:
They are similar to type[] class objects, but additionally allow matching TypedDicts, generic lists, unions, literals, and other complex types.
When TypeExpr
s land, hopefully in Python 3.14, it'll be perfect for what I want to do, but unfortunately I haven't found a decent workaround for right now.