Skip to content

Commit f7f8915

Browse files
committed
Merge remote-tracking branch 'upstream/master' into experiments/typecheck-unreachable
2 parents 102ac11 + 5c87e97 commit f7f8915

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+3347
-1070
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
# the oldest and newest supported Python versions
3434
- name: Test suite with py39-ubuntu, mypyc-compiled
3535
python: '3.9'
36-
os: ubuntu-22.04-arm
36+
os: ubuntu-24.04-arm
3737
toxenv: py
3838
tox_extra_args: "-n 4"
3939
test_mypyc: true
@@ -44,31 +44,31 @@ jobs:
4444
tox_extra_args: "-n 4"
4545
- name: Test suite with py310-ubuntu
4646
python: '3.10'
47-
os: ubuntu-22.04-arm
47+
os: ubuntu-24.04-arm
4848
toxenv: py
4949
tox_extra_args: "-n 4"
5050
- name: Test suite with py311-ubuntu, mypyc-compiled
5151
python: '3.11'
52-
os: ubuntu-22.04-arm
52+
os: ubuntu-24.04-arm
5353
toxenv: py
5454
tox_extra_args: "-n 4"
5555
test_mypyc: true
5656
- name: Test suite with py312-ubuntu, mypyc-compiled
5757
python: '3.12'
58-
os: ubuntu-22.04-arm
58+
os: ubuntu-24.04-arm
5959
toxenv: py
6060
tox_extra_args: "-n 4"
6161
test_mypyc: true
6262
- name: Test suite with py313-ubuntu, mypyc-compiled
6363
python: '3.13'
64-
os: ubuntu-22.04-arm
64+
os: ubuntu-24.04-arm
6565
toxenv: py
6666
tox_extra_args: "-n 4"
6767
test_mypyc: true
6868

6969
# - name: Test suite with py314-dev-ubuntu
7070
# python: '3.14-dev'
71-
# os: ubuntu-22.04-arm
71+
# os: ubuntu-24.04-arm
7272
# toxenv: py
7373
# tox_extra_args: "-n 4"
7474
# allow_failure: true

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ repos:
1111
- id: black
1212
exclude: '^(test-data/)'
1313
- repo: https://github.com/astral-sh/ruff-pre-commit
14-
rev: v0.8.6
14+
rev: v0.9.10
1515
hooks:
1616
- id: ruff
1717
args: [--exit-non-zero-on-fix]

CREDITS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Dropbox core team:
1515

1616
Non-Dropbox core team members:
1717

18-
Ethan Smith
18+
Emma Harper Smith <[email protected]>
1919
Guido van Rossum <[email protected]>
2020
Jelle Zijlstra <[email protected]>
2121
Michael J. Sullivan <[email protected]>

docs/source/metaclasses.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ Mypy supports the lookup of attributes in the metaclass:
3434

3535
.. code-block:: python
3636
37-
from typing import ClassVar, Self
37+
from typing import ClassVar, TypeVar
38+
39+
S = TypeVar("S")
3840
3941
class M(type):
4042
count: ClassVar[int] = 0
4143
42-
def make(cls) -> Self:
44+
def make(cls: type[S]) -> S:
4345
M.count += 1
4446
return cls()
4547
@@ -55,9 +57,6 @@ Mypy supports the lookup of attributes in the metaclass:
5557
b: B = B.make() # metaclasses are inherited
5658
print(B.count + " objects were created") # Error: Unsupported operand types for + ("int" and "str")
5759
58-
.. note::
59-
In Python 3.10 and earlier, ``Self`` is available in ``typing_extensions``.
60-
6160
.. _limitations:
6261

6362
Gotchas and limitations of metaclass support
@@ -88,3 +87,6 @@ so it's better not to combine metaclasses and class hierarchies:
8887
such as ``class A(metaclass=f()): ...``
8988
* Mypy does not and cannot understand arbitrary metaclass code.
9089
* Mypy only recognizes subclasses of :py:class:`type` as potential metaclasses.
90+
* ``Self`` is not allowed as annotation in metaclasses as per `PEP 673`_.
91+
92+
.. _PEP 673: https://peps.python.org/pep-0673/#valid-locations-for-self

docs/source/type_narrowing.rst

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ techniques which are supported by mypy.
88

99
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``.
1010

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:
1120

1221
Type narrowing expressions
1322
--------------------------
@@ -356,40 +365,6 @@ What happens here?
356365

357366
The same will work with ``isinstance(x := a, float)`` as well.
358367

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-
class C:
371-
pass
372-
373-
def f(a: C | None, b: C | None) -> C:
374-
if a is not None or b is not None:
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-
def f(a: C | None, b: C | None) -> C:
387-
if a is not None:
388-
return a
389-
elif b is not None:
390-
return b
391-
return C()
392-
393368

394369
.. _typeis:
395370

@@ -555,3 +530,38 @@ You can use the assignment expression operator ``:=`` with ``TypeIs`` to create
555530
reveal_type(x) # Revealed type is 'float'
556531
# x is narrowed to float in this block
557532
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+
class C:
547+
pass
548+
549+
def f(a: C | None, b: C | None) -> C:
550+
if a is not None or b is not None:
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:
559+
560+
.. code-block:: python
561+
562+
def f(a: C | None, b: C | None) -> C:
563+
if a is not None:
564+
return a
565+
elif b is not None:
566+
return b
567+
return C()

0 commit comments

Comments
 (0)