Skip to content

Instantly share code, notes, and snippets.

@eltoder
Last active February 5, 2023 04:23
Show Gist options
  • Save eltoder/4035faa041112a988dcf3ab101fb3db1 to your computer and use it in GitHub Desktop.
Save eltoder/4035faa041112a988dcf3ab101fb3db1 to your computer and use it in GitHub Desktop.
Generic typing.NewType
class NewType(_Immutable):
def __init__(self, name, tp, *, _tvars=()):
self.__qualname__ = name
if '.' in name:
name = name.rpartition('.')[-1]
self.__name__ = name
self.__supertype__ = tp
self.__parameters__ = _tvars
def_mod = _caller()
if def_mod != 'typing':
self.__module__ = def_mod
@_tp_cache
def __class_getitem__(cls, params):
# copied from Generic.__class_getitem__
if not isinstance(params, tuple):
params = (params,)
if not params:
raise TypeError(
f"Parameter list to {cls.__qualname__}[...] cannot be empty")
params = tuple(_type_convert(p) for p in params)
if not all(isinstance(p, (TypeVar, ParamSpec)) for p in params):
raise TypeError(
f"Parameters to {cls.__name__}[...] must all be type variables "
f"or parameter specification variables.")
if len(set(params)) != len(params):
raise TypeError(
f"Parameters to {cls.__name__}[...] must all be unique")
return functools.partial(cls, _tvars=params)
@_tp_cache
def __getitem__(self, params):
# copied from Generic.__class_getitem__
if not isinstance(params, tuple):
params = (params,)
params = tuple(_type_convert(p) for p in params)
if any(isinstance(t, ParamSpec) for t in self.__parameters__):
params = _prepare_paramspec_params(self, params)
else:
_check_generic(self, params, len(self.__parameters__))
return _GenericAlias(self, params,
_typevar_types=(TypeVar, ParamSpec),
_paramspec_tvars=True)
def __repr__(self):
return f'{self.__module__}.{self.__qualname__}'
def __call__(self, x):
return x
def __reduce__(self):
return self.__qualname__
def __or__(self, other):
return Union[self, other]
def __ror__(self, other):
return Union[other, self]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment