MCPcopy Index your code
hub / github.com/python/cpython / TypeGuard

Function TypeGuard

Lib/typing.py:851–903  ·  view source on GitHub ↗

Special typing construct for marking user-defined type predicate functions. ``TypeGuard`` can be used to annotate the return type of a user-defined type predicate function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean.

(self, parameters)

Source from the content-addressed store, hash-verified

849
850@_SpecialForm
851def TypeGuard(self, parameters):
852 """Special typing construct for marking user-defined type predicate functions.
853
854 ``TypeGuard`` can be used to annotate the return type of a user-defined
855 type predicate function. ``TypeGuard`` only accepts a single type argument.
856 At runtime, functions marked this way should return a boolean.
857
858 ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
859 type checkers to determine a more precise type of an expression within a
860 program's code flow. Usually type narrowing is done by analyzing
861 conditional code flow and applying the narrowing to a block of code. The
862 conditional expression here is sometimes referred to as a "type predicate".
863
864 Sometimes it would be convenient to use a user-defined boolean function
865 as a type predicate. Such a function should use ``TypeGuard[...]`` or
866 ``TypeIs[...]`` as its return type to alert static type checkers to
867 this intention. ``TypeGuard`` should be used over ``TypeIs`` when narrowing
868 from an incompatible type (e.g., ``list[object]`` to ``list[int]``) or when
869 the function does not return ``True`` for all instances of the narrowed type.
870
871 Using ``-> TypeGuard[NarrowedType]`` tells the static type checker that
872 for a given function:
873
874 1. The return value is a boolean.
875 2. If the return value is ``True``, the type of its argument
876 is ``NarrowedType``.
877
878 For example::
879
880 def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
881 '''Determines whether all objects in the list are strings'''
882 return all(isinstance(x, str) for x in val)
883
884 def func1(val: list[object]):
885 if is_str_list(val):
886 # Type of ``val`` is narrowed to ``list[str]``.
887 print(" ".join(val))
888 else:
889 # Type of ``val`` remains as ``list[object]``.
890 print("Not a list of strings!")
891
892 Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
893 form of ``TypeA`` (it can even be a wider form) and this may lead to
894 type-unsafe results. The main reason is to allow for things like
895 narrowing ``list[object]`` to ``list[str]`` even though the latter is not
896 a subtype of the former, since ``list`` is invariant. The responsibility of
897 writing type-safe type predicates is left to the user.
898
899 ``TypeGuard`` also works with type variables. For more information, see
900 PEP 647 (User-Defined Type Guards).
901 """
902 item = _type_check(parameters, f'{self} accepts only single type.')
903 return _GenericAlias(self, (item,))
904
905
906@_TypeFormForm

Callers 1

test_cannot_initMethod · 0.90

Calls 2

_type_checkFunction · 0.85
_GenericAliasClass · 0.85

Tested by 1

test_cannot_initMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…