New Typing Features in Python 3.13: ReadOnly, @warnings.deprecated, TypeIs, is_protocol, get_protocol_members, Default TypeVars, NoDefault and Performance Improvements
Python 3.13 adds seven new typing enhancements—including ReadOnly TypedDict fields, a @warnings.deprecated decorator, TypeIs for type narrowing, is_protocol and get_protocol_members utilities, default TypeVar support, the NoDefault sentinel, and import‑time optimizations—each illustrated with code examples.
Python 3.13 introduces seven new typing features that enhance code reliability and developer productivity.
The ReadOnly type can be used inside TypedDict to mark specific fields as immutable, causing type‑checkers to flag assignments to those fields.
<code>from typing import TypedDict, ReadOnly
class Leader(TypedDict):
name: ReadOnly[str]
age: int
author: Leader = {'name': 'Yang Zhou', 'age': 30}
author['age'] = 31 # ok
author['name'] = 'Yang' # Type check error
</code>A simpler syntax also allows ReadOnly directly in the TypedDict definition.
<code>from typing import TypedDict, ReadOnly
Leader = TypedDict('Leader', {'name': ReadOnly[str], 'age': int})
author: Leader = {'name': 'Yang Zhou', 'age': 30}
author['age'] = 31
author['name'] = 'Tim' # Type check error
</code>The new @warnings.deprecated decorator marks functions or classes as deprecated; IDEs such as PyCharm will display a strikethrough warning.
Python 3.13 adds the TypeIs protocol for more precise type narrowing, allowing functions to return True when an argument conforms to a narrower type.
The is_protocol function quickly checks whether an object is a Protocol type.
<code>from typing import is_protocol, Protocol
class PersonProto(Protocol):
name: str
age: int
print(is_protocol(PersonProto)) # True
print(is_protocol(int)) # False
</code>The get_protocol_members function returns a frozenset of member names defined in a protocol.
<code>from typing import Protocol, get_protocol_members
class PersonProto(Protocol):
name: str
age: int
print(get_protocol_members(PersonProto)) # frozenset({'age', 'name'})
</code>Type variables ( TypeVar ), ParamSpec , and TypeVarTuple now support default types via the default= argument, and the has_default() method can query this.
<code>from typing import TypeVar
T = TypeVar('T', default=int)
print(T.has_default()) # True
S = TypeVar('S')
print(S.has_default()) # False
</code>The new NoDefault sentinel indicates that a type variable has no default value.
<code>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
</code>Performance improvements include removing the deprecated typing.io and typing.re namespaces and the keyword‑argument method for creating TypedDict , reducing import time of the typing module by about one‑third.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.