What’s New In Python 3.12

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.

Sep 10, 2024 - 10:24
 0
What’s New In Python 3.12

What's New in Python 3.12: Release Highlights

Python 3.12, the latest stable release, brings a variety of updates to both the language and its standard library. Key library changes focus on enhancing usability, improving performance, and removing deprecated APIs, with the notable removal of the distutils package. There are also several improvements to filesystem support in modules like os and pathlib.

On the language side, usability improvements include enhanced f-strings, with many previous limitations removed, and better "Did you mean..." suggestions. New syntax for type parameters and the introduction of the type statement make working with generic types and type aliases in static type checking more intuitive.

This article provides an overview of the key updates. For more detailed information, refer to the official documentation, including the Library Reference and Language Reference. For an in-depth understanding of new features, refer to the corresponding PEP (Python Enhancement Proposal), though keep in mind that PEPs may not always reflect the latest updates after a feature has been fully implemented.

New Features
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 generic classes and 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 type aliases using the type statement, which creates an instance of TypeAliasType:

type Point = tuple[float, float]
Type aliases can also be generic:

type Point[T] = tuple[T, T]
The new syntax allows declaring TypeVarTuple and ParamSpec parameters, as well as 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 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 Type parameter lists 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 annotation scope. Annotation scopes behave for the most part like function scopes, but interact differently with enclosing class scopes. In Python 3.13, annotations will also be evaluated in annotation scopes.


What's Your Reaction?

like

dislike

love

funny

angry

sad

wow