8000 Improve code examples in `typing.rst` (GH-105346) · miss-islington/cpython@463b576 · GitHub
[go: up one dir, main page]

Skip to content

Commit 463b576

Browse files
AlexWaygoodmiss-islington
authored andcommitted
Improve code examples in typing.rst (pythonGH-105346)
(cherry picked from commit 81c8132) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
1 parent ca4649a commit 463b576

File tree

1 file changed

+75
-30
lines changed

1 file changed

+75
-30
lines changed

Doc/library/typing.rst

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
:mod:`typing` --- Support for type hints
33
========================================
44

5+
.. testsetup:: *
6+
7+
import typing
8+
from typing import *
9+
510
.. module:: typing
611
:synopsis: Support for type hints (see :pep:`484`).
712

@@ -251,19 +256,22 @@ Callable
251256
Frameworks expecting callback functions of specific signatures might be
252257
type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``.
253258

254-
For example::
259+
For example:
260+
261+
.. testcode::
255262

256263
from collections.abc import Callable
257264

258265
def feeder(get_next_item: Callable[[], str]) -> None:
259-
# Body
266+
... # Body
260267

261268
def async_query(on_success: Callable[[int], None],
262269
on_error: Callable[[int, Exception], None]) -> None:
263-
# Body
270+
... # Body
264271

265272
async def on_update(value: str) -> None:
266-
# Body
273+
... # Body
274+
267275
callback: Callable[[str], Awaitable[None]] = on_update
268276

269277
It is possible to declare the return type of a callable without specifying
@@ -421,11 +429,14 @@ In this case ``MyDict`` has a single parameter, ``T``.
421429

422430
Using a generic class without specifying type parameters assumes
423431
:data:`Any` for each position. In the following example, ``MyIterable`` is
424-
not generic but implicitly inherits from ``Iterable[Any]``::
432+
not generic but implicitly inherits from ``Iterable[Any]``:
433+
434+
.. testcode::
425435

426436
from collections.abc import Iterable
427437

428438
class MyIterable(Iterable): # Same as Iterable[Any]
439+
...
429440

430441
User-defined generic type aliases are also supported. Examples::
431442

@@ -691,9 +702,11 @@ These can be used as types in annotations and do not support ``[]``.
691702
A string created by composing ``LiteralString``-typed objects
692703
is also acceptable as a ``LiteralString``.
693704

694-
Example::
705+
Example:
706+
707+
.. testcode::
695708

696-
def run_query(sql: LiteralString) -> ...
709+
def run_query(sql: LiteralString) -> None:
697710
...
698711

699712
def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
@@ -1586,16 +1599,19 @@ without the dedicated syntax, as documented below.
15861599
def __abs__(self) -> "Array[*Shape]": ...
15871600
def get_shape(self) -> tuple[*Shape]: ...
15881601

1589-
Type variable tuples can be happily combined with normal type variables::
1602+
Type variable tuples can be happily combined with normal type variables:
15901603

1591-
DType = TypeVar('DType')
1604+
.. testcode::
15921605

15931606
class Array[DType, *Shape]: # This is fine
15941607
pass
15951608
15961609
class Array2[*Shape, DType]: # This would also be fine
15971610
pass
15981611
1612+
class Height: ...
1613+
class Width: ...
1614+
15991615
float_array_1d: Array[float, Height] = Array() # Totally fine
16001616
int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too
16011617

@@ -1749,7 +1765,9 @@ without the dedicated syntax, as documented below.
17491765

17501766
The type of type aliases created through the :keyword:`type` statement.
17511767

1752-
Example::
1768+
Example:
1769+
1770+
.. doctest::
17531771

17541772
>>> type Alias = int
17551773
>>> type(Alias)
@@ -1759,7 +1777,9 @@ without the dedicated syntax, as documented below.
17591777

17601778
.. attribute:: __name__
17611779

1762-
The name of the type alias::
1780+
The name of the type alias:
1781+
1782+
.. doctest::
17631783

17641784
>>> type Alias = int
17651785
>>> Alias.__name__
@@ -2148,7 +2168,11 @@ These are not used in annotations. They are building blocks for declaring types.
21482168
group: list[T]
21492169

21502170
To create a generic ``TypedDict`` that is compatible with Python 3.11
2151-
or lower, inherit from :class:`Generic` explicitly::
2171+
or lower, inherit from :class:`Generic` explicitly:
2172+
2173+
.. testcode::
2174+
2175+
T = TypeVar("T")
21522176

21532177
class Group(TypedDict, Generic[T]):
21542178
key: T
@@ -2161,7 +2185,9 @@ These are not used in annotations. They are building blocks for declaring types.
21612185
.. attribute:: __total__
21622186

21632187
``Point2D.__total__`` gives the value of the ``total`` argument.
2164-
Example::
2188+
Example:
2189+
2190+
.. doctest::
21652191

21662192
>>> from typing import TypedDict
21672193
>>> class Point2D(TypedDict): pass
@@ -2191,7 +2217,9 @@ These are not used in annotations. They are building blocks for declaring types.
21912217
non-required keys in the same ``TypedDict`` . This is done by declaring a
21922218
``TypedDict`` with one value for the ``total`` argument and then
21932219
inheriting from it in another ``TypedDict`` with a different value for
2194-
``total``::
2220+
``total``:
2221+
2222+
.. doctest::
21952223

21962224
>>> class Point2D(TypedDict, total=False):
21972225
... x: int
@@ -2850,12 +2878,12 @@ Functions and decorators
28502878
decorated object performs runtime "magic" that
28512879
transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors.
28522880

2853-
Example usage with a decorator function::
2881+
Example usage with a decorator function:
28542882

2855-
T = TypeVar("T")
2883+
.. testcode::
28562884

28572885
@dataclass_transform()
2858-
def create_model(cls: type[T]) -> type[T]:
2886+
def create_model[T](cls: type[T]) -> type[T]:
28592887
...
28602888
return cls
28612889

@@ -2959,7 +2987,9 @@ Functions and decorators
29592987
runtime but should be ignored by a type checker. At runtime, calling
29602988
a ``@overload``-decorated function directly will raise
29612989
:exc:`NotImplementedError`. An example of overload that gives a more
2962-
precise type than can be expressed using a union or a type variable::
2990+
precise type than can be expressed using a union or a type variable:
2991+
2992+
.. testcode::
29632993

29642994
@overload
29652995
def process(response: None) -> None:
@@ -2971,7 +3001,7 @@ Functions and decorators
29713001
def process(response: bytes) -> str:
29723002
...
29733003
def process(response):
2974-
<actual implementation>
3004+
... # actual implementation goes here
29753005

29763006
See :pep:`484` for more details and comparison with other typing semantics.
29773007

@@ -3063,10 +3093,13 @@ Functions and decorators
30633093
This helps prevent bugs that may occur when a base class is changed without
30643094
an equivalent change to a child class.
30653095

3066-
For example::
3096+
For example:
3097+
3098+
.. testcode::
30673099

30683100
class Base:
3069-
def log_status(self)
3101+
def log_status(self) -> None:
3102+
...
30703103

30713104
class Sub(Base):
30723105
@override
@@ -3125,14 +3158,16 @@ Introspection helpers
31253158

31263159
The function recursively replaces all ``Annotated[T, ...]`` with ``T``,
31273160
unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for
3128-
more information). For example::
3161+
more information). For example:
3162+
3163+
.. testcode::
31293164

31303165
class Student(NamedTuple):
31313166
name: Annotated[str, 'some marker']
31323167

3133-
get_type_hints(Student) == {'name': str}
3134-
get_type_hints(Student, include_extras=False) == {'name': str}
3135-
get_type_hints(Student, include_extras=True) == {
3168+
assert get_type_hints(Student) == {'name': str}
3169+
assert get_type_hints(Student, include_extras=False) == {'name': str}
3170+
assert get_type_hints(Student, include_extras=True) == {
31363171
'name': Annotated[str, 'some marker']
31373172
}
31383173

@@ -3159,7 +3194,9 @@ Introspection helpers
31593194
If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`,
31603195
return the underlying :class:`ParamSpec`.
31613196
Return ``None`` for unsupported objects.
3162-
Examples::
3197+
Examples:
3198+
3199+
.. testcode::
31633200

31643201
assert get_origin(str) is None
31653202
assert get_origin(Dict[str, int]) is dict
@@ -3178,7 +3215,9 @@ Introspection helpers
31783215
generic type, the order of ``(Y, Z, ...)`` may be different from the order
31793216
of the original arguments ``[Y, Z, ...]`` due to type caching.
31803217
Return ``()`` for unsupported objects.
3181-
Examples::
3218+
Examples:
3219+
3220+
.. testcode::
31823221

31833222
assert get_args(int) == ()
31843223
assert get_args(Dict[int, str]) == (int, str)
@@ -3190,14 +3229,20 @@ Introspection helpers
31903229

31913230
Check if a type is a :class:`TypedDict`.
31923231

3193-
For example::
3232+
For example:
3233+
3234+
.. testcode::
31943235

31953236
class Film(TypedDict):
31963237
title: str
31973238
year: int
31983239

3199-
is_typeddict(Film) # => True
3200-
is_typeddict(list | str) # => False
3240+
assert is_typeddict(Film)
3241+
assert not is_typeddict(list | str)
3242+
3243+
# TypedDict is a factory for creating typed dicts,
3244+
# not a typed dict itself
3245+
assert not is_typeddict(TypedDict)
32013246

32023247
.. versionadded:: 3.10
32033248

0 commit comments

Comments
 (0)
0