7 New Type Features in Python 3.13

The recently released Python 3.13 continues to challenge the limits of efficiency and elegance.

In addition to the much-discussed exciting free-threading model and Just-In-Time compiler, what attracts me are the new improvements in the type system.

Building on the powerful type system introduced in earlier versions, Python 3.13 will introduce seven new type features, expected to enhance code reliability and developer productivity.

In this article, we will try out these exciting new features and explore how they simplify our code and elevate our programming practices to new heights.

All code snippets in this article were tested on the latest release version of Python 3.13.0rc2, which is the final release preview of Python 3.13. The official release of 3.13.0 will be on Tuesday, October 1, 2024.

1. ReadOnly Type

Defining items as read-only

The new ReadOnly type, as the name suggests, is a special type construct used to mark items in a TypedDict as read-only.

from typing import TypedDict, ReadOnly

class Leader(TypedDict):
    name: ReadOnly[str]
    age: int

author: Leader = {'name': 'Yang Zhou', 'age': 30}
author['age'] = 31  # no problem to change
author['name'] = 'Yang'  # Type check error: "name" is read-only

The above code demonstrates its usage. Since we defined the name property as ReadOnly[str], changing its value will trigger a type inconsistency warning in integrated development environments or other static type checking tools.

Note: The “ReadOnly” type can only be used in “TypedDict”.

If you prefer a simpler way to define TypedDict, you can also use the ReadOnly type:

from typing import TypedDict, ReadOnly

Leader = TypedDict("Leader", {"name": ReadOnly[str], "age": int})

author: Leader = {'name': 'Yang Zhou', 'age': 30}
author['age'] = 31  # no problem to change
author['name'] = 'Tim'  # Type check error: "name" is read-only

2. @warnings.deprecated

New decorator to indicate that an object is deprecated

Good software continually improves. This not only means adding new content but also removing outdated content.

However, directly removing functions or classes in the next new version is not user-friendly. We should not do this.

If you strictly follow Python’s official documentation, you will find that the gradual removal of useless objects is the industry standard:

  • Mark relative objects as deprecated, notifying developers in advance which objects will be removed in the future. However, these objects can still be used in the following versions.
  • After several versions, fully informed objects will be completely removed from the latest version of Python.

Python 3.13 provides us with a more convenient way to mark deprecated objects – a new decorator called @warnings.deprecated.

As long as an object is equipped with this decorator, static type checking tools or integrated development environments will remind us when using deprecated objects.

For example, I used a deprecated object in the program below, and the integrated development environment (PyCharm) will remind me with a clear strikethrough:

7 New Type Features in Python 3.13
A PyCharm screenshot to show how the deprecated decorator works

Simple and easy to use, this is another classic Pythonic design!

3. TypeIs

Making type narrowing easier

The new “TypeIs” concept is aimed at “type narrowing”, which is described in its official documentation as a technique used by static type checkers to determine a more precise type of an expression in the program code flow.

While we may not use it often in our application code, we need to understand what it is:

In short, the form def foo(arg: TypeA) -> TypeIs[TypeB]: ... means that if foo(arg) returns True, then arg is an instance of TypeB; if it returns False, then it is not an instance of TypeB.

4.is_protocol

New function to quickly check if a class is of protocol type

The new function is_protocol is a convenient method to check whether an object is of Protocol type.

We just need to import this function from the typing module and use it directly:

from typing import is_protocol, Protocol


class PersonProto(Protocol):
    name: str
    age: int

print(is_protocol(PersonProto))
# True
print(is_protocol(int))
# False

5.get_protocol_members

Function to return the set of protocol members

The new get_protocol_members() function is used to quickly obtain all item names of a Protocol type. It returns a frozenset containing all names:

from typing import Protocol, get_protocol_members


class PersonProto(Protocol):
    name: str
    age: int

print(get_protocol_members(PersonProto))
# frozenset({'age', 'name'})

6. Default Types for TypeVar, ParamSpec, and TypeVarTuple

In Python 3.13, type parameters (typing.TypeVar, typing.ParamSpec, and typing.TypeVarTuple) now support default types. The usage is quite simple.

For example, the code below shows how to easily set a default type for TypeVar:

from typing import TypeVar
T = TypeVar("T", default=int)  # This means that if no type is specified, T is int
print(T.has_default())
# True
S = TypeVar("S")
print(S.has_default())
# False

Python 3.13 also adds the has_default() function to check whether TypeVar has a default type.

7. NoDefault

Indicating no default value

In addition to providing default support for some new type parameters, the typing module also provides a new object called NoDefault to indicate that a type parameter has no default value.

from typing import TypeVar, NoDefault
T = TypeVar("T")
print(T.__default__ is NoDefault)
# True

S = TypeVar("S", default=None)
print(S.__default__ is NoDefault)
# False

As demonstrated in the code above, if no type is set as a default value, then the __default__ attribute of TypeVar will be NoDefault. However, if its default value is None, it still has a default value.

Performance Improvements and Method Removals

The official documentation of Python 3.13 mentions that by removing dependencies on re and contextlib, the import time of the typing module has been reduced by about one third.

We should also note that starting from this new Python version, some typing-related things will be removed:

For reference links, click the bottom left corner to read the original text. Copyright belongs to the original author or platform, used only for academic sharing. If there is any infringement, it will be removed immediately.

Editor / Garvey

Reviewed by / Fan Ruiqiang

Checked by / Fan Ruiqiang

Click below

Follow us

Leave a Comment