def _approx_type_to_bytes()

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