-
Notifications
You must be signed in to change notification settings - Fork 287
-
I'm trying to add type hints to https://github.com/open-telemetry/opentelemetry-python-contrib, and in a lot of places we have a pattern that is something like:
def to_type_check(fn, args, kwargs): return fn(*args, **kwargs)
How do I add type hints to this?
Some playgrounds:
Also, I can't change how the code looks like, I can only add type hints. It's an old code source.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 5 replies
-
Unfortunately ParamSpec only works with exactly *args, **kwargs as inputs, so this isn't possible. If you restrict to only accepting positional arguments variadic generics would work. If these functions are only being used in the implementation and externally it just looks like the original function, perhaps you could just pretend the functions are aliases to users, and leave the implementation untypeable.
Beta Was this translation helpful? Give feedback.
All reactions
-
Unfortunately ParamSpec only works with exactly *args, **kwargs as inputs, so this isn't possible. If you restrict to only accepting positional arguments variadic generics would work.
I'm aware of those points, but I'm asking for advice on what I would need to do to here to have it typed correctly.
If the answer is: "it's not possible". Then it seems like something is missing to Python itself, and I'd like to see if we can do something about it.
Beta Was this translation helpful? Give feedback.
All reactions
-
That is the answer, the most accurate way to type this currently would be something along the lines of:
def to_type_check[T](fn: Callable[..., T], args: Sequence[Any], kwargs: Mapping[str, Any]) -> T: return fn(*args, **kwargs)
ParamSpec is indeed a very incomplete solution and yet it took a year for support in mypy to land and in pytype there's still no full support to this day. So this should give you an idea how complex the feature is to implement, even with all the simplifications to keep the scope small. I don't think anybody would object to making ParamSpec more powerful, but it will take a tremendous time investment of figuring out all the important details and corner cases, so you end up with something that's still actually sound and useful.
TypeVarTuple is slightly more powerful, so the same function could be typed accurately for passing only positional arguments:
def to_type_check[T, *Ts](fn: Callable[*Ts, T], args: tuple[*Ts]) -> T: return fn(*args)
Beta Was this translation helpful? Give feedback.
All reactions
-
def to_type_check[T](fn: Callable[..., T], args: Sequence[Any], **kwargs: Mapping[str, Any]) -> T: return fn(*args, **kwargs)
This is wrong. Are the ** an oversight?
That is the answer, [...]
I tried to be very objective in this discussion and not point to any direction. Again, if the answer is: "it's not possible". Then it seems like something is missing to Python itself, and I'd like to see if we can do something about it.
I don't think "but it will take a tremendous time investment of figuring out all the important details and corner cases" is a blocker here. I'm asking how can I proceed here, if that's the case.
Beta Was this translation helpful? Give feedback.
All reactions
-
Indeed, the ** were added accidentally, I edited the post.
I also don't think it's a blocker, I'm just warning you that it will not be easy. Many people have asked for extended ParamSpec features, but nobody has actually invested the time yet to write up a detailed proposal, ideally with a proof-of-concept implementation in one of the type checkers.
Beta Was this translation helpful? Give feedback.
All reactions
-
As far how to proceed, here's the general process for proposing larger changes to typing spec (this will almost certainly require a PEP, the process for typing PEPs is no different from other PEPs and is documented elsewhere): https://github.com/python/typing-council?tab=readme-ov-file#decisions
Beta Was this translation helpful? Give feedback.