-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
PEP 718: Specify binding, parametrisation and overload interactions #4649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,28 +201,9 @@ The following code snippet would fail at runtime without this change as | |
| Interactions with ``@typing.overload`` | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| Overloaded functions should work much the same as already, since they have no effect on | ||
| the runtime type. This change will lead to more expressiveness with user's able to | ||
| decide and the behaviour/overload can be specified by the developer rather than leaving | ||
| it to ordering of overloads/unions. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # N.B. `class bytes(Sequence[int]): ...` and `Foo` is a non-specified generic type | ||
| @overload | ||
| def seq_first[T: Sequence[int]](x: T) -> T: ... | ||
| @overload | ||
| def seq_first[T: bytes](x: T) -> Foo[T]: ... | ||
|
|
||
| @overload | ||
| def bytes_first[T: bytes](x: T) -> Foo[T]: ... | ||
| @overload | ||
| def bytes_first[T: Sequence[int]](x: T) -> T: ... | ||
|
|
||
| reveal_type(seq_first(b"")) # type is bytes | ||
| reveal_type(bytes_first(b"")) # type is Foo[bytes] | ||
|
|
||
| Explicit specialisation will restrict the set of available overloads | ||
| Overloaded functions should work much the same as they already do, since they do not | ||
| affect the runtime type. Explicit specialisation will restrict the set of available | ||
| overloads. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's worth spelling out in detail how this would work. What I'd expect is that if the function is subscripted, only those overloads are considered for which the subscription may succeed. So if you have an overload |
||
|
|
||
| .. code-block:: python | ||
|
|
||
|
|
@@ -232,33 +213,32 @@ Explicit specialisation will restrict the set of available overloads | |
| def make(x: str, y: str) -> tuple[int, int]: ... | ||
|
|
||
| reveal_type(make[int](1)) # type is int | ||
| reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x:str, y: str)` found, a similar overload exists but explicit specialisation prevented its use | ||
| reveal_type(make[int]("foo", "bar")) # Invalid: no overload for `make[int](x: str, y: str)` found, a similar overload exists but explicit specialisation prevented its use | ||
|
|
||
| Functions Parameterized by ``TypeVarTuple``\ s | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| Currently type checkers disallow the use of multiple ``TypeVarTuple`` \s in it's | ||
| generic parameters, however it is currently valid to have a function as such | ||
| Currently, type checkers disallow the use of multiple ``TypeVarTuple``\s in their | ||
| generic parameters; however, it is currently valid to have a function as such: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| def foo[*T, *U](bar: Bar[*T], baz: Baz[*U]): ... | ||
| def spam[*T](bar: Bar[*T]): ... | ||
|
|
||
| This PEP does not allow similar functions to be subscripted, for the same reason as | ||
| defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. | ||
| This PEP does not allow functions like ``foo`` to be subscripted, for the same reason | ||
| as defined in :pep:`PEP 646<646#multiple-type-variable-tuples-not-allowed>`. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| foo[int, str, bool, complex](Bar(), Baz()) # Invalid: cannot determine which parameters are passed to *T and *U. Explicitly parameterise the instances individually | ||
| spam[int, str, bool, complex](Bar()) # OK | ||
|
|
||
|
|
||
| Binding Rules | ||
| ^^^^^^^^^^^^^ | ||
| Subscriptions on methods (including classmethods, staticmethods etc.) should only have | ||
| access to their function's type parameters and not the enclosing class's. Subscription | ||
| should follow the rules specified in :pep:`PEP 696<696#binding-rules>` methods should | ||
| be bound on attribute access. | ||
| Method subscription (including ``classmethods``, ``staticmethods``, etc.) should only | ||
| have access tos their function's type parameter and not the enclosing class's. | ||
Gobot1234 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Subscription should follow the rules specified in :pep:`PEP 696<696#binding-rules>`; | ||
| methods should bind type parameters on attribute access. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is about the runtime behavior of calling overloaded functions?