This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: typing.Annotated cannot wrap typing.ParamSpec args/kwargs
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, GBeauregard, JelleZijlstra, gvanrossum, kj, miss-islington, serhiy.storchaka, sobolevn
Priority: normal Keywords: patch

Created on 2022-02-04 22:19 by GBeauregard, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 31238 merged GBeauregard, 2022-02-09 22:38
PR 31646 merged miss-islington, 2022-03-03 01:15
PR 31651 merged JelleZijlstra, 2022-03-03 05:00
Messages (9)
msg412546 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-02-04 22:19
Consider the following.
```
import logging
from typing import Annotated, Callable, ParamSpec, TypeVar

T = TypeVar("T")
P = ParamSpec("P")

def add_logging(f: Callable[P, T]) -> Callable[P, T]:
    """A type-safe decorator to add logging to a function."""
    def inner(*args: Annotated[P.args, "meta"], **kwargs: P.kwargs) -> T:
        logging.info(f"{f.__name__} was called")
        return f(*args, **kwargs)
    return inner

@add_logging
def add_two(x: float, y: float) -> float:
    """Add two numbers together."""
    return x + y
```
This raises an error at runtime because P.args/P.kwargs cannot pass the typing._type_check called by Annotated because they are not callable(). This prevents being able to use Annotated on these type annotations.

This can be fixed by adding __call__ methods that raise to typing.ParamSpecArgs and typing.ParamSpecKwargs to match other typeforms.

I can write this patch given agreement
msg412549 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-02-04 23:08
We can also fix this with my proposal in bpo-46644. I'm okay with either fix (that or implementing __call__), or both.
msg412817 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-02-08 07:54
Should it? Annotated wraps types, and P.args/P.kwargs are not types.

If make Annotated accepting P.args/P.kwargs (and possible other non-types, e.g. P), it is a new feature which should be publicly discussed first and documented. I do not thing it requires a PEP.
msg412818 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-02-08 08:09
My general understanding has been that since Annotated exists primarily to allow interoperability between typing and non-typing uses of annotation space, and that this is quite clear in the PEP, most cases where this is not allowed (_especially_ at the top level of the annotation, as in this case) are either a bug or unintentional. We fixed Annotated wrapping Final and ClassVar a couple weeks ago for arguments sorta along these lines after discussion on typing-sig, where the concern of what constitutes a type to wrap was specifically addressed: https://bugs.python.org/issue46491

But, I am not opposed to discussing this case too, or discussing the issue more broadly. Is typing-sig the appropriate place for me to make a thread, or do we wait for comments here? Even if we decide this particular issue is okay to fix, I think you bring up a good point about documenting our decision clearly once and for all so I agree we should do this.
msg412869 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-02-08 20:43
I have made a thread on typing-sig to discuss this: https://mail.python.org/archives/list/typing-sig@python.org/thread/WZ4BCFO4VZ7U4CZ4FSDQNFAKPG2KOGCL/
msg412973 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-02-10 03:19
I wrote a PR that fixes the underlying issue here, but I'm leaving it as a draft while the discussion plays out. I think the stuff currently in the patch should be okay regardless of the discussion decision, because the underlying issue is that P.args and P.kwargs didn't pass typing._type_check, which is needed for reasons unrelated to Annotated (such as if they were stringified and had get_type_hints called on them).

If the result of the discussion is that we need to start supporting limitations on where Annotated is used, I'll add another PR that introduces support for this pattern in whatever locations that are decided it shouldn't be allowed.
msg414394 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-03 01:15
New changeset 75d2d945b4e28ca34506b2d4902367b61a8dff82 by Gregory Beauregard in branch 'main':
bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238)
https://github.com/python/cpython/commit/75d2d945b4e28ca34506b2d4902367b61a8dff82
msg414399 - (view) Author: miss-islington (miss-islington) Date: 2022-03-03 02:26
New changeset 257f5be7f7fad37d0db6c145e534e5b7289d8804 by Miss Islington (bot) in branch '3.10':
bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238)
https://github.com/python/cpython/commit/257f5be7f7fad37d0db6c145e534e5b7289d8804
msg414404 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-03 05:27
New changeset 59e1ce95f1e6ea8a556212b8b10cbc122f1a1711 by Jelle Zijlstra in branch 'main':
bpo-46643: fix NEWS entry (GH-31651)
https://github.com/python/cpython/commit/59e1ce95f1e6ea8a556212b8b10cbc122f1a1711
History
Date User Action Args
2022-04-11 14:59:55adminsetgithub: 90801
2022-03-03 05:27:28JelleZijlstrasetmessages: + msg414404
2022-03-03 05:00:04JelleZijlstrasetpull_requests: + pull_request29770
2022-03-03 02:26:59miss-islingtonsetmessages: + msg414399
2022-03-03 01:22:04JelleZijlstrasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2022-03-03 01:15:15miss-islingtonsetnosy: + miss-islington
pull_requests: + pull_request29766
2022-03-03 01:15:10JelleZijlstrasetmessages: + msg414394
2022-02-10 03:19:47GBeauregardsetmessages: + msg412973
2022-02-09 22:38:01GBeauregardsetkeywords: + patch
stage: patch review
pull_requests: + pull_request29408
2022-02-08 20:43:39GBeauregardsetmessages: + msg412869
2022-02-08 08:09:21GBeauregardsetmessages: + msg412818
2022-02-08 07:54:44serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg412817
2022-02-04 23:08:25GBeauregardsetmessages: + msg412549
2022-02-04 22:19:38GBeauregardsetnosy: + sobolevn
2022-02-04 22:19:25GBeauregardcreate