Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gh-91491: What's New in 3.11 section for typing PEPs
Other aspects of typing aren't covered yet; I'll do that in a
separate PR.
  • Loading branch information
JelleZijlstra committed Apr 20, 2022
commit f0d92e249f3b255759614db91010a45d1e724432
130 changes: 128 additions & 2 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ New syntax features:

New typing features:

* :pep:`673`: ``Self`` Type.
(Contributed by James Hilton-Balfe and Pradeep Kumar in :issue:`30924`.)
* :pep:`646`: Variadic generics.
* :pep:`655`: Marking individual TypedDict items as required or potentially-missing.
Comment thread
JelleZijlstra marked this conversation as resolved.
* :pep:`673`: ``Self`` type.
* :pep:`675`: Arbitrary literal string type.


New Features
============
Expand Down Expand Up @@ -167,6 +170,129 @@ default traceback. See :pep:`678` for more details. (Contributed by
Irit Katriel in :issue:`45607`.)


.. _new-feat-related-type-hints:

New Features Related to Type Hints
==================================

This section covers major changes affecting :pep:`484` type hints and
the :mod:`typing` module.

PEP 646: Variadic generics
--------------------------

:pep:`484` introduced ``TypeVar``, enabling creation of generics parameterised
with a single type. The new :data:`TypeVarTuple` enables parameterisation
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
with an *arbitrary* number of types - that is, a *variadic* type variable,
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
enabling *variadic* generics. This enables a wide variety of use cases.
In particular, it allows the type of array-like structures
in numerical computing libraries such as NumPy and TensorFlow to be
parameterised with the array *shape*, enabling static type checkers
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
to catch shape-related bugs in code that uses these libraries.

See :pep:`646` for more details.

(Contributed by Matthew Rahtz in :issue:`43224`, with contributions by
Serhiy Storchaka and Jelle Zijlstra. PEP written by Mark Mendoza, Matthew
Rahtz, Pradeep Kumar, and Vincent Siles.)
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated

PEP 655: Marking individual ``TypedDict`` items as required or non-required
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
---------------------------------------------------------------------------

:data:`typing.Required` and :data:`typing.NotRequired` provide a
straightforward way to mark whether individual items in a
:data:`TypedDict` must be present. Previously, this was only possible
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
using inheritance.

As before, fields are required by default, unless the ``total=False``
parameter is set.
For example, the following specifies a dictionary with one required and
one non-required key::
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated

class Movie(TypedDict):
title: str
year: NotRequired[int]

m1: Movie = {"title": "Black Panther", "year": 2018} # ok
m2: Movie = {"title": "Star Wars"} # ok (year is not required)
m3: Movie = {"year": 2022} # error (missing required field title)

The following definition is equivalent::

class Movie(TypedDict, total=False):
title: Required[str]
year: int

See :pep:`655` for more details.

(Contributed by David Foster and Jelle Zijlstra in :issue:`47087`. PEP
written by David Foster.)

PEP 673: ``Self`` type
----------------------

The new :data:`typing.Self` annotation provides a simple and intuitive
way to annotate methods that returnan instance of their class. This
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
behaves the same as the :data:`typing.TypeVar`-based approach specified
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
in :pep:`484` but is more concise and easier to follow.

Common use cases include alternative constructors provided as classmethods
and :meth:`~object.__enter__` methods that return ``self``::

class MyLock:
def __enter__(self) -> Self:
self.lock()
return self

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One important use case is that calling this method on a subclass object will return the subclass type, not this class type. e.g.,

class ChildLock(MyLock): ...

ChildLock().__enter__()  # type is `ChildLock`, not `MyLock`.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that should be mentioned here? It's meant to be a brief summary after all.

...

class MyInt:
@classmethod
def fromhex(cls, s: str) -> Self:
return cls(int(s, 16))

...

See :pep:`673` for more details.

(Contributed by James Hilton-Balfe in :issue:`46534`. PEP written by
Pradeep Kumar and James Hilton-Balfe.)
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated

PEP 675: Arbitrary literal string type
--------------------------------------

The new :data:`typing.LiteralString` annotation may be used to indicate
that a function parameter can be of any literal string type. This allows
a function to accept arbitrary literal string types, as well as strings
created from other literal strings. This allows static type checkers to
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
enforce that sensitive functions, such as those that execute SQL
statements or shell commands, are called only with static arguments,
which provides some protection against injection attacks.
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated

For example, a SQL query function could be annotated as follows::

def run_query(sql: LiteralString) -> ...
...

def caller(
arbitrary_string: str,
query_string: LiteralString,
table_name: LiteralString,
) -> None:
run_query("SELECT * FROM students") # ok
run_query(query_string) # ok
run_query("SELECT * FROM " + table_name) # ok
run_query(arbitrary_string) # type checker error
run_query( # type checker error
f"SELECT * FROM students WHERE name = {arbitrary_string}"
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated
)

See :pep:`675` for more details.

(Contributed by Jelle Zijlstra in :issue:`47088`. PEP written by Pradeep
Kumar and Graham Bleaney.)
Comment thread
JelleZijlstra marked this conversation as resolved.
Outdated


Other Language Changes
======================

Expand Down