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]
```