[PEP 695] Document Python 3.12 type parameter syntax#17816
Conversation
docs/source/generics.rst
Outdated
|
|
||
| There are currently no plans to deprecate the legacy syntax. | ||
| You can freely mix code using the new and old syntax variants, | ||
| even within a single file. |
There was a problem hiding this comment.
PEP 695 does say you can't mix them within the same class (https://peps.python.org/pep-0695/#compatibility-with-traditional-typevars). The error cases are quite obscure though, so I'd be OK with not mentioning that.
| .. code-block:: python | ||
|
|
||
| class Shape: | ||
| def set_scale[T: Shape](self: T, scale: float) -> T: |
There was a problem hiding this comment.
This is the first example using TypeVar bounds, should we introduce the syntax more explicitly?
There was a problem hiding this comment.
Yeah, a good idea. I'll do this in a separate PR, since it might involve moving the upper bound section, which will generate a pretty big diff.
There was a problem hiding this comment.
Here's the PR that changes the order of sections: #17827
| Importantly, this is different from a union type, since combinations | ||
| of ``str`` and ``bytes`` are not accepted: | ||
| No matter which syntax you use, such a type variable is called a type variable | ||
| with a value restriction. Importantly, this is different from a union type, |
There was a problem hiding this comment.
At runtime we call this a TypeVar with "constraints"; maybe we should also switch to this terminology in mypy?
There was a problem hiding this comment.
A good idea. I'll create a follow-up PR (or a documentation issue).
docs/source/generics.rst
Outdated
| There are two syntax variants for defining generic classes in Python. | ||
| Python 3.12 introduced a new dedicated syntax for defining generic |
There was a problem hiding this comment.
It'd be nice to link to the docs — maybe this one https://docs.python.org/3/whatsnew/3.12.html#pep-695-type-parameter-syntax
|
|
||
| class Shape: | ||
| def set_scale[T: Shape](self: T, scale: float) -> T: | ||
| self.scale = scale |
There was a problem hiding this comment.
| class Shape: | |
| def set_scale[T: Shape](self: T, scale: float) -> T: | |
| self.scale = scale | |
| from typing import Self | |
| class Shape: | |
| def set_scale(self, scale: float) -> Self: | |
| self.scale = scale |
Since Self is more explicit and concise, I think it's better to reference that here. We can even get rid of the legacy T = TypeVar("T", bound="Shape") which was necessary before Self (added in 3.11).
There was a problem hiding this comment.
We discuss Self in the next section, so I'm leaving this as is. The idea is that this also explain how the Self type works behind the scenes. It would be reasonable to introduce Self first, but this can proposed in a separate PR, as it's not directly related to PEP 695 support.
| other: "Friend | None" = None | ||
|
|
||
| @classmethod | ||
| def make_pair[T: Friend](cls: type[T]) -> tuple[T, T]: |
There was a problem hiding this comment.
similarly here, we can make it more concise with
| def make_pair[T: Friend](cls: type[T]) -> tuple[T, T]: | |
| def make_pair(cls) -> tuple[Self, Self]: |
There was a problem hiding this comment.
See my comment above.
docs/source/generics.rst
Outdated
|
|
||
| * :py:class:`~typing.List` is an invariant generic type. Naively, one would think | ||
| * ``list`` is an invariant generic type. Naively, one would think | ||
| that it is covariant, like :py:class:`~typing.Sequence` above, but consider this code: |
There was a problem hiding this comment.
typing.Sequence is deprecated since 3.9 in favor of https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Brian Schubert <brianm.schubert@gmail.com>
Finish work started in #17816. Document `type` statement when discussing type aliases. Update some examples to have both old-style and new-style variants. In less common scenarios, examples only use a single syntax variant to reduce verbosity. Also update some examples to generally use more modern features. Closes #17810.
Provide examples using both syntax variants, and give both of the syntax variants similar prominence. It's likely that both syntax variants will continue to be widely used for a long time.
Also adjust terminology (e.g. use 'type parameter' / 'type argument' more consistently), since otherwise some descriptions would be unclear.
I didn't update examples outside the generics chapter. I'll do this in a follow-up PR.
Work on #17810.