Skip to content

Commit ee09374

Browse files
committed
gh-149995: Update typing.py docstrings
Some of these docstrings read as if they were written when typing.py was first written, and things have evolved since then. A few motivations: - Call protocols protocols instead of ABCs. They are also ABCs, but the fact they are protocols is more relevant to typing. - Avoid recommending direct use of .__annotations__ and steer users to annotationlib instead. - For TypedDict, mention NotRequired before total=False since it is more general and probably more frequently useful. - For overloads, mention runtime use first instead of stub use. I think early on there was talk of allowing overload only in stubs, but it is now heavily used at runtime too and that's more likely to be relevant to users.
1 parent 0ed497a commit ee09374

1 file changed

Lines changed: 53 additions & 53 deletions

File tree

Lib/typing.py

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Generic, Protocol, and internal machinery to support generic aliases.
66
All subscripted types like X[int], Union[int, str] are generic aliases.
77
* Various "special forms" that have unique meanings in type annotations:
8-
NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others.
8+
Any, Never, ClassVar, Self, Concatenate, Unpack, and others.
99
* Classes whose instances can be type arguments to generic classes and functions:
1010
TypeVar, ParamSpec, TypeVarTuple.
1111
* Public helper functions: get_type_hints, overload, cast, final, and others.
@@ -591,12 +591,12 @@ def __repr__(self):
591591
class Any(metaclass=_AnyMeta):
592592
"""Special type indicating an unconstrained type.
593593
594-
- Any is compatible with every type.
595-
- Any assumed to have all methods.
596-
- All values assumed to be instances of Any.
594+
- Any is assignable to every type.
595+
- Any assumed to have all methods and attributes.
596+
- All values are assignable to Any.
597597
598598
Note that all the above statements are true from the point of view of
599-
static type checkers. At runtime, Any should not be used with instance
599+
static type checkers. At runtime, Any cannot be used with instance
600600
checks.
601601
"""
602602

@@ -715,7 +715,7 @@ class Starship:
715715
716716
ClassVar accepts only types and cannot be further subscribed.
717717
718-
Note that ClassVar is not a class itself, and should not
718+
Note that ClassVar is not a class itself, and cannot
719719
be used with isinstance() or issubclass().
720720
"""
721721
item = _type_check(parameters, f'{self} accepts only single type.', allow_special_forms=True)
@@ -745,7 +745,7 @@ class FastConnector(Connection):
745745

746746
@_SpecialForm
747747
def Optional(self, parameters):
748-
"""Optional[X] is equivalent to Union[X, None]."""
748+
"""Optional[X] is equivalent to X | None."""
749749
arg = _type_check(parameters, f"{self} requires a single type.")
750750
return Union[arg, type(None)]
751751

@@ -788,7 +788,7 @@ def open_helper(file: str, mode: MODE) -> str:
788788
def TypeAlias(self, parameters):
789789
"""Special form for marking type aliases.
790790
791-
Use TypeAlias to indicate that an assignment should
791+
TypeAlias can be used to indicate that an assignment should
792792
be recognized as a proper type alias definition by type
793793
checkers.
794794
@@ -1796,7 +1796,7 @@ class Movie(TypedDict):
17961796
def foo(**kwargs: Unpack[Movie]): ...
17971797
17981798
Note that there is only some runtime checking of this operator. Not
1799-
everything the runtime allows may be accepted by static type checkers.
1799+
everything the runtime allows is accepted by static type checkers.
18001800
18011801
For more information, see PEPs 646 and 692.
18021802
"""
@@ -2307,7 +2307,7 @@ def runtime_checkable(cls):
23072307
Such protocol can be used with isinstance() and issubclass().
23082308
Raise TypeError if applied to a non-protocol class.
23092309
This allows a simple-minded structural check very similar to
2310-
one trick ponies in collections.abc such as Iterable.
2310+
one-trick ponies in collections.abc such as Iterable.
23112311
23122312
For example::
23132313
@@ -2377,8 +2377,8 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False,
23772377
*, format=None):
23782378
"""Return type hints for an object.
23792379
2380-
This is often the same as obj.__annotations__, but it handles
2381-
forward references encoded as string literals and recursively replaces all
2380+
This is often the same as obj.__annotations__ and annotationlib.get_annotations(obj),
2381+
but it handles forward references encoded as string literals and recursively replaces all
23822382
'Annotated[T, ...]' with 'T' (unless 'include_extras=True').
23832383
23842384
The argument may be a module, class, method, or function. The annotations
@@ -2590,7 +2590,7 @@ def get_args(tp):
25902590

25912591

25922592
def is_typeddict(tp):
2593-
"""Check if an annotation is a TypedDict class.
2593+
"""Check if an object is a TypedDict class.
25942594
25952595
For example::
25962596
@@ -2688,29 +2688,29 @@ def overload(func):
26882688
"""Decorator for overloaded functions/methods.
26892689
26902690
In a stub file, place two or more stub definitions for the same
2691-
function in a row, each decorated with @overload.
2692-
2693-
For example::
2691+
function in a row, each decorated with @overload, followed
2692+
with an implementation. The implementation should *not*
2693+
be decorated with @overload::
26942694
26952695
@overload
26962696
def utf8(value: None) -> None: ...
26972697
@overload
26982698
def utf8(value: bytes) -> bytes: ...
26992699
@overload
27002700
def utf8(value: str) -> bytes: ...
2701+
def utf8(value):
2702+
... # implementation goes here
27012703
2702-
In a non-stub file (i.e. a regular .py file), do the same but
2703-
follow it with an implementation. The implementation should *not*
2704-
be decorated with @overload::
2704+
In a stub file or in a Protocol definition, the implementation
2705+
should be omitted::
27052706
27062707
@overload
27072708
def utf8(value: None) -> None: ...
27082709
@overload
27092710
def utf8(value: bytes) -> bytes: ...
27102711
@overload
27112712
def utf8(value: str) -> bytes: ...
2712-
def utf8(value):
2713-
... # implementation goes here
2713+
27142714
27152715
The overloads for a function can be retrieved at runtime using the
27162716
get_overloads() function.
@@ -2746,7 +2746,7 @@ def final(f):
27462746
"""Decorator to indicate final methods and final classes.
27472747
27482748
Use this decorator to indicate to type checkers that the decorated
2749-
method cannot be overridden, and decorated class cannot be subclassed.
2749+
method cannot be overridden, and the decorated class cannot be subclassed.
27502750
27512751
For example::
27522752
@@ -2899,7 +2899,7 @@ class TeamUser(User): ...
28992899
And a function that takes a class argument that's a subclass of
29002900
User and returns an instance of the corresponding class::
29012901
2902-
def new_user[U](user_class: Type[U]) -> U:
2902+
def new_user[U](user_class: type[U]) -> U:
29032903
user = user_class()
29042904
# (Here we could write the user object to a database)
29052905
return user
@@ -2912,7 +2912,7 @@ def new_user[U](user_class: Type[U]) -> U:
29122912

29132913
@runtime_checkable
29142914
class SupportsInt(Protocol):
2915-
"""An ABC with one abstract method __int__."""
2915+
"""A protocol with one abstract method __int__."""
29162916

29172917
__slots__ = ()
29182918

@@ -2923,7 +2923,7 @@ def __int__(self) -> int:
29232923

29242924
@runtime_checkable
29252925
class SupportsFloat(Protocol):
2926-
"""An ABC with one abstract method __float__."""
2926+
"""A protocol with one abstract method __float__."""
29272927

29282928
__slots__ = ()
29292929

@@ -2934,7 +2934,7 @@ def __float__(self) -> float:
29342934

29352935
@runtime_checkable
29362936
class SupportsComplex(Protocol):
2937-
"""An ABC with one abstract method __complex__."""
2937+
"""A protocol with one abstract method __complex__."""
29382938

29392939
__slots__ = ()
29402940

@@ -2945,7 +2945,7 @@ def __complex__(self) -> complex:
29452945

29462946
@runtime_checkable
29472947
class SupportsBytes(Protocol):
2948-
"""An ABC with one abstract method __bytes__."""
2948+
"""A protocol with one abstract method __bytes__."""
29492949

29502950
__slots__ = ()
29512951

@@ -2956,7 +2956,7 @@ def __bytes__(self) -> bytes:
29562956

29572957
@runtime_checkable
29582958
class SupportsIndex(Protocol):
2959-
"""An ABC with one abstract method __index__."""
2959+
"""A protocol with one abstract method __index__."""
29602960

29612961
__slots__ = ()
29622962

@@ -2967,7 +2967,7 @@ def __index__(self) -> int:
29672967

29682968
@runtime_checkable
29692969
class SupportsAbs[T](Protocol):
2970-
"""An ABC with one abstract method __abs__ that is covariant in its return type."""
2970+
"""A protocol with one abstract method __abs__ that is covariant in its return type."""
29712971

29722972
__slots__ = ()
29732973

@@ -2978,7 +2978,7 @@ def __abs__(self) -> T:
29782978

29792979
@runtime_checkable
29802980
class SupportsRound[T](Protocol):
2981-
"""An ABC with one abstract method __round__ that is covariant in its return type."""
2981+
"""A protocol with one abstract method __round__ that is covariant in its return type."""
29822982

29832983
__slots__ = ()
29842984

@@ -3095,7 +3095,7 @@ def annotate(format):
30953095

30963096

30973097
def NamedTuple(typename, fields, /):
3098-
"""Typed version of namedtuple.
3098+
"""Typed version of collections.namedtuple.
30993099
31003100
Usage::
31013101
@@ -3107,8 +3107,8 @@ class Employee(NamedTuple):
31073107
31083108
Employee = collections.namedtuple('Employee', ['name', 'id'])
31093109
3110-
The resulting class has an extra __annotations__ attribute, giving a
3111-
dict that maps field names to types. (The field names are also in
3110+
The types for each field name can be retrieved by calling
3111+
annotationlib.get_annotations(Employee). (The field names are also in
31123112
the _fields attribute, which is part of the namedtuple API.)
31133113
An alternative equivalent functional syntax is also accepted::
31143114
@@ -3161,7 +3161,7 @@ def __new__(cls, name, bases, ns, total=True, closed=None,
31613161
31623162
This method is called when TypedDict is subclassed,
31633163
or when TypedDict is instantiated. This way
3164-
TypedDict supports all three syntax forms described in its docstring.
3164+
TypedDict classes can be created through both class-based and functional syntax.
31653165
Subclasses and instances of TypedDict return actual dictionaries.
31663166
"""
31673167
for base in bases:
@@ -3315,14 +3315,22 @@ def TypedDict(typename, fields, /, *, total=True, closed=None,
33153315
>>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
33163316
True
33173317
3318-
The type info can be accessed via the Point2D.__annotations__ dict, and
3319-
the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
3318+
The type info can be accessed by calling annotationlib.get_annotations(Point2D), and
3319+
via the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
33203320
TypedDict supports an additional equivalent form::
33213321
33223322
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
33233323
33243324
By default, all keys must be present in a TypedDict. It is possible
3325-
to override this by specifying totality::
3325+
to override this by using the NotRequired and Required special forms::
3326+
3327+
class Point2D(TypedDict):
3328+
x: int # the "x" key must always be present (Required is the default)
3329+
y: NotRequired[int] # the "y" key can be omitted
3330+
3331+
This means that a Point2D TypedDict can have the "y" key omitted, but the "x" key must be present.
3332+
Items are required by default, so the Required special form is not necessary in this example.
3333+
In addition, the total argument to the TypedDict function can be used to make all items not required::
33263334
33273335
class Point2D(TypedDict, total=False):
33283336
x: int
@@ -3331,16 +3339,8 @@ class Point2D(TypedDict, total=False):
33313339
This means that a Point2D TypedDict can have any of the keys omitted. A type
33323340
checker is only expected to support a literal False or True as the value of
33333341
the total argument. True is the default, and makes all items defined in the
3334-
class body be required.
3335-
3336-
The Required and NotRequired special forms can also be used to mark
3337-
individual keys as being required or not required::
3338-
3339-
class Point2D(TypedDict):
3340-
x: int # the "x" key must always be present (Required is the default)
3341-
y: NotRequired[int] # the "y" key can be omitted
3342-
3343-
See PEP 655 for more details on Required and NotRequired.
3342+
class body be required. The Required special form can be used to mark individual
3343+
keys as required in a total=False TypedDict.
33443344
33453345
The ReadOnly special form can be used
33463346
to mark individual keys as immutable for type checkers::
@@ -3374,7 +3374,7 @@ class Point3D(Point2D):
33743374
by default, and it may not be used with the closed argument at the same
33753375
time.
33763376
3377-
See PEP 728 for more information about closed and extra_items.
3377+
See PEPs 589, 655, 705, and 728 for more information.
33783378
"""
33793379
ns = {'__annotations__': dict(fields)}
33803380
module = _caller()
@@ -3533,8 +3533,8 @@ class IO(Generic[AnyStr]):
35333533
classes (text vs. binary, read vs. write vs. read/write,
35343534
append-only, unbuffered). The TextIO and BinaryIO subclasses
35353535
below capture the distinctions between text vs. binary, which is
3536-
pervasive in the interface; however we currently do not offer a
3537-
way to track the other distinctions in the type system.
3536+
pervasive in the interface. For more precise types, define a custom
3537+
Protocol.
35383538
"""
35393539

35403540
__slots__ = ()
@@ -3624,7 +3624,7 @@ def __exit__(self, type, value, traceback, /) -> None:
36243624

36253625

36263626
class BinaryIO(IO[bytes]):
3627-
"""Typed version of the return of open() in binary mode."""
3627+
"""Typed approximation of the return of open() in binary mode."""
36283628

36293629
__slots__ = ()
36303630

@@ -3638,7 +3638,7 @@ def __enter__(self) -> BinaryIO:
36383638

36393639

36403640
class TextIO(IO[str]):
3641-
"""Typed version of the return of open() in text mode."""
3641+
"""Typed approximation of the return of open() in text mode."""
36423642

36433643
__slots__ = ()
36443644

@@ -3705,7 +3705,7 @@ def dataclass_transform(
37053705
field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (),
37063706
**kwargs: Any,
37073707
) -> _IdentityCallable:
3708-
"""Decorator to mark an object as providing dataclass-like behaviour.
3708+
"""Decorator to mark an object as providing dataclass-like behavior.
37093709
37103710
The decorator can be applied to a function, class, or metaclass.
37113711

0 commit comments

Comments
 (0)