No matter how I try to use it, I get a mypy error. Essentially I have a function like:
def normalize(cls, data, *args, normalizer=None, **kwargs):
if isinstance(cls, GenericAlias) and cls.__origin__ == list:
if not isinstance(data, list):
data = [data]
if normalizer:
return [normalizer(d, *args, **kwargs) for d in data]
obj_cls = cls.__args__[0]
return [obj_cls(d, *args, **kwargs) for d in data]
if normalizer:
return normalizer(data, *args, **kwargs)
return cls(data, *args, **kwargs)
which does the following:
- If
cls
is a class type, simply passdata, *args, **kwargs
tocls
constructor - If
cls
is alist[cls]
, then make suredata
is also a list and pass the elements of it along with*args, **kwargs
tocls
constructor and return the list of those objects - If
normalizer
is passed then use that instead of the constructor
I think I’ve understood the syntax for when normalizer
is passed to be like:
T = TypeVar('T')
P = ParamSpec('P')
Normalizer: TypeAlias = Callable[Concatenate[str, P], T]
@overload
def normalize(cls: type[T], data: str, *args: P.args, # type: ignore
normalizer: Normalizer[P, T],
**kwargs: P.kwargs) -> T:
...
@overload
def normalize(cls: type[list[T]], data: str, *args: P.args,
normalizer: Normalizer[P, T],
**kwargs: P.kwargs) -> list[T]:
...
@overload
def normalize(cls: type[list[T]], data: list[str], *args: P.args,
normalizer: Normalizer[P, T],
**kwargs: P.kwargs) -> list[T]:
But then, how do I combine this with the case where normalizer = None
? How do I get the P.args
to originate from cls
? I was thinking of switching cls
to be the constructor, but that would not solve the case of passing list[cls]
.