Skip to content

Commit b343be3

Browse files
authored
Add pinned dev version of ast_serialize to CI (#20836)
This PR makes parallel tests run with native parser (I temporarily skip parallel tests on Windows). This will: * Prevent accidental regressions in native parser * Allow me to start working on making parallel checking native-parser-only. In parallel we can gradually re-enable remaining ~50 skipped tests. (FWIW I don't think there is anything essential there, mostly different error messages, and some rare edge cases.)
1 parent f3e2a97 commit b343be3

24 files changed

Lines changed: 102 additions & 70 deletions

.github/workflows/test.yml

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,20 @@ jobs:
106106
os: ubuntu-24.04-arm
107107
toxenv: py
108108
tox_extra_args: "-n 4 --mypy-num-workers=4 mypy/test/testcheck.py"
109+
dev_ast_serialize: true
109110
- name: Parallel tests with py314-ubuntu, mypyc-compiled
110111
python: '3.14'
111112
os: ubuntu-24.04-arm
112113
toxenv: py
113114
tox_extra_args: "-n 4 --mypy-num-workers=4 mypy/test/testcheck.py"
114115
test_mypyc: true
115-
- name: Parallel tests with py314-windows-64, interpreted
116-
python: '3.14'
117-
os: windows-latest
118-
toxenv: py
119-
tox_extra_args: "-n 2 --mypy-num-workers=2 mypy/test/testcheck.py -k 'incremental or modules or classes'"
116+
dev_ast_serialize: true
117+
# Skip Windows tests until we publish ast_serialize wheels on PyPI.
118+
# - name: Parallel tests with py314-windows-64, interpreted
119+
# python: '3.14'
120+
# os: windows-latest
121+
# toxenv: py
122+
# tox_extra_args: "-n 2 --mypy-num-workers=2 mypy/test/testcheck.py -k 'incremental or modules or classes'"
120123

121124
- name: Type check our own code (py310-ubuntu)
122125
python: '3.10'
@@ -139,6 +142,7 @@ jobs:
139142
timeout-minutes: 60
140143
env:
141144
TOX_SKIP_MISSING_INTERPRETERS: False
145+
VIRTUALENV_SYSTEM_SITE_PACKAGES: ${{ matrix.dev_ast_serialize && 1 || 0 }}
142146
# Rich (pip) -- Disable color for windows + pytest
143147
FORCE_COLOR: ${{ !(startsWith(matrix.os, 'windows-') && startsWith(matrix.toxenv, 'py')) && 1 || 0 }}
144148
# Tox
@@ -213,6 +217,30 @@ jobs:
213217
pip install -r test-requirements.txt
214218
CC=clang MYPYC_OPT_LEVEL=0 MYPY_USE_MYPYC=1 pip install -e .
215219
220+
# To speed-up process until ast_serialize is on PyPI.
221+
- name: Checkout pinned ast_serialize
222+
if: ${{ matrix.dev_ast_serialize }}
223+
uses: actions/checkout@v4
224+
with:
225+
persist-credentials: false
226+
repository: mypyc/ast_serialize
227+
ref: da5a16cf268dbec63ed6b2e6b715470576e2d1a6
228+
path: ast_serialize
229+
230+
- if: ${{ matrix.dev_ast_serialize }}
231+
uses: PyO3/maturin-action@v1
232+
with:
233+
target: aarch64
234+
args: --release --out dist
235+
working-directory: ast_serialize
236+
237+
- if: ${{ matrix.dev_ast_serialize }}
238+
run: |
239+
pip install ast_serialize/dist/ast_serialize-0.1.0-cp39-abi3-manylinux_2_34_aarch64.whl
240+
echo 'no way' > test_ast_serialize.py
241+
python3 -c 'import ast_serialize; print(ast_serialize.parse("test_ast_serialize.py")[1])'
242+
rm test_ast_serialize.py
243+
216244
- name: Setup tox environment
217245
run: |
218246
tox run -e ${{ matrix.toxenv }} --notest

mypy/message_registry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ def with_additional_msg(self, info: str) -> ErrorMessage:
303303
"Condition can't be inferred, unable to merge overloads"
304304
)
305305
TYPE_IGNORE_WITH_ERRCODE_ON_MODULE: Final = ErrorMessage(
306-
"type ignore with error code is not supported for modules; "
306+
"Type ignore with error code is not supported for modules; "
307307
'use `# mypy: disable-error-code="{}"`',
308308
codes.SYNTAX,
309309
)

mypy/test/testcheck.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,16 @@ def run_case_once(
141141

142142
if options.num_workers:
143143
options.fixed_format_cache = True
144+
options.native_parser = True
144145
if testcase.output_files:
145146
raise pytest.skip("Reports are not supported in parallel mode")
146147
# Note: do not use this unless really needed!
147148
if testcase.name.endswith("_no_parallel"):
148149
raise pytest.skip("Test not supported in parallel mode yet")
149150

151+
if options.native_parser and testcase.name.endswith("_no_native_parse"):
152+
raise pytest.skip("Test not supported by native parser yet")
153+
150154
# Enable some options automatically based on test file name.
151155
if "columns" in testcase.file:
152156
options.show_column_numbers = True

test-data/unit/check-annotated.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ x: Annotated[int, THESE, ARE, IGNORED, FOR, NOW]
1717
reveal_type(x) # N: Revealed type is "builtins.int"
1818
[builtins fixtures/tuple.pyi]
1919

20-
[case testAnnotated3]
20+
[case testAnnotated3_no_native_parse]
2121
from typing_extensions import Annotated
2222
x: Annotated[int, -+~12.3, "som"[e], more(anno+a+ions, that=[are]), (b"ignored",), 4, N.O.W, ...]
2323
reveal_type(x) # N: Revealed type is "builtins.int"

test-data/unit/check-async-await.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ async def f() -> None:
192192
[builtins fixtures/async_await.pyi]
193193
[typing fixtures/typing-async.pyi]
194194

195-
[case testAsyncForTypeComments]
195+
[case testAsyncForTypeComments_no_native_parse]
196196

197197
from typing import AsyncIterator, Union
198198
class C(AsyncIterator[int]):
@@ -342,7 +342,7 @@ async def f() -> None:
342342
[builtins fixtures/async_await.pyi]
343343
[typing fixtures/typing-async.pyi]
344344

345-
[case testAsyncWithTypeComments]
345+
[case testAsyncWithTypeComments_no_native_parse]
346346

347347
class C:
348348
async def __aenter__(self) -> int: pass

test-data/unit/check-basic.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ x = 1
286286
x in 1, # E: Unsupported right operand type for in ("int")
287287
[builtins fixtures/tuple.pyi]
288288

289-
[case testTrailingCommaInIfParsing]
289+
[case testTrailingCommaInIfParsing_no_native_parse]
290290
if x in 1, : pass
291291
[out]
292292
main:1: error: Invalid syntax

test-data/unit/check-columns.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Test column numbers in messages. --show-column-numbers is enabled implicitly by test runner.
22

3-
[case testColumnsSyntaxError]
3+
[case testColumnsSyntaxError_no_native_parse]
44
f()
55
1 +
66
[out]
@@ -146,7 +146,7 @@ if int():
146146
def f(a: 'A') -> None: pass
147147
(f(b=object())) # E:6: Unexpected keyword argument "b" for "f"
148148

149-
[case testColumnInvalidType]
149+
[case testColumnInvalidType_no_native_parse]
150150

151151
from typing import Iterable
152152

@@ -342,7 +342,7 @@ if int():
342342
main:2:11: error: Syntax error in type annotation
343343
main:2:11: note: Suggestion: Is there a spurious trailing comma?
344344

345-
[case testColumnSyntaxErrorInTypeAnnotation2]
345+
[case testColumnSyntaxErrorInTypeAnnotation2_no_native_parse]
346346
if int():
347347
# TODO: It would be better to point to the type comment
348348
xyz = 0 # type: blurbnard blarb

test-data/unit/check-errorcodes.test

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,21 @@ class A:
3030
[case testErrorCodeNoteHasNoCode]
3131
reveal_type(1) # N: Revealed type is "Literal[1]?"
3232

33-
[case testErrorCodeSyntaxError]
33+
[case testErrorCodeSyntaxError_no_native_parse]
3434
1 ''
3535
[out]
3636
main:1: error: Invalid syntax [syntax]
3737
[out version==3.10.0]
3838
main:1: error: Invalid syntax. Perhaps you forgot a comma? [syntax]
3939

40-
[case testErrorCodeSyntaxError2]
40+
[case testErrorCodeSyntaxError2_no_native_parse]
4141
def f(): # E: Type signature has too many parameters [syntax]
4242
# type: (int) -> None
4343
1
4444

4545
x = 0 # type: x y # E: Syntax error in type comment "x y" [syntax]
4646

47-
[case testErrorCodeSyntaxError3]
47+
[case testErrorCodeSyntaxError3_no_native_parse]
4848
# This is a bit inconsistent -- syntax error would be more logical?
4949
x: 'a b' # E: Invalid type comment or annotation [valid-type]
5050
for v in x: # type: int, int # E: Syntax error in type annotation [syntax] \
@@ -208,7 +208,7 @@ def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name
208208
import nostub # type: ignore[import]
209209
from defusedxml import xyz # type: ignore[import]
210210

211-
[case testErrorCodeBadIgnore]
211+
[case testErrorCodeBadIgnore_no_native_parse]
212212
import nostub # type: ignore xyz # E: Invalid "type: ignore" comment [syntax] \
213213
# E: Cannot find implementation or library stub for module named "nostub" [import-not-found] \
214214
# N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
@@ -226,7 +226,7 @@ def f(x, # type: int # type: ignore[ # E: Invalid "type: ignore" comment [sy
226226
# type: (...) -> None
227227
pass
228228

229-
[case testErrorCodeBadIgnoreNoExtraComment]
229+
[case testErrorCodeBadIgnoreNoExtraComment_no_native_parse]
230230
# Omit the E: ... comments, as they affect parsing
231231
import nostub # type: ignore xyz
232232
import nostub # type: ignore[xyz
@@ -762,7 +762,7 @@ main:1: error: Name "y" is not defined [name-defined]
762762
main:2: error: Name "ignored" is not defined [name-defined]
763763
main:2: error: Name "y" is not defined [name-defined]
764764

765-
[case testErrorCodeTypeIgnoreMisspelled2]
765+
[case testErrorCodeTypeIgnoreMisspelled2_no_native_parse]
766766
x = y # type: int # type: ignored[foo]
767767
x = y # type: int # type: ignored [foo]
768768
[out]
@@ -1014,7 +1014,7 @@ def f(arg: int) -> int:
10141014
def f(arg: str) -> str:
10151015
...
10161016

1017-
[case testSliceInDictBuiltin]
1017+
[case testSliceInDictBuiltin_no_native_parse]
10181018
# flags: --show-column-numbers
10191019
b: dict[int, x:y]
10201020
c: dict[x:y]
@@ -1027,7 +1027,7 @@ main:3:4: error: "dict" expects 2 type arguments, but 1 given [type-arg]
10271027
main:3:9: error: Invalid type comment or annotation [valid-type]
10281028
main:3:9: note: did you mean to use ',' instead of ':' ?
10291029

1030-
[case testSliceInDictTyping]
1030+
[case testSliceInDictTyping_no_native_parse]
10311031
# flags: --show-column-numbers
10321032
from typing import Dict
10331033
b: Dict[int, x:y]
@@ -1067,11 +1067,11 @@ def f(d: D, s: str) -> None:
10671067
[typing fixtures/typing-typeddict.pyi]
10681068

10691069
[case testRecommendErrorCode]
1070-
# type: ignore[whatever] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever"` [syntax]
1070+
# type: ignore[whatever] # E: Type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever"` [syntax]
10711071
1 + "asdf"
10721072

10731073
[case testRecommendErrorCode2]
1074-
# type: ignore[whatever, other] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever, other"` [syntax]
1074+
# type: ignore[whatever, other] # E: Type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever, other"` [syntax]
10751075
1 + "asdf"
10761076

10771077
[case testShowErrorCodesInConfig]

test-data/unit/check-expressions.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ if int():
14561456
b = (x for x in a) # E: Generator has incompatible item type "Callable[[], str]"; expected "Callable[[], int]"
14571457
[builtins fixtures/list.pyi]
14581458

1459-
[case testGeneratorNoSpuriousError]
1459+
[case testGeneratorNoSpuriousError_no_native_parse]
14601460
from typing import Iterable, overload
14611461

14621462
@overload
@@ -1915,7 +1915,7 @@ None == None
19151915
None < None # E: Unsupported left operand type for < ("None")
19161916
[builtins fixtures/ops.pyi]
19171917

1918-
[case testDictWithStarExpr]
1918+
[case testDictWithStarExpr_no_native_parse]
19191919

19201920
b = {'z': 26, *a} # E: Invalid syntax
19211921
[builtins fixtures/dict.pyi]

test-data/unit/check-fastparse.test

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
[case testFastParseSyntaxError]
1+
[case testFastParseSyntaxError_no_native_parse]
22

33
1 + # E: Invalid syntax
44

5-
[case testFastParseTypeCommentSyntaxError]
5+
[case testFastParseTypeCommentSyntaxError_no_native_parse]
66

77
x = None # type: a : b # E: Syntax error in type comment "a : b"
88

@@ -12,13 +12,13 @@ x = None # type: a + b # E: Invalid type comment or annotation
1212

1313
-- Function type comments are attributed to the function def line.
1414
-- This happens in both parsers.
15-
[case testFastParseFunctionAnnotationSyntaxError]
15+
[case testFastParseFunctionAnnotationSyntaxError_no_native_parse]
1616

1717
def f(): # E: Syntax error in type comment "None -> None" # N: Suggestion: wrap argument types in parentheses
1818
# type: None -> None
1919
pass
2020

21-
[case testFastParseFunctionAnnotationSyntaxErrorSpaces]
21+
[case testFastParseFunctionAnnotationSyntaxErrorSpaces_no_native_parse]
2222

2323
def f(): # E: Syntax error in type comment "None -> None" # N: Suggestion: wrap argument types in parentheses
2424
# type: None -> None
@@ -156,7 +156,7 @@ def f(a, # type: A
156156
[builtins fixtures/dict.pyi]
157157
[out]
158158

159-
[case testFastParsePerArgumentAnnotationsWithAnnotatedBareStar]
159+
[case testFastParsePerArgumentAnnotationsWithAnnotatedBareStar_no_native_parse]
160160

161161
def f(*, # type: int # E: Bare * has associated type comment
162162
x # type: str
@@ -194,7 +194,7 @@ def f(x, y): # E: Type signature has too few parameters
194194
f(1, 2)
195195
f(1) # E: Missing positional argument "y" in call to "f"
196196

197-
[case testFasterParseTypeErrorCustom]
197+
[case testFasterParseTypeErrorCustom_no_native_parse]
198198

199199
from typing import TypeVar, Generic
200200
T = TypeVar('T')
@@ -275,7 +275,7 @@ def f7(x: int): # E: Function has duplicate type signatures
275275
# type: (int) -> int
276276
pass
277277

278-
[case testFastParserDuplicateNames]
278+
[case testFastParserDuplicateNames_no_native_parse]
279279

280280
def f(x, y, z):
281281
pass

0 commit comments

Comments
 (0)