Skip to content

Commit 4c4b78b

Browse files
Merge branch 'master' into fix-enum-with-property-match-exhaustion
2 parents cdbbbb5 + 7f3d7f8 commit 4c4b78b

30 files changed

+1216
-592
lines changed

.github/workflows/test.yml

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ jobs:
7171
tox_extra_args: "-n 4"
7272
test_mypyc: true
7373

74+
- name: Test suit with py313-dev-ubuntu, mypyc-compiled
75+
python: '3.13-dev'
76+
arch: x64
77+
os: ubuntu-latest
78+
toxenv: py
79+
tox_extra_args: "-n 4"
80+
test_mypyc: true
81+
# - name: Test suit with py314-dev-ubuntu
82+
# python: '3.14-dev'
83+
# arch: x64
84+
# os: ubuntu-latest
85+
# toxenv: py
86+
# tox_extra_args: "-n 4"
87+
# allow_failure: true
88+
# test_mypyc: true
89+
7490
- name: mypyc runtime tests with py39-macos
7591
python: '3.9.18'
7692
arch: x64
@@ -119,51 +135,69 @@ jobs:
119135
MYPY_FORCE_TERMINAL_WIDTH: 200
120136
# Pytest
121137
PYTEST_ADDOPTS: --color=yes
138+
122139
steps:
123140
- uses: actions/checkout@v4
124-
- uses: actions/setup-python@v5
125-
with:
126-
python-version: ${{ matrix.python }}
127-
architecture: ${{ matrix.arch }}
141+
128142
- name: Debug build
129143
if: ${{ matrix.debug_build }}
130144
run: |
131145
PYTHONVERSION=${{ matrix.python }}
132146
PYTHONDIR=~/python-debug/python-$PYTHONVERSION
133147
VENV=$PYTHONDIR/env
134148
./misc/build-debug-python.sh $PYTHONVERSION $PYTHONDIR $VENV
149+
# TODO: does this do anything? env vars aren't passed to the next step right
135150
source $VENV/bin/activate
151+
- name: Latest Dev build
152+
if: ${{ endsWith(matrix.python, '-dev') }}
153+
run: |
154+
sudo apt-get update
155+
sudo apt-get install -y --no-install-recommends \
156+
build-essential gdb lcov libbz2-dev libffi-dev libgdbm-dev liblzma-dev libncurses5-dev \
157+
libreadline6-dev libsqlite3-dev libssl-dev lzma lzma-dev tk-dev uuid-dev zlib1g-dev
158+
git clone --depth 1 https://github.com/python/cpython.git /tmp/cpython --branch $( echo ${{ matrix.python }} | sed 's/-dev//' )
159+
cd /tmp/cpython
160+
echo git rev-parse HEAD; git rev-parse HEAD
161+
git show --no-patch
162+
./configure --prefix=/opt/pythondev
163+
make -j$(nproc)
164+
sudo make install
165+
sudo ln -s /opt/pythondev/bin/python3 /opt/pythondev/bin/python
166+
sudo ln -s /opt/pythondev/bin/pip3 /opt/pythondev/bin/pip
167+
echo "/opt/pythondev/bin" >> $GITHUB_PATH
168+
- uses: actions/setup-python@v5
169+
if: ${{ !(matrix.debug_build || endsWith(matrix.python, '-dev')) }}
170+
with:
171+
python-version: ${{ matrix.python }}
172+
architecture: ${{ matrix.arch }}
173+
136174
- name: Install tox
137-
run: pip install setuptools==68.2.2 tox==4.11.0
175+
run: |
176+
echo PATH; echo $PATH
177+
echo which python; which python
178+
echo which pip; which pip
179+
echo python version; python -c 'import sys; print(sys.version)'
180+
echo debug build; python -c 'import sysconfig; print(bool(sysconfig.get_config_var("Py_DEBUG")))'
181+
echo os.cpu_count; python -c 'import os; print(os.cpu_count())'
182+
echo os.sched_getaffinity; python -c 'import os; print(len(getattr(os, "sched_getaffinity", lambda *args: [])(0)))'
183+
pip install setuptools==68.2.2 tox==4.11.0
184+
138185
- name: Compiled with mypyc
139186
if: ${{ matrix.test_mypyc }}
140187
run: |
141188
pip install -r test-requirements.txt
142189
CC=clang MYPYC_OPT_LEVEL=0 MYPY_USE_MYPYC=1 pip install -e .
190+
143191
- name: Setup tox environment
144192
run: |
145-
tox run -e ${{ matrix.toxenv }} --notest
146-
python -c 'import os; print("os.cpu_count", os.cpu_count(), "os.sched_getaffinity", len(getattr(os, "sched_getaffinity", lambda *args: [])(0)))'
193+
tox run -e ${{ matrix.toxenv }} --notes
147194
- name: Test
148195
run: tox run -e ${{ matrix.toxenv }} --skip-pkg-install -- ${{ matrix.tox_extra_args }}
196+
continue-on-error: ${{ matrix.allow_failure == 'true' }}
149197

150-
python-nightly:
151-
runs-on: ubuntu-latest
152-
name: Test suite with Python nightly
153-
steps:
154-
- uses: actions/checkout@v3
155-
- uses: actions/setup-python@v4
156-
with:
157-
python-version: '3.13-dev'
158-
- name: Install tox
159-
run: pip install setuptools==68.2.2 tox==4.11.0
160-
- name: Setup tox environment
161-
run: tox run -e py --notest
162-
- name: Test
163-
run: tox run -e py --skip-pkg-install -- "-n 4"
164-
continue-on-error: true
165-
- name: Mark as a success
166-
run: exit 0
198+
- name: Mark as success (check failures manually)
199+
if: ${{ matrix.allow_failure == 'true' }}
200+
run: exit 0
167201

168202
python_32bits:
169203
runs-on: ubuntu-latest

docs/source/additional_features.rst

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,18 @@ define dataclasses. For example:
4646
UnorderedPoint(1, 2) < UnorderedPoint(3, 4) # Error: Unsupported operand types
4747
4848
Dataclasses can be generic and can be used in any other way a normal
49-
class can be used:
49+
class can be used (Python 3.12 syntax):
5050

5151
.. code-block:: python
5252
5353
from dataclasses import dataclass
54-
from typing import Generic, TypeVar
55-
56-
T = TypeVar('T')
5754
5855
@dataclass
59-
class BoxedData(Generic[T]):
56+
class BoxedData[T]:
6057
data: T
6158
label: str
6259
63-
def unbox(bd: BoxedData[T]) -> T:
60+
def unbox[T](bd: BoxedData[T]) -> T:
6461
...
6562
6663
val = unbox(BoxedData(42, "<important>")) # OK, inferred type is int
@@ -98,17 +95,16 @@ does **not** work:
9895
9996
10097
To have Mypy recognize a wrapper of :py:func:`dataclasses.dataclass <dataclasses.dataclass>`
101-
as a dataclass decorator, consider using the :py:func:`~typing.dataclass_transform` decorator:
98+
as a dataclass decorator, consider using the :py:func:`~typing.dataclass_transform`
99+
decorator (example uses Python 3.12 syntax):
102100

103101
.. code-block:: python
104102
105103
from dataclasses import dataclass, Field
106-
from typing import TypeVar, dataclass_transform
107-
108-
T = TypeVar('T')
104+
from typing import dataclass_transform
109105
110106
@dataclass_transform(field_specifiers=(Field,))
111-
def my_dataclass(cls: type[T]) -> type[T]:
107+
def my_dataclass[T](cls: type[T]) -> type[T]:
112108
...
113109
return dataclass(cls)
114110

docs/source/cheat_sheet_py3.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,20 @@ Decorators
349349
**********
350350

351351
Decorator functions can be expressed via generics. See
352-
:ref:`declaring-decorators` for more details.
352+
:ref:`declaring-decorators` for more details. Example using Python 3.12
353+
syntax:
354+
355+
.. code-block:: python
356+
357+
from typing import Any, Callable
358+
359+
def bare_decorator[F: Callable[..., Any]](func: F) -> F:
360+
...
361+
362+
def decorator_args[F: Callable[..., Any]](url: str) -> Callable[[F], F]:
363+
...
364+
365+
The same example using pre-3.12 syntax:
353366

354367
.. code-block:: python
355368

docs/source/command_line.rst

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ format into the specified directory.
10081008
Enabling incomplete/experimental features
10091009
*****************************************
10101010

1011-
.. option:: --enable-incomplete-feature {PreciseTupleTypes, NewGenericSyntax, InlineTypedDict}
1011+
.. option:: --enable-incomplete-feature {PreciseTupleTypes, InlineTypedDict}
10121012

10131013
Some features may require several mypy releases to implement, for example
10141014
due to their complexity, potential for backwards incompatibility, or
@@ -1055,19 +1055,6 @@ List of currently incomplete/experimental features:
10551055
# Without PreciseTupleTypes: tuple[int, ...]
10561056
# With PreciseTupleTypes: tuple[()] | tuple[int] | tuple[int, int]
10571057
1058-
* ``NewGenericSyntax``: this feature enables support for syntax defined
1059-
by :pep:`695`. For example:
1060-
1061-
.. code-block:: python
1062-
1063-
class Container[T]: # defines a generic class
1064-
content: T
1065-
1066-
def first[T](items: list[T]) -> T: # defines a generic function
1067-
return items[0]
1068-
1069-
type Items[T] = list[tuple[T, T]] # defines a generic type alias
1070-
10711058
* ``InlineTypedDict``: this feature enables non-standard syntax for inline
10721059
:ref:`TypedDicts <typeddict>`, for example:
10731060

docs/source/error_code_list.rst

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -434,15 +434,11 @@ Check type variable values [type-var]
434434
Mypy checks that value of a type variable is compatible with a value
435435
restriction or the upper bound type.
436436

437-
Example:
437+
Example (Python 3.12 syntax):
438438

439439
.. code-block:: python
440440
441-
from typing import TypeVar
442-
443-
T1 = TypeVar('T1', int, float)
444-
445-
def add(x: T1, y: T1) -> T1:
441+
def add[T1: (int, float)](x: T1, y: T1) -> T1:
446442
return x + y
447443
448444
add(4, 5.5) # OK
@@ -783,27 +779,25 @@ Example:
783779
Safe handling of abstract type object types [type-abstract]
784780
-----------------------------------------------------------
785781

786-
Mypy always allows instantiating (calling) type objects typed as ``Type[t]``,
782+
Mypy always allows instantiating (calling) type objects typed as ``type[t]``,
787783
even if it is not known that ``t`` is non-abstract, since it is a common
788784
pattern to create functions that act as object factories (custom constructors).
789785
Therefore, to prevent issues described in the above section, when an abstract
790-
type object is passed where ``Type[t]`` is expected, mypy will give an error.
791-
Example:
786+
type object is passed where ``type[t]`` is expected, mypy will give an error.
787+
Example (Python 3.12 syntax):
792788

793789
.. code-block:: python
794790
795791
from abc import ABCMeta, abstractmethod
796-
from typing import List, Type, TypeVar
797792
798793
class Config(metaclass=ABCMeta):
799794
@abstractmethod
800795
def get_value(self, attr: str) -> str: ...
801796
802-
T = TypeVar("T")
803-
def make_many(typ: Type[T], n: int) -> List[T]:
797+
def make_many[T](typ: type[T], n: int) -> list[T]:
804798
return [typ() for _ in range(n)] # This will raise if typ is abstract
805799
806-
# Error: Only concrete class can be given where "Type[Config]" is expected [type-abstract]
800+
# Error: Only concrete class can be given where "type[Config]" is expected [type-abstract]
807801
make_many(Config, 5)
808802
809803
.. _code-safe-super:

docs/source/final_attrs.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Final names
2525

2626
You can use the ``typing.Final`` qualifier to indicate that
2727
a name or attribute should not be reassigned, redefined, or
28-
overridden. This is often useful for module and class level constants
29-
as a way to prevent unintended modification. Mypy will prevent
28+
overridden. This is often useful for module and class-level
29+
constants to prevent unintended modification. Mypy will prevent
3030
further assignments to final names in type-checked code:
3131

3232
.. code-block:: python
@@ -70,23 +70,23 @@ You can use ``Final`` in one of these forms:
7070
7171
ID: Final[int] = 1
7272
73-
Here mypy will infer type ``int`` for ``ID``.
73+
Here, mypy will infer type ``int`` for ``ID``.
7474

7575
* You can omit the type:
7676

7777
.. code-block:: python
7878
7979
ID: Final = 1
8080
81-
Here mypy will infer type ``Literal[1]`` for ``ID``. Note that unlike for
82-
generic classes this is *not* the same as ``Final[Any]``.
81+
Here, mypy will infer type ``Literal[1]`` for ``ID``. Note that unlike for
82+
generic classes, this is *not* the same as ``Final[Any]``.
8383

84-
* In class bodies and stub files you can omit the right hand side and just write
84+
* In class bodies and stub files, you can omit the right-hand side and just write
8585
``ID: Final[int]``.
8686

8787
* Finally, you can write ``self.id: Final = 1`` (also optionally with
8888
a type in square brackets). This is allowed *only* in
89-
:py:meth:`__init__ <object.__init__>` methods, so that the final instance attribute is
89+
:py:meth:`__init__ <object.__init__>` methods so the final instance attribute is
9090
assigned only once when an instance is created.
9191

9292
Details of using ``Final``
@@ -129,7 +129,7 @@ the scope of a final declaration automatically depending on whether it was
129129
initialized in the class body or in :py:meth:`__init__ <object.__init__>`.
130130

131131
A final attribute can't be overridden by a subclass (even with another
132-
explicit final declaration). Note however that a final attribute can
132+
explicit final declaration). Note, however, that a final attribute can
133133
override a read-only property:
134134

135135
.. code-block:: python
@@ -176,12 +176,12 @@ overriding. You can use the ``typing.final`` decorator for this purpose:
176176
This ``@final`` decorator can be used with instance methods, class methods,
177177
static methods, and properties.
178178

179-
For overloaded methods you should add ``@final`` on the implementation
179+
For overloaded methods, you should add ``@final`` on the implementation
180180
to make it final (or on the first overload in stubs):
181181

182182
.. code-block:: python
183183
184-
from typing import Any, overload
184+
from typing import final, overload
185185
186186
class Base:
187187
@overload
@@ -224,7 +224,7 @@ Here are some situations where using a final class may be useful:
224224

225225
An abstract class that defines at least one abstract method or
226226
property and has ``@final`` decorator will generate an error from
227-
mypy, since those attributes could never be implemented.
227+
mypy since those attributes could never be implemented.
228228

229229
.. code-block:: python
230230

0 commit comments

Comments
 (0)