mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
GH-109190: Copyedit 3.12 What's New: Release highlights (#109770)
This commit is contained in:
parent
62881a79a8
commit
b35f0843fc
1 changed files with 262 additions and 175 deletions
|
@ -59,36 +59,106 @@ Summary -- Release highlights
|
||||||
.. This section singles out the most important changes in Python 3.12.
|
.. This section singles out the most important changes in Python 3.12.
|
||||||
Brevity is key.
|
Brevity is key.
|
||||||
|
|
||||||
|
Python 3.12 is the latest stable release of the Python programming language,
|
||||||
|
with a mix of changes to the language and the standard library.
|
||||||
|
The library changes focus on cleaning up deprecated APIs, usability, and correctness.
|
||||||
|
Of note, the :mod:`!distutils` package has been removed from the standard library.
|
||||||
|
Filesystem support in :mod:`os` and :mod:`pathlib` has seen a number of improvements,
|
||||||
|
and several modules have better performance.
|
||||||
|
|
||||||
|
The language changes focus on usability,
|
||||||
|
as :term:`f-strings <f-string>` have had many limitations removed
|
||||||
|
and 'Did you mean ...' suggestions continue to improve.
|
||||||
|
The new :ref:`type parameter syntax <whatsnew312-pep695>`
|
||||||
|
and :keyword:`type` statement improve ergonomics for using :term:`generic types
|
||||||
|
<generic type>` and :term:`type aliases <type alias>` with static type checkers.
|
||||||
|
|
||||||
|
This article doesn't attempt to provide a complete specification of all new features,
|
||||||
|
but instead gives a convenient overview.
|
||||||
|
For full details, you should refer to the documentation,
|
||||||
|
such as the :ref:`Library Reference <library-index>`
|
||||||
|
and :ref:`Language Reference <reference-index>`.
|
||||||
|
If you want to understand the complete implementation and design rationale for a change,
|
||||||
|
refer to the PEP for a particular new feature;
|
||||||
|
but note that PEPs usually are not kept up-to-date
|
||||||
|
once a feature has been fully implemented.
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
.. PEP-sized items next.
|
.. PEP-sized items next.
|
||||||
|
|
||||||
|
New syntax features:
|
||||||
|
|
||||||
|
* :ref:`PEP 695 <whatsnew312-pep695>`, type parameter syntax and the :keyword:`type` statement
|
||||||
|
|
||||||
New grammar features:
|
New grammar features:
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep701`
|
* :ref:`PEP 701 <whatsnew312-pep701>`, :term:`f-strings <f-string>` in the grammar
|
||||||
|
|
||||||
Interpreter improvements:
|
Interpreter improvements:
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep684`
|
* :ref:`PEP 684 <whatsnew312-pep684>`, a unique per-interpreter :term:`GIL
|
||||||
|
<global interpreter lock>`
|
||||||
|
* :ref:`PEP 669 <whatsnew312-pep669>`, low impact monitoring
|
||||||
|
* `Improved 'Did you mean ...' suggestions <improved error messages_>`_
|
||||||
|
for :exc:`NameError`, :exc:`ImportError`, and :exc:`SyntaxError` exceptions
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep669`
|
Python data model improvements:
|
||||||
|
|
||||||
|
* :ref:`PEP 688 <whatsnew312-pep688>`, using the :ref:`buffer protocol
|
||||||
|
<bufferobjects>` from Python
|
||||||
|
|
||||||
|
Significant improvements in the standard library:
|
||||||
|
|
||||||
|
* The :class:`pathlib.Path` class now supports subclassing
|
||||||
|
* The :mod:`os` module received several improvements for Windows support
|
||||||
|
* A :ref:`command-line interface <sqlite3-cli>` has been added to the
|
||||||
|
:mod:`sqlite3` module
|
||||||
|
* :func:`isinstance` checks against :func:`runtime-checkable protocols
|
||||||
|
<typing.runtime_checkable>` enjoy a speed up of between two and 20 times
|
||||||
|
* The :mod:`asyncio` package has had a number of performance improvements,
|
||||||
|
with some benchmarks showing a 75% speed up.
|
||||||
|
* A :ref:`command-line interface <uuid-cli>` has been added to the
|
||||||
|
:mod:`uuid` module
|
||||||
|
* Due to the changes in :ref:`PEP 701 <whatsnew312-pep701>`,
|
||||||
|
producing tokens via the :mod:`tokenize` module is up to up to 64% faster.
|
||||||
|
|
||||||
|
Security improvements:
|
||||||
|
|
||||||
|
* Replace the builtin :mod:`hashlib` implementations of
|
||||||
|
SHA1, SHA3, SHA2-384, SHA2-512, and MD5 with formally verified code from the
|
||||||
|
`HACL* <https://github.com/hacl-star/hacl-star/>`__ project.
|
||||||
|
These builtin implementations remain as fallbacks that are only used when
|
||||||
|
OpenSSL does not provide them.
|
||||||
|
|
||||||
|
C API improvements:
|
||||||
|
|
||||||
|
* :ref:`PEP 697 <whatsnew312-pep697>`, unstable C API tier
|
||||||
|
* :ref:`PEP 683 <whatsnew312-pep683>`, immortal objects
|
||||||
|
|
||||||
|
CPython implementation improvements:
|
||||||
|
|
||||||
|
* :ref:`PEP 709 <whatsnew312-pep709>`, comprehension inlining
|
||||||
|
* :ref:`CPython support <perf_profiling>` for the Linux ``perf`` profiler
|
||||||
|
* Implement stack overflow protection on supported platforms
|
||||||
|
|
||||||
New typing features:
|
New typing features:
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep688`
|
* :ref:`PEP 692 <whatsnew312-pep692>`, using :class:`~typing.TypedDict` to
|
||||||
|
annotate :term:`**kwargs <argument>`
|
||||||
* :ref:`whatsnew312-pep692`
|
* :ref:`PEP 698 <whatsnew312-pep698>`, :func:`typing.override` decorator
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep695`
|
|
||||||
|
|
||||||
* :ref:`whatsnew312-pep698`
|
|
||||||
|
|
||||||
Important deprecations, removals or restrictions:
|
Important deprecations, removals or restrictions:
|
||||||
|
|
||||||
* :pep:`623`: Remove wstr from Unicode
|
* :pep:`623`: Remove ``wstr`` from Unicode objects in Python's C API,
|
||||||
|
reducing the size of every :class:`str` object by at least 8 bytes.
|
||||||
|
|
||||||
* :pep:`632`: Remove the ``distutils`` package. See
|
* :pep:`632`: Remove the :mod:`!distutils` package.
|
||||||
`the migration guide <https://peps.python.org/pep-0632/#migration-advice>`_
|
See `the migration guide <https://peps.python.org/pep-0632/#migration-advice>`_
|
||||||
for advice on its replacement.
|
for advice replacing the APIs it provided.
|
||||||
|
The third-party `Setuptools <https://setuptools.pypa.io/en/latest/deprecated/distutils-legacy.html>`__
|
||||||
|
package continues to provide :mod:`!distutils`,
|
||||||
|
if you still require it in Python 3.12 and beyond.
|
||||||
|
|
||||||
* :gh:`95299`: Do not pre-install ``setuptools`` in virtual environments
|
* :gh:`95299`: Do not pre-install ``setuptools`` in virtual environments
|
||||||
created with :mod:`venv`.
|
created with :mod:`venv`.
|
||||||
|
@ -97,61 +167,78 @@ Important deprecations, removals or restrictions:
|
||||||
run ``pip install setuptools`` in the :ref:`activated <venv-explanation>`
|
run ``pip install setuptools`` in the :ref:`activated <venv-explanation>`
|
||||||
virtual environment.
|
virtual environment.
|
||||||
|
|
||||||
Improved Error Messages
|
* The :mod:`!asynchat`, :mod:`!asyncore`, and :mod:`!imp` modules have been
|
||||||
=======================
|
removed, along with several :class:`unittest.TestCase`
|
||||||
|
`method aliases <unittest-TestCase-removed-aliases_>`_.
|
||||||
* Modules from the standard library are now potentially suggested as part of
|
|
||||||
the error messages displayed by the interpreter when a :exc:`NameError` is
|
|
||||||
raised to the top level. (Contributed by Pablo Galindo in :gh:`98254`.)
|
|
||||||
|
|
||||||
>>> sys.version_info
|
|
||||||
Traceback (most recent call last):
|
|
||||||
File "<stdin>", line 1, in <module>
|
|
||||||
NameError: name 'sys' is not defined. Did you forget to import 'sys'?
|
|
||||||
|
|
||||||
* Improve the error suggestion for :exc:`NameError` exceptions for instances.
|
|
||||||
Now if a :exc:`NameError` is raised in a method and the instance has an
|
|
||||||
attribute that's exactly equal to the name in the exception, the suggestion
|
|
||||||
will include ``self.<NAME>`` instead of the closest match in the method
|
|
||||||
scope. (Contributed by Pablo Galindo in :gh:`99139`.)
|
|
||||||
|
|
||||||
>>> class A:
|
|
||||||
... def __init__(self):
|
|
||||||
... self.blech = 1
|
|
||||||
...
|
|
||||||
... def foo(self):
|
|
||||||
... somethin = blech
|
|
||||||
...
|
|
||||||
>>> A().foo()
|
|
||||||
Traceback (most recent call last):
|
|
||||||
File "<stdin>", line 1
|
|
||||||
somethin = blech
|
|
||||||
^^^^^
|
|
||||||
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
|
|
||||||
|
|
||||||
* Improve the :exc:`SyntaxError` error message when the user types ``import x
|
|
||||||
from y`` instead of ``from y import x``. (Contributed by Pablo Galindo in :gh:`98931`.)
|
|
||||||
|
|
||||||
>>> import a.y.z from b.y.z
|
|
||||||
Traceback (most recent call last):
|
|
||||||
File "<stdin>", line 1
|
|
||||||
import a.y.z from b.y.z
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
SyntaxError: Did you mean to use 'from ... import ...' instead?
|
|
||||||
|
|
||||||
* :exc:`ImportError` exceptions raised from failed ``from <module> import
|
|
||||||
<name>`` statements now include suggestions for the value of ``<name>`` based on the
|
|
||||||
available names in ``<module>``. (Contributed by Pablo Galindo in :gh:`91058`.)
|
|
||||||
|
|
||||||
>>> from collections import chainmap
|
|
||||||
Traceback (most recent call last):
|
|
||||||
File "<stdin>", line 1, in <module>
|
|
||||||
ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
|
|
||||||
|
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
============
|
============
|
||||||
|
|
||||||
|
.. _whatsnew312-pep695:
|
||||||
|
|
||||||
|
PEP 695: Type Parameter Syntax
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Generic classes and functions under :pep:`484` were declared using a verbose syntax
|
||||||
|
that left the scope of type parameters unclear and required explicit declarations of
|
||||||
|
variance.
|
||||||
|
|
||||||
|
:pep:`695` introduces a new, more compact and explicit way to create
|
||||||
|
:ref:`generic classes <generic-classes>` and :ref:`functions <generic-functions>`::
|
||||||
|
|
||||||
|
def max[T](args: Iterable[T]) -> T:
|
||||||
|
...
|
||||||
|
|
||||||
|
class list[T]:
|
||||||
|
def __getitem__(self, index: int, /) -> T:
|
||||||
|
...
|
||||||
|
|
||||||
|
def append(self, element: T) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
In addition, the PEP introduces a new way to declare :ref:`type aliases <type-aliases>`
|
||||||
|
using the :keyword:`type` statement, which creates an instance of
|
||||||
|
:class:`~typing.TypeAliasType`::
|
||||||
|
|
||||||
|
type Point = tuple[float, float]
|
||||||
|
|
||||||
|
Type aliases can also be :ref:`generic <generic-type-aliases>`::
|
||||||
|
|
||||||
|
type Point[T] = tuple[T, T]
|
||||||
|
|
||||||
|
The new syntax allows declaring :class:`~typing.TypeVarTuple`
|
||||||
|
and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar`
|
||||||
|
parameters with bounds or constraints::
|
||||||
|
|
||||||
|
type IntFunc[**P] = Callable[P, int] # ParamSpec
|
||||||
|
type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple
|
||||||
|
type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound
|
||||||
|
type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints
|
||||||
|
|
||||||
|
The value of type aliases and the bound and constraints of type variables
|
||||||
|
created through this syntax are evaluated only on demand (see
|
||||||
|
:ref:`lazy evaluation <lazy-evaluation>`). This means type aliases are able to
|
||||||
|
refer to other types defined later in the file.
|
||||||
|
|
||||||
|
Type parameters declared through a type parameter list are visible within the
|
||||||
|
scope of the declaration and any nested scopes, but not in the outer scope. For
|
||||||
|
example, they can be used in the type annotations for the methods of a generic
|
||||||
|
class or in the class body. However, they cannot be used in the module scope after
|
||||||
|
the class is defined. See :ref:`type-params` for a detailed description of the
|
||||||
|
runtime semantics of type parameters.
|
||||||
|
|
||||||
|
In order to support these scoping semantics, a new kind of scope is introduced,
|
||||||
|
the :ref:`annotation scope <annotation-scopes>`. Annotation scopes behave for the
|
||||||
|
most part like function scopes, but interact differently with enclosing class scopes.
|
||||||
|
In Python 3.13, :term:`annotations <annotation>` will also be evaluated in
|
||||||
|
annotation scopes.
|
||||||
|
|
||||||
|
See :pep:`695` for more details.
|
||||||
|
|
||||||
|
(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut,
|
||||||
|
and others in :gh:`103764`.)
|
||||||
|
|
||||||
.. _whatsnew312-pep701:
|
.. _whatsnew312-pep701:
|
||||||
|
|
||||||
PEP 701: Syntactic formalization of f-strings
|
PEP 701: Syntactic formalization of f-strings
|
||||||
|
@ -244,52 +331,6 @@ are parsed with the PEG parser, error messages can be more precise and show the
|
||||||
Maureira-Fredes and Marta Gómez in :gh:`102856`. PEP written by Pablo Galindo,
|
Maureira-Fredes and Marta Gómez in :gh:`102856`. PEP written by Pablo Galindo,
|
||||||
Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez).
|
Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez).
|
||||||
|
|
||||||
.. _whatsnew312-pep709:
|
|
||||||
|
|
||||||
PEP 709: Comprehension inlining
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Dictionary, list, and set comprehensions are now inlined, rather than creating a
|
|
||||||
new single-use function object for each execution of the comprehension. This
|
|
||||||
speeds up execution of a comprehension by up to two times.
|
|
||||||
See :pep:`709` for further details.
|
|
||||||
|
|
||||||
Comprehension iteration variables remain isolated and don't overwrite a
|
|
||||||
variable of the same name in the outer scope, nor are they visible after the
|
|
||||||
comprehension. Inlining does result in a few visible behavior changes:
|
|
||||||
|
|
||||||
* There is no longer a separate frame for the comprehension in tracebacks,
|
|
||||||
and tracing/profiling no longer shows the comprehension as a function call.
|
|
||||||
* The :mod:`symtable` module will no longer produce child symbol tables for each
|
|
||||||
comprehension; instead, the comprehension's locals will be included in the
|
|
||||||
parent function's symbol table.
|
|
||||||
* Calling :func:`locals` inside a comprehension now includes variables
|
|
||||||
from outside the comprehension, and no longer includes the synthetic ``.0``
|
|
||||||
variable for the comprehension "argument".
|
|
||||||
* A comprehension iterating directly over ``locals()`` (e.g. ``[k for k in
|
|
||||||
locals()]``) may see "RuntimeError: dictionary changed size during iteration"
|
|
||||||
when run under tracing (e.g. code coverage measurement). This is the same
|
|
||||||
behavior already seen in e.g. ``for k in locals():``. To avoid the error, first
|
|
||||||
create a list of keys to iterate over: ``keys = list(locals()); [k for k in
|
|
||||||
keys]``.
|
|
||||||
|
|
||||||
(Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`.)
|
|
||||||
|
|
||||||
.. _whatsnew312-pep688:
|
|
||||||
|
|
||||||
PEP 688: Making the buffer protocol accessible in Python
|
|
||||||
--------------------------------------------------------
|
|
||||||
|
|
||||||
:pep:`688` introduces a way to use the :ref:`buffer protocol <bufferobjects>`
|
|
||||||
from Python code. Classes that implement the :meth:`~object.__buffer__` method
|
|
||||||
are now usable as buffer types.
|
|
||||||
|
|
||||||
The new :class:`collections.abc.Buffer` ABC provides a standard
|
|
||||||
way to represent buffer objects, for example in type annotations.
|
|
||||||
The new :class:`inspect.BufferFlags` enum represents the flags that
|
|
||||||
can be used to customize buffer creation.
|
|
||||||
(Contributed by Jelle Zijlstra in :gh:`102500`.)
|
|
||||||
|
|
||||||
.. _whatsnew312-pep684:
|
.. _whatsnew312-pep684:
|
||||||
|
|
||||||
PEP 684: A Per-Interpreter GIL
|
PEP 684: A Per-Interpreter GIL
|
||||||
|
@ -333,7 +374,105 @@ This means that you only pay for what you use, providing support
|
||||||
for near-zero overhead debuggers and coverage tools.
|
for near-zero overhead debuggers and coverage tools.
|
||||||
See :mod:`sys.monitoring` for details.
|
See :mod:`sys.monitoring` for details.
|
||||||
|
|
||||||
(Contributed by Mark Shannon in :gh:`103083`.)
|
(Contributed by Mark Shannon in :gh:`103082`.)
|
||||||
|
|
||||||
|
.. _whatsnew312-pep688:
|
||||||
|
|
||||||
|
PEP 688: Making the buffer protocol accessible in Python
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
:pep:`688` introduces a way to use the :ref:`buffer protocol <bufferobjects>`
|
||||||
|
from Python code. Classes that implement the :meth:`~object.__buffer__` method
|
||||||
|
are now usable as buffer types.
|
||||||
|
|
||||||
|
The new :class:`collections.abc.Buffer` ABC provides a standard
|
||||||
|
way to represent buffer objects, for example in type annotations.
|
||||||
|
The new :class:`inspect.BufferFlags` enum represents the flags that
|
||||||
|
can be used to customize buffer creation.
|
||||||
|
(Contributed by Jelle Zijlstra in :gh:`102500`.)
|
||||||
|
|
||||||
|
.. _whatsnew312-pep709:
|
||||||
|
|
||||||
|
PEP 709: Comprehension inlining
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Dictionary, list, and set comprehensions are now inlined, rather than creating a
|
||||||
|
new single-use function object for each execution of the comprehension. This
|
||||||
|
speeds up execution of a comprehension by up to two times.
|
||||||
|
See :pep:`709` for further details.
|
||||||
|
|
||||||
|
Comprehension iteration variables remain isolated and don't overwrite a
|
||||||
|
variable of the same name in the outer scope, nor are they visible after the
|
||||||
|
comprehension. Inlining does result in a few visible behavior changes:
|
||||||
|
|
||||||
|
* There is no longer a separate frame for the comprehension in tracebacks,
|
||||||
|
and tracing/profiling no longer shows the comprehension as a function call.
|
||||||
|
* The :mod:`symtable` module will no longer produce child symbol tables for each
|
||||||
|
comprehension; instead, the comprehension's locals will be included in the
|
||||||
|
parent function's symbol table.
|
||||||
|
* Calling :func:`locals` inside a comprehension now includes variables
|
||||||
|
from outside the comprehension, and no longer includes the synthetic ``.0``
|
||||||
|
variable for the comprehension "argument".
|
||||||
|
* A comprehension iterating directly over ``locals()`` (e.g. ``[k for k in
|
||||||
|
locals()]``) may see "RuntimeError: dictionary changed size during iteration"
|
||||||
|
when run under tracing (e.g. code coverage measurement). This is the same
|
||||||
|
behavior already seen in e.g. ``for k in locals():``. To avoid the error, first
|
||||||
|
create a list of keys to iterate over: ``keys = list(locals()); [k for k in
|
||||||
|
keys]``.
|
||||||
|
|
||||||
|
(Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`.)
|
||||||
|
|
||||||
|
Improved Error Messages
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* Modules from the standard library are now potentially suggested as part of
|
||||||
|
the error messages displayed by the interpreter when a :exc:`NameError` is
|
||||||
|
raised to the top level. (Contributed by Pablo Galindo in :gh:`98254`.)
|
||||||
|
|
||||||
|
>>> sys.version_info
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
NameError: name 'sys' is not defined. Did you forget to import 'sys'?
|
||||||
|
|
||||||
|
* Improve the error suggestion for :exc:`NameError` exceptions for instances.
|
||||||
|
Now if a :exc:`NameError` is raised in a method and the instance has an
|
||||||
|
attribute that's exactly equal to the name in the exception, the suggestion
|
||||||
|
will include ``self.<NAME>`` instead of the closest match in the method
|
||||||
|
scope. (Contributed by Pablo Galindo in :gh:`99139`.)
|
||||||
|
|
||||||
|
>>> class A:
|
||||||
|
... def __init__(self):
|
||||||
|
... self.blech = 1
|
||||||
|
...
|
||||||
|
... def foo(self):
|
||||||
|
... somethin = blech
|
||||||
|
...
|
||||||
|
>>> A().foo()
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1
|
||||||
|
somethin = blech
|
||||||
|
^^^^^
|
||||||
|
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
|
||||||
|
|
||||||
|
* Improve the :exc:`SyntaxError` error message when the user types ``import x
|
||||||
|
from y`` instead of ``from y import x``. (Contributed by Pablo Galindo in :gh:`98931`.)
|
||||||
|
|
||||||
|
>>> import a.y.z from b.y.z
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1
|
||||||
|
import a.y.z from b.y.z
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
SyntaxError: Did you mean to use 'from ... import ...' instead?
|
||||||
|
|
||||||
|
* :exc:`ImportError` exceptions raised from failed ``from <module> import
|
||||||
|
<name>`` statements now include suggestions for the value of ``<name>`` based on the
|
||||||
|
available names in ``<module>``. (Contributed by Pablo Galindo in :gh:`91058`.)
|
||||||
|
|
||||||
|
>>> from collections import chainmap
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
|
||||||
|
|
||||||
|
|
||||||
New Features Related to Type Hints
|
New Features Related to Type Hints
|
||||||
==================================
|
==================================
|
||||||
|
@ -398,70 +537,6 @@ See :pep:`698` for more details.
|
||||||
|
|
||||||
(Contributed by Steven Troxler in :gh:`101561`.)
|
(Contributed by Steven Troxler in :gh:`101561`.)
|
||||||
|
|
||||||
.. _whatsnew312-pep695:
|
|
||||||
|
|
||||||
PEP 695: Type Parameter Syntax
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
Generic classes and functions under :pep:`484` were declared using a verbose syntax
|
|
||||||
that left the scope of type parameters unclear and required explicit declarations of
|
|
||||||
variance.
|
|
||||||
|
|
||||||
:pep:`695` introduces a new, more compact and explicit way to create
|
|
||||||
:ref:`generic classes <generic-classes>` and :ref:`functions <generic-functions>`::
|
|
||||||
|
|
||||||
def max[T](args: Iterable[T]) -> T:
|
|
||||||
...
|
|
||||||
|
|
||||||
class list[T]:
|
|
||||||
def __getitem__(self, index: int, /) -> T:
|
|
||||||
...
|
|
||||||
|
|
||||||
def append(self, element: T) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
In addition, the PEP introduces a new way to declare :ref:`type aliases <type-aliases>`
|
|
||||||
using the :keyword:`type` statement, which creates an instance of
|
|
||||||
:class:`~typing.TypeAliasType`::
|
|
||||||
|
|
||||||
type Point = tuple[float, float]
|
|
||||||
|
|
||||||
Type aliases can also be :ref:`generic <generic-type-aliases>`::
|
|
||||||
|
|
||||||
type Point[T] = tuple[T, T]
|
|
||||||
|
|
||||||
The new syntax allows declaring :class:`~typing.TypeVarTuple`
|
|
||||||
and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar`
|
|
||||||
parameters with bounds or constraints::
|
|
||||||
|
|
||||||
type IntFunc[**P] = Callable[P, int] # ParamSpec
|
|
||||||
type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple
|
|
||||||
type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound
|
|
||||||
type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints
|
|
||||||
|
|
||||||
The value of type aliases and the bound and constraints of type variables
|
|
||||||
created through this syntax are evaluated only on demand (see
|
|
||||||
:ref:`lazy evaluation <lazy-evaluation>`). This means type aliases are able to
|
|
||||||
refer to other types defined later in the file.
|
|
||||||
|
|
||||||
Type parameters declared through a type parameter list are visible within the
|
|
||||||
scope of the declaration and any nested scopes, but not in the outer scope. For
|
|
||||||
example, they can be used in the type annotations for the methods of a generic
|
|
||||||
class or in the class body. However, they cannot be used in the module scope after
|
|
||||||
the class is defined. See :ref:`type-params` for a detailed description of the
|
|
||||||
runtime semantics of type parameters.
|
|
||||||
|
|
||||||
In order to support these scoping semantics, a new kind of scope is introduced,
|
|
||||||
the :ref:`annotation scope <annotation-scopes>`. Annotation scopes behave for the
|
|
||||||
most part like function scopes, but interact differently with enclosing class scopes.
|
|
||||||
In Python 3.13, :term:`annotations <annotation>` will also be evaluated in
|
|
||||||
annotation scopes.
|
|
||||||
|
|
||||||
See :pep:`695` for more details.
|
|
||||||
|
|
||||||
(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut,
|
|
||||||
and others in :gh:`103764`.)
|
|
||||||
|
|
||||||
Other Language Changes
|
Other Language Changes
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
@ -1020,6 +1095,13 @@ CPython bytecode changes
|
||||||
* Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and
|
* Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and
|
||||||
Vladimir Matveev in :gh:`103497`.)
|
Vladimir Matveev in :gh:`103497`.)
|
||||||
|
|
||||||
|
FOR_ITER new behavior is not mentioned
|
||||||
|
The fact that POP_JUMP_IF_* family of instructions are now real instructions is not mentioned
|
||||||
|
YIELD_VALUE need for an argument is not mentioned
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Demos and Tools
|
Demos and Tools
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
@ -1578,6 +1660,8 @@ unittest
|
||||||
|
|
||||||
* Remove many long-deprecated :mod:`unittest` features:
|
* Remove many long-deprecated :mod:`unittest` features:
|
||||||
|
|
||||||
|
.. _unittest-TestCase-removed-aliases:
|
||||||
|
|
||||||
* A number of :class:`~unittest.TestCase` method aliases:
|
* A number of :class:`~unittest.TestCase` method aliases:
|
||||||
|
|
||||||
============================ =============================== ===============
|
============================ =============================== ===============
|
||||||
|
@ -1811,6 +1895,7 @@ C API Changes
|
||||||
New Features
|
New Features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
.. _whatsnew312-pep697:
|
||||||
|
|
||||||
* :pep:`697`: Introduce the :ref:`Unstable C API tier <unstable-c-api>`,
|
* :pep:`697`: Introduce the :ref:`Unstable C API tier <unstable-c-api>`,
|
||||||
intended for low-level tools like debuggers and JIT compilers.
|
intended for low-level tools like debuggers and JIT compilers.
|
||||||
|
@ -1938,6 +2023,8 @@ New Features
|
||||||
to replace the legacy-api :c:func:`!PyErr_Display`. (Contributed by
|
to replace the legacy-api :c:func:`!PyErr_Display`. (Contributed by
|
||||||
Irit Katriel in :gh:`102755`).
|
Irit Katriel in :gh:`102755`).
|
||||||
|
|
||||||
|
.. _whatsnew312-pep683:
|
||||||
|
|
||||||
* :pep:`683`: Introduce *Immortal Objects*, which allows objects
|
* :pep:`683`: Introduce *Immortal Objects*, which allows objects
|
||||||
to bypass reference counts, and related changes to the C-API:
|
to bypass reference counts, and related changes to the C-API:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue