You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Accept Ellipsis as last argument for Concatenate. #14656
If changes based on implementation experience and user feedback are made to Standards track PEPs while in the Provisional or (with SC approval) Accepted state, they should be noted in the PEP, such that the PEP accurately describes the implementation at the point where it is marked Final.
Following from this, I think we need to update the PEP. I'm not sure about that "with [steering committee] approval" but PEP 1 is clear that when PEP 621 is put in a Final state, it should accurately reflect implementations (ie allowing ... as the last argument to concatenate).
To update the PEP, it seems we should run it by the author first...
@mrkmndz are you fine with this change? You've probably said something about this before but I can't find it on a cursory look.
PEP 612 is final, so it cannot be amended at this point.
Mypy can deviate from the typing standards if its maintainers decide to do so, but if you want this change to be incorporated into the runtime, typing_extensions, and other type checkers, then it would need to be part of a new PEP, or at the very least a discussion in the python/typing discussion forum so all affected parties can join in to the discussion.
I'll point out that there is already a way to express this concept in the Python type system via a callback protocol. The proposal would offer a (slightly) terser way to express the same thing. It saves one line.
Normally, the bar is quite high for introducing a redundant mechanism. You would need to demonstrate convincingly that this is a common enough pattern to justify it.
@randolf-scholz, mypy is correct in emitting an error in your example because function foo does not accept *args and **kwargs, as indicated by the protocol. I didn't realize that you were expecting that to work.
So you are looking for a way in the type system to represent a function that accepts a single positional argument that is type int followed by some specific number of positional or keyword arguments (and possibly none)? Why is that concept useful in a type system? It's not possible to use such a value in a type-safe manner because there's no way to know what arguments such a call safely accepts.
If this is really what you want, you could use the following:
So you are looking for a way in the type system to represent a function that accepts a single positional argument that is type int followed by some specific number of positional or keyword arguments (and possibly none)? Why is that concept useful in a type system?
The point is to be able to represent partial signatures. This has been requested multiple times, so I think I am not doing something super arcane here. (#5876 (comment), #6077, #8263, python/typing#696)
A common use-case are decorators that add/remove arguments, as described in https://peps.python.org/pep-0612/#motivation. Another use-case is when the remaining arguments are provided at-runtime from a config-file.
It's not possible to use such a value in a type-safe manner because there's no way to know what arguments such a call safely accepts.
Well, if it is known that the first argument of a Callable must be int, but the remainder of the signature is unknown (including even the number of args!), then the type checker can still verify that whenever the function is called the first argument is int. I think this is well in line with the idea of gradual typing.
You will have to specify arbitrary_arg to be a positional-only argument, probably because the first IntFun argument name is ignored thanks to the leading __ (see mypy docs). So the following works:
Sorry for spamming you with comments earlier, it was towards the end of work and I didn't read the issue properly.
Could someone explain what part of PEP 612 forbids this behaviour? I read the pep but can't find any mention that ... cannot be used, just no example that it can be used. I would guess the grammar is what forbids this behaviour, but my understanding is that ... is a valid expression_type and thus should be legal. I am most likely wrong but I don't understand why.
I recommend closing this issue. If someone wants to propose a change to the type system to support ellipsis, the mypy issue tracker isn't the right place for this. It should be discussed in the python/typing discussion forum.
The change to the CPython runtime behaviour and the typing docs was made in the CPython PR python/cpython#30969. That change was made after a lengthy discussion in the CPython issue python/cpython#88954 between the authors of PEP 612 and the typing-module maintainers at CPython.
A PEP is a historical document that represents the consensus of the community at a fixed point in time; where a PEP and the "living documentation" at CPython contradict each other, the living documentation always takes precedence. We don't have a great mechanism right now for tweaking typing specs without writing a whole new PEP, and it's arguable whether or not the discussion in python/cpython#88954 was visible enough to the community as a whole. As a practical matter, however, I think we should view the spec as having been amended following the discussion in python/cpython#88954. Mypy should therefore change its behaviour here, as it is not following the amended spec.
Activity
A5rocks commentedon Feb 12, 2023
Hi! This is a good idea, but I think we have to do some work before adding this to mypy.
PEP 1 states:
Following from this, I think we need to update the PEP. I'm not sure about that "with [steering committee] approval" but PEP 1 is clear that when PEP 621 is put in a Final state, it should accurately reflect implementations (ie allowing
...as the last argument to concatenate).To update the PEP, it seems we should run it by the author first...
@mrkmndz are you fine with this change? You've probably said something about this before but I can't find it on a cursory look.
erictraut commentedon Feb 12, 2023
PEP 612 is final, so it cannot be amended at this point.
Mypy can deviate from the typing standards if its maintainers decide to do so, but if you want this change to be incorporated into the runtime,
typing_extensions, and other type checkers, then it would need to be part of a new PEP, or at the very least a discussion in the python/typing discussion forum so all affected parties can join in to the discussion.I'll point out that there is already a way to express this concept in the Python type system via a callback protocol. The proposal would offer a (slightly) terser way to express the same thing. It saves one line.
versus
Normally, the bar is quite high for introducing a redundant mechanism. You would need to demonstrate convincingly that this is a common enough pattern to justify it.
A5rocks commentedon Feb 12, 2023
Currently its status is Accepted; not Final :^)
This is probably an oversight tbf, but it opens the gate for features like this.
Additionally, this already holds true at runtime (and stdlib docs) which is part of the way there!
randolf-scholz commentedon Feb 13, 2023
@erictraut That would be a good alternative solution. Currently it is unsupported by mypy.
Mypy does support
def __call__(self, *args: Any, **kwargs: Any)(#5876), but it does not work with partial signatures. (#5876 (comment)).Maybe, in view of the addition of
Concatenate, one should reopen #6077?erictraut commentedon Feb 13, 2023
@randolf-scholz, mypy is correct in emitting an error in your example because function
foodoes not accept*argsand**kwargs, as indicated by the protocol. I didn't realize that you were expecting that to work.So you are looking for a way in the type system to represent a function that accepts a single positional argument that is type
intfollowed by some specific number of positional or keyword arguments (and possibly none)? Why is that concept useful in a type system? It's not possible to use such a value in a type-safe manner because there's no way to know what arguments such a call safely accepts.If this is really what you want, you could use the following:
Mypy currently emits an error here, but it's legal according to PEP 612, so it appears to just be a bug.
randolf-scholz commentedon Feb 13, 2023
The point is to be able to represent partial signatures. This has been requested multiple times, so I think I am not doing something super arcane here. (#5876 (comment), #6077, #8263, python/typing#696)
A common use-case are decorators that add/remove arguments, as described in https://peps.python.org/pep-0612/#motivation. Another use-case is when the remaining arguments are provided at-runtime from a config-file.
Well, if it is known that the first argument of a Callable must be int, but the remainder of the signature is unknown (including even the number of args!), then the type checker can still verify that whenever the function is called the first argument is
int. I think this is well in line with the idea of gradual typing.Viicos commentedon Feb 18, 2023
Note that the following definition will not work with the following function:
You will have to specify
arbitrary_argto be a positional-only argument, probably because the firstIntFunargument name is ignored thanks to the leading__(see mypy docs). So the following works:Jacob-Flasheye commentedon May 30, 2023
Sorry for spamming you with comments earlier, it was towards the end of work and I didn't read the issue properly.
Could someone explain what part of PEP 612 forbids this behaviour? I read the pep but can't find any mention that
...cannot be used, just no example that it can be used. I would guess the grammar is what forbids this behaviour, but my understanding is that...is a validexpression_typeand thus should be legal. I am most likely wrong but I don't understand why.erictraut commentedon Aug 14, 2023
@Jacob-Flasheye, it's documented in the section titled Valid use locations. Here's the specific portion:
I recommend closing this issue. If someone wants to propose a change to the type system to support ellipsis, the mypy issue tracker isn't the right place for this. It should be discussed in the python/typing discussion forum.
Viicos commentedon Aug 14, 2023
Should the Python docs be updated then? As they explicitly state (as OP mentioned) that
...is allowed as the last parameter toConcatenatehauntsaninja commentedon Aug 14, 2023
cc @JelleZijlstra do you have context on what the intended state is here?
AlexWaygood commentedon Aug 14, 2023
The change to the CPython runtime behaviour and the typing docs was made in the CPython PR python/cpython#30969. That change was made after a lengthy discussion in the CPython issue python/cpython#88954 between the authors of PEP 612 and the
typing-module maintainers at CPython.A PEP is a historical document that represents the consensus of the community at a fixed point in time; where a PEP and the "living documentation" at CPython contradict each other, the living documentation always takes precedence. We don't have a great mechanism right now for tweaking typing specs without writing a whole new PEP, and it's arguable whether or not the discussion in python/cpython#88954 was visible enough to the community as a whole. As a practical matter, however, I think we should view the spec as having been amended following the discussion in python/cpython#88954. Mypy should therefore change its behaviour here, as it is not following the amended spec.
erictraut commentedon Aug 14, 2023
Ah, thanks for the links to the threads. Since that has now been added to the spec, I'll add it to pyright as well.
Allow Ellipsis in Concatenate; cleanup ParamSpec literals (#15905)
hauntsaninja commentedon Aug 19, 2023
@randolf-scholz is the project you're running into this on open source?