in chz/tiepin.py [0:0]
def _approx_type_to_bytes(t) -> bytes:
# This tries to keep the resulting value similar with and without __future__ annotations
# As a result, the conversion is approximate. For instance, `builtins.float` and
# `class float: ...` will look the same.
# If you need something more discerning, maybe just use pickle? Although note that pickle
# doesn't work on at least forward refs and non-module level typevars
origin = getattr(t, "__origin__", None)
args = getattr(t, "__args__", ())
if origin is None:
if isinstance(t, type):
# don't use t.__module__, so that we're more likely to preserve hashes
# with and without future annotations
origin_bytes = t.__name__.encode("utf-8")
elif isinstance(t, typing._SpecialForm):
origin_bytes = t._name.encode("utf-8")
elif isinstance(t, typing.TypeVar):
origin_bytes = t.__name__.encode("utf-8")
elif isinstance(t, typing.ForwardRef):
origin_bytes = t.__forward_arg__.encode("utf-8")
elif isinstance(t, str):
origin_bytes = t.encode("utf-8")
elif isinstance(t, (bytes, int, type(...), type(None))):
# enums?
origin_bytes = repr(t).encode("utf-8")
else:
raise TypeError(f"Cannot convert {t} of {type(t)} to bytes")
else:
origin_bytes = _approx_type_to_bytes(origin)
arg_bytes = (b"[" + b",".join(_approx_type_to_bytes(a) for a in args) + b"]") if args else b""
return origin_bytes + arg_bytes