You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/type_narrowing.rst
+44-34Lines changed: 44 additions & 34 deletions
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,15 @@ techniques which are supported by mypy.
8
8
9
9
Type narrowing is when you convince a type checker that a broader type is actually more specific, for instance, that an object of type ``Shape`` is actually of the narrower type ``Square``.
10
10
11
+
The following type narrowing techniques are available:
12
+
13
+
- :ref:`type-narrowing-expressions`
14
+
- :ref:`casts`
15
+
- :ref:`type-guards`
16
+
- :ref:`typeis`
17
+
18
+
19
+
.. _type-narrowing-expressions:
11
20
12
21
Type narrowing expressions
13
22
--------------------------
@@ -356,40 +365,6 @@ What happens here?
356
365
357
366
The same will work with ``isinstance(x := a, float)`` as well.
358
367
359
-
Limitations
360
-
-----------
361
-
362
-
Mypy's analysis is limited to individual symbols and it will not track
363
-
relationships between symbols. For example, in the following code
364
-
it's easy to deduce that if :code:`a` is None then :code:`b` must not be,
365
-
therefore :code:`a or b` will always be an instance of :code:`C`,
366
-
but Mypy will not be able to tell that:
367
-
368
-
.. code-block:: python
369
-
370
-
classC:
371
-
pass
372
-
373
-
deff(a: C |None, b: C |None) -> C:
374
-
if a isnotNoneor b isnotNone:
375
-
return a or b # Incompatible return value type (got "C | None", expected "C")
376
-
return C()
377
-
378
-
Tracking these sort of cross-variable conditions in a type checker would add significant complexity
379
-
and performance overhead.
380
-
381
-
You can use an ``assert`` to convince the type checker, override it with a :ref:`cast <casts>`
382
-
or rewrite the function to be slightly more verbose:
383
-
384
-
.. code-block:: python
385
-
386
-
deff(a: C |None, b: C |None) -> C:
387
-
if a isnotNone:
388
-
return a
389
-
elif b isnotNone:
390
-
return b
391
-
return C()
392
-
393
368
394
369
.. _typeis:
395
370
@@ -555,3 +530,38 @@ You can use the assignment expression operator ``:=`` with ``TypeIs`` to create
555
530
reveal_type(x) # Revealed type is 'float'
556
531
# x is narrowed to float in this block
557
532
print(x +1.0)
533
+
534
+
535
+
Limitations
536
+
-----------
537
+
538
+
Mypy's analysis is limited to individual symbols and it will not track
539
+
relationships between symbols. For example, in the following code
540
+
it's easy to deduce that if :code:`a` is None then :code:`b` must not be,
541
+
therefore :code:`a or b` will always be an instance of :code:`C`,
542
+
but Mypy will not be able to tell that:
543
+
544
+
.. code-block:: python
545
+
546
+
classC:
547
+
pass
548
+
549
+
deff(a: C |None, b: C |None) -> C:
550
+
if a isnotNoneor b isnotNone:
551
+
return a or b # Incompatible return value type (got "C | None", expected "C")
552
+
return C()
553
+
554
+
Tracking these sort of cross-variable conditions in a type checker would add significant complexity
555
+
and performance overhead.
556
+
557
+
You can use an ``assert`` to convince the type checker, override it with a :ref:`cast <casts>`
558
+
or rewrite the function to be slightly more verbose:
0 commit comments