@@ -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