@@ -1385,22 +1385,23 @@ These can be used as types in annotations. They all support subscription using
13851385 .. versionadded :: 3.9
13861386
13871387
1388- .. data :: TypeGuard
1388+ .. data :: TypeIs
13891389
1390- Special typing construct for marking user-defined type guard functions.
1390+ Special typing construct for marking user-defined type predicate functions.
13911391
1392- ``TypeGuard `` can be used to annotate the return type of a user-defined
1393- type guard function. ``TypeGuard `` only accepts a single type argument.
1394- At runtime, functions marked this way should return a boolean.
1392+ ``TypeIs `` can be used to annotate the return type of a user-defined
1393+ type predicate function. ``TypeIs `` only accepts a single type argument.
1394+ At runtime, functions marked this way should return a boolean and take at
1395+ least one positional argument.
13951396
1396- ``TypeGuard `` aims to benefit *type narrowing * -- a technique used by static
1397+ ``TypeIs `` aims to benefit *type narrowing * -- a technique used by static
13971398 type checkers to determine a more precise type of an expression within a
13981399 program's code flow. Usually type narrowing is done by analyzing
13991400 conditional code flow and applying the narrowing to a block of code. The
1400- conditional expression here is sometimes referred to as a "type guard "::
1401+ conditional expression here is sometimes referred to as a "type predicate "::
14011402
14021403 def is_str(val: str | float):
1403- # "isinstance" type guard
1404+ # "isinstance" type predicate
14041405 if isinstance(val, str):
14051406 # Type of ``val`` is narrowed to ``str``
14061407 ...
@@ -1409,8 +1410,73 @@ These can be used as types in annotations. They all support subscription using
14091410 ...
14101411
14111412 Sometimes it would be convenient to use a user-defined boolean function
1412- as a type guard. Such a function should use ``TypeGuard[...] `` as its
1413- return type to alert static type checkers to this intention.
1413+ as a type predicate. Such a function should use ``TypeIs[...] `` or
1414+ :data: `TypeGuard ` as its return type to alert static type checkers to
1415+ this intention. ``TypeIs `` usually has more intuitive behavior than
1416+ ``TypeGuard ``, but it cannot be used when the input and output types
1417+ are incompatible (e.g., ``list[object] `` to ``list[int] ``) or when the
1418+ function does not return ``True `` for all instances of the narrowed type.
1419+
1420+ Using ``-> TypeIs[NarrowedType] `` tells the static type checker that for a given
1421+ function:
1422+
1423+ 1. The return value is a boolean.
1424+ 2. If the return value is ``True ``, the type of its argument
1425+ is the intersection of the argument's original type and ``NarrowedType ``.
1426+ 3. If the return value is ``False ``, the type of its argument
1427+ is narrowed to exclude ``NarrowedType ``.
1428+
1429+ For example::
1430+
1431+ from typing import assert_type, final, TypeIs
1432+
1433+ class Parent: pass
1434+ class Child(Parent): pass
1435+ @final
1436+ class Unrelated: pass
1437+
1438+ def is_parent(val: object) -> TypeIs[Parent]:
1439+ return isinstance(val, Parent)
1440+
1441+ def run(arg: Child | Unrelated):
1442+ if is_parent(arg):
1443+ # Type of ``arg`` is narrowed to the intersection
1444+ # of ``Parent`` and ``Child``, which is equivalent to
1445+ # ``Child``.
1446+ assert_type(arg, Child)
1447+ else:
1448+ # Type of ``arg`` is narrowed to exclude ``Parent``,
1449+ # so only ``Unrelated`` is left.
1450+ assert_type(arg, Unrelated)
1451+
1452+ The type inside ``TypeIs `` must be consistent with the type of the
1453+ function's argument; if it is not, static type checkers will raise
1454+ an error. An incorrectly written ``TypeIs `` function can lead to
1455+ unsound behavior in the type system; it is the user's responsibility
1456+ to write such functions in a type-safe manner.
1457+
1458+ If a ``TypeIs `` function is a class or instance method, then the type in
1459+ ``TypeIs `` maps to the type of the second parameter after ``cls `` or
1460+ ``self ``.
1461+
1462+ In short, the form ``def foo(arg: TypeA) -> TypeIs[TypeB]: ... ``,
1463+ means that if ``foo(arg) `` returns ``True ``, then ``arg `` is an instance
1464+ of ``TypeB ``, and if it returns ``False ``, it is not an instance of ``TypeB ``.
1465+
1466+ ``TypeIs `` also works with type variables. For more information, see
1467+ :pep: `742 ` (Narrowing types with ``TypeIs ``).
1468+
1469+ .. versionadded :: 3.13
1470+
1471+
1472+ .. data :: TypeGuard
1473+
1474+ Special typing construct for marking user-defined type predicate functions.
1475+
1476+ Type predicate functions are user-defined functions that return whether their
1477+ argument is an instance of a particular type.
1478+ ``TypeGuard `` works similarly to :data: `TypeIs `, but has subtly different
1479+ effects on type checking behavior (see below).
14141480
14151481 Using ``-> TypeGuard `` tells the static type checker that for a given
14161482 function:
@@ -1419,6 +1485,8 @@ These can be used as types in annotations. They all support subscription using
14191485 2. If the return value is ``True ``, the type of its argument
14201486 is the type inside ``TypeGuard ``.
14211487
1488+ ``TypeGuard `` also works with type variables. See :pep: `647 ` for more details.
1489+
14221490 For example::
14231491
14241492 def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
@@ -1433,23 +1501,19 @@ These can be used as types in annotations. They all support subscription using
14331501 # Type of ``val`` remains as ``list[object]``.
14341502 print("Not a list of strings!")
14351503
1436- If ``is_str_list `` is a class or instance method, then the type in
1437- ``TypeGuard `` maps to the type of the second parameter after ``cls `` or
1438- ``self ``.
1439-
1440- In short, the form ``def foo(arg: TypeA) -> TypeGuard[TypeB]: ... ``,
1441- means that if ``foo(arg) `` returns ``True ``, then ``arg `` narrows from
1442- ``TypeA `` to ``TypeB ``.
1443-
1444- .. note ::
1445-
1446- ``TypeB `` need not be a narrower form of ``TypeA `` -- it can even be a
1447- wider form. The main reason is to allow for things like
1448- narrowing ``list[object] `` to ``list[str] `` even though the latter
1449- is not a subtype of the former, since ``list `` is invariant.
1450- The responsibility of writing type-safe type guards is left to the user.
1451-
1452- ``TypeGuard `` also works with type variables. See :pep: `647 ` for more details.
1504+ ``TypeIs `` and ``TypeGuard `` differ in the following ways:
1505+
1506+ * ``TypeIs `` requires the narrowed type to be a subtype of the input type, while
1507+ ``TypeGuard `` does not. The main reason is to allow for things like
1508+ narrowing ``list[object] `` to ``list[str] `` even though the latter
1509+ is not a subtype of the former, since ``list `` is invariant.
1510+ * When a ``TypeGuard `` function returns ``True ``, type checkers narrow the type of the
1511+ variable to exactly the ``TypeGuard `` type. When a ``TypeIs `` function returns ``True ``,
1512+ type checkers can infer a more precise type combining the previously known type of the
1513+ variable with the ``TypeIs `` type. (Technically, this is known as an intersection type.)
1514+ * When a ``TypeGuard `` function returns ``False ``, type checkers cannot narrow the type of
1515+ the variable at all. When a ``TypeIs `` function returns ``False ``, type checkers can narrow
1516+ the type of the variable to exclude the ``TypeIs `` type.
14531517
14541518 .. versionadded :: 3.10
14551519
0 commit comments