Skip to content

Commit b1084ab

Browse files
sobolevnIvan Levkivskyi
authored and
Ivan Levkivskyi
committed
Adds docs about := and TypeGuard (#11161)
Closes #11075
1 parent 5ed919c commit b1084ab

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

docs/source/type_narrowing.rst

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ Type narrowing is contextual. For example, based on the condition, mypy will nar
3737
# Back outside of the ``if`` statement, the type isn't narrowed:
3838
reveal_type(arg) # Revealed type: "builtins.object"
3939
40-
Mypy understands the implications `return` or exception raising can have for what type an object could be:
40+
Mypy understands the implications ``return`` or exception raising can have
41+
for what type an object could be:
4142

4243
.. code-block:: python
4344
@@ -295,3 +296,35 @@ TypeGuards as methods
295296
296297
def is_child(instance: Parent) -> TypeGuard[Child]:
297298
return isinstance(instance, Child)
299+
300+
Assignment expressions as TypeGuards
301+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
302+
303+
Sometimes you might need to create a new variable and narrow it
304+
to some specific type at the same time.
305+
This can be achieved by using ``TypeGuard`` together
306+
with `:= operator <https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions>`_.
307+
308+
.. code-block:: python
309+
310+
from typing import TypeGuard # use `typing_extensions` for `python<3.10`
311+
312+
def is_float(a: object) -> TypeGuard[float]:
313+
return isinstance(a, float)
314+
315+
def main(a: object) -> None:
316+
if is_float(x := a):
317+
reveal_type(x) # N: Revealed type is 'builtins.float'
318+
reveal_type(a) # N: Revealed type is 'builtins.object'
319+
reveal_type(x) # N: Revealed type is 'builtins.object'
320+
reveal_type(a) # N: Revealed type is 'builtins.object'
321+
322+
What happens here?
323+
324+
1. We create a new variable ``x`` and assign a value of ``a`` to it
325+
2. We run ``is_float()`` type guard on ``x``
326+
3. It narrows ``x`` to be ``float`` in the ``if`` context and does not touch ``a``
327+
328+
.. note::
329+
330+
The same will work with ``isinstance(x := a, float)`` as well.

0 commit comments

Comments
 (0)