I’m looking for a uniformly nice way to achieve “stringification” of some basic types, including some generics.
For things like union types, the str(...)
works well, but this also gives <class 'float'>
for instance. Using getattr(t, '__name__', str(t))
covers both cases but dict[str].__name__
is dict
, so I basically end up with this. Is there a better way?
def stringify_type(x):
if hasattr(x, '__args__'):
return str(x)
return getattr(x, '__name__', str(x))
type_list = [
float,
dict,
float | int,
dict[str, int],
tuple[int, float],
tuple[tuple[int, int], int],
]
for t in type_list:
print(stringify_type(t))
Expected result:
float
dict
float | int
dict[str, int]
tuple[int, float]
tuple[tuple[int, int], int]
A sidenote, I noticed that an IPython REPL will print these types “nicely” although I don’t quite understand how they did it. (A normal Python REPL will show float as <class 'float'>
)
In [1]: float
Out[1]: float
In [2]: dict
Out[2]: dict
In [3]: float | int
Out[3]: float | int
In [4]: dict[str, int]
Out[4]: dict[str, int]
In [5]: tuple[int, float]
Out[5]: tuple[int, float]