Skip to content

Commit cac6080

Browse files
committed
Require Python 3.10 and support pytest 9
pytest 9.0.0 began requiring this version, so pytest-mypy-testing now fails when targeting earlier versions. This also requires mypy 1.17.0 in tests, due to python/mypy#19179.
1 parent e3d5c5a commit cac6080

3 files changed

Lines changed: 38 additions & 40 deletions

File tree

.github/workflows/tests.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ jobs:
2424
fail-fast: false
2525
matrix:
2626
os: [ubuntu-latest, windows-latest, macos-latest]
27-
python-version: ["3.9", "3.13", "3.14", "3.14t"]
27+
python-version: ["3.10", "3.13", "3.14", "3.14t"]
2828
include:
29-
- os: ubuntu-latest
30-
python-version: "3.10"
3129
- os: ubuntu-latest
3230
python-version: "3.11"
3331
- os: ubuntu-latest

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ classifiers = [
2020
"Programming Language :: Python",
2121
"Typing :: Typed",
2222
]
23-
requires-python = ">=3.9"
23+
requires-python = ">=3.10"
2424
dynamic = ["version"]
2525

2626
[project.urls]
@@ -33,11 +33,11 @@ Tracker = "https://github.com/ipython/traitlets/issues"
3333
[project.optional-dependencies]
3434
test = [
3535
"argcomplete>=3.0.3",
36-
"mypy>=1.7.0",
36+
"mypy>=1.17.0",
3737
"pre-commit",
3838
"pytest-mock",
3939
"pytest-mypy-testing",
40-
"pytest>=7.0,<8.2",
40+
"pytest>=7.0,<10.0",
4141
]
4242
docs = [
4343
"myst-parser",
@@ -86,7 +86,7 @@ build = [
8686

8787
[tool.mypy]
8888
files = "traitlets"
89-
python_version = "3.9"
89+
python_version = "3.10"
9090
strict = true
9191
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
9292
pretty = true

tests/test_typing.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -185,27 +185,27 @@ class T(HasTraits):
185185

186186
t = T()
187187
reveal_type(
188-
Unicode( # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
188+
Unicode( # R: traitlets.traitlets.Unicode[builtins.str, builtins.str | builtins.bytes]
189189
"foo"
190190
)
191191
)
192192
reveal_type(
193-
Unicode( # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
193+
Unicode( # R: traitlets.traitlets.Unicode[builtins.str, builtins.str | builtins.bytes]
194194
""
195195
).tag(sync=True)
196196
)
197197
reveal_type(
198-
Unicode( # R: traitlets.traitlets.Unicode[Union[builtins.str, None], Union[builtins.str, builtins.bytes, None]]
198+
Unicode( # R: traitlets.traitlets.Unicode[builtins.str | None, builtins.str | builtins.bytes | None]
199199
None, allow_none=True
200200
)
201201
)
202202
reveal_type(
203-
Unicode( # R: traitlets.traitlets.Unicode[Union[builtins.str, None], Union[builtins.str, builtins.bytes, None]]
203+
Unicode( # R: traitlets.traitlets.Unicode[builtins.str | None, builtins.str | builtins.bytes | None]
204204
None, allow_none=True
205205
).tag(sync=True)
206206
)
207207
reveal_type(
208-
T.export_format # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
208+
T.export_format # R: traitlets.traitlets.Unicode[builtins.str, builtins.str | builtins.bytes]
209209
)
210210
reveal_type(t.export_format) # R: builtins.str
211211

@@ -312,37 +312,37 @@ class T(HasTraits):
312312

313313
t = T()
314314
reveal_type(
315-
Bool(True) # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
315+
Bool(True) # R: traitlets.traitlets.Bool[builtins.bool, builtins.bool | builtins.int]
316316
)
317317
reveal_type(
318-
Bool( # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
318+
Bool( # R: traitlets.traitlets.Bool[builtins.bool, builtins.bool | builtins.int]
319319
True
320320
).tag(sync=True)
321321
)
322322
reveal_type(
323-
Bool( # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
323+
Bool( # R: traitlets.traitlets.Bool[builtins.bool | None, builtins.bool | builtins.int | None]
324324
None, allow_none=True
325325
)
326326
)
327327
reveal_type(
328-
Bool( # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
328+
Bool( # R: traitlets.traitlets.Bool[builtins.bool | None, builtins.bool | builtins.int | None]
329329
None, allow_none=True
330330
).tag(sync=True)
331331
)
332332
reveal_type(
333-
T.b # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
333+
T.b # R: traitlets.traitlets.Bool[builtins.bool, builtins.bool | builtins.int]
334334
)
335335
reveal_type(t.b) # R: builtins.bool
336-
reveal_type(t.ob) # R: Union[builtins.bool, None]
336+
reveal_type(t.ob) # R: builtins.bool | None
337337
reveal_type(
338-
T.b # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
338+
T.b # R: traitlets.traitlets.Bool[builtins.bool, builtins.bool | builtins.int]
339339
)
340340
reveal_type(
341-
T.ob # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
341+
T.ob # R: traitlets.traitlets.Bool[builtins.bool | None, builtins.bool | builtins.int | None]
342342
)
343-
# we would expect this to be Optional[Union[bool, int]], but...
344-
t.b = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Union[bool, int]") [assignment]
345-
t.b = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[bool, int]") [assignment]
343+
# we would expect this to be bool | int | None, but...
344+
t.b = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "bool | int") [assignment]
345+
t.b = None # E: Incompatible types in assignment (expression has type "None", variable has type "bool | int") [assignment]
346346

347347

348348
@pytest.mark.mypy_testing
@@ -355,21 +355,21 @@ class T(HasTraits):
355355
reveal_type(Int(True)) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
356356
reveal_type(Int(True).tag(sync=True)) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
357357
reveal_type(
358-
Int( # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
358+
Int( # R: traitlets.traitlets.Int[builtins.int | None, builtins.int | None]
359359
None, allow_none=True
360360
)
361361
)
362362
reveal_type(
363-
Int( # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
363+
Int( # R: traitlets.traitlets.Int[builtins.int | None, builtins.int | None]
364364
None, allow_none=True
365365
).tag(sync=True)
366366
)
367367
reveal_type(T.i) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
368368
reveal_type(t.i) # R: builtins.int
369-
reveal_type(t.oi) # R: Union[builtins.int, None]
369+
reveal_type(t.oi) # R: builtins.int | None
370370
reveal_type(T.i) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
371371
reveal_type(
372-
T.oi # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
372+
T.oi # R: traitlets.traitlets.Int[builtins.int | None, builtins.int | None]
373373
)
374374
t.i = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
375375
t.i = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [assignment]
@@ -386,18 +386,18 @@ class T(HasTraits):
386386
reveal_type(CInt(42)) # R: traitlets.traitlets.CInt[builtins.int, Any]
387387
reveal_type(CInt(42).tag(sync=True)) # R: traitlets.traitlets.CInt[builtins.int, Any]
388388
reveal_type(
389-
CInt(None, allow_none=True) # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
389+
CInt(None, allow_none=True) # R: traitlets.traitlets.CInt[builtins.int | None, Any]
390390
)
391391
reveal_type(
392-
CInt( # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
392+
CInt( # R: traitlets.traitlets.CInt[builtins.int | None, Any]
393393
None, allow_none=True
394394
).tag(sync=True)
395395
)
396396
reveal_type(T.i) # R: traitlets.traitlets.CInt[builtins.int, Any]
397397
reveal_type(t.i) # R: builtins.int
398-
reveal_type(t.oi) # R: Union[builtins.int, None]
398+
reveal_type(t.oi) # R: builtins.int | None
399399
reveal_type(T.i) # R: traitlets.traitlets.CInt[builtins.int, Any]
400-
reveal_type(T.oi) # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
400+
reveal_type(T.oi) # R: traitlets.traitlets.CInt[builtins.int | None, Any]
401401

402402

403403
@pytest.mark.mypy_testing
@@ -416,17 +416,17 @@ class T(HasTraits):
416416
sync=True
417417
)
418418
)
419-
reveal_type(t.otcp) # R: Union[tuple[builtins.str, builtins.int], None]
419+
reveal_type(t.otcp) # R: tuple[builtins.str, builtins.int] | None
420420
reveal_type(
421-
T.otcp # R: traitlets.traitlets.TCPAddress[Union[tuple[builtins.str, builtins.int], None], Union[tuple[builtins.str, builtins.int], None]]
421+
T.otcp # R: traitlets.traitlets.TCPAddress[tuple[builtins.str, builtins.int] | None, tuple[builtins.str, builtins.int] | None]
422422
)
423423
reveal_type(
424-
T.otcp.tag( # R: traitlets.traitlets.TCPAddress[Union[tuple[builtins.str, builtins.int], None], Union[tuple[builtins.str, builtins.int], None]]
424+
T.otcp.tag( # R: traitlets.traitlets.TCPAddress[tuple[builtins.str, builtins.int] | None, tuple[builtins.str, builtins.int] | None]
425425
sync=True
426426
)
427427
)
428428
t.tcp = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "tuple[str, int]") [assignment]
429-
t.otcp = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[tuple[str, int]]") [assignment]
429+
t.otcp = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "tuple[str, int] | None") [assignment]
430430
t.tcp = None # E: Incompatible types in assignment (expression has type "None", variable has type "tuple[str, int]") [assignment]
431431

432432

@@ -441,14 +441,14 @@ class T(HasTraits):
441441
reveal_type(t.inst) # R: tests.test_typing.Foo
442442
reveal_type(T.inst) # R: traitlets.traitlets.Instance[tests.test_typing.Foo]
443443
reveal_type(T.inst.tag(sync=True)) # R: traitlets.traitlets.Instance[tests.test_typing.Foo]
444-
reveal_type(t.oinst) # R: Union[tests.test_typing.Foo, None]
445-
reveal_type(t.oinst_string) # R: Union[Any, None]
446-
reveal_type(T.oinst) # R: traitlets.traitlets.Instance[Union[tests.test_typing.Foo, None]]
444+
reveal_type(t.oinst) # R: tests.test_typing.Foo | None
445+
reveal_type(t.oinst_string) # R: Any | None
446+
reveal_type(T.oinst) # R: traitlets.traitlets.Instance[tests.test_typing.Foo | None]
447447
reveal_type(
448-
T.oinst.tag( # R: traitlets.traitlets.Instance[Union[tests.test_typing.Foo, None]]
448+
T.oinst.tag( # R: traitlets.traitlets.Instance[tests.test_typing.Foo | None]
449449
sync=True
450450
)
451451
)
452452
t.inst = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Foo") [assignment]
453-
t.oinst = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Foo]") [assignment]
453+
t.oinst = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Foo | None") [assignment]
454454
t.inst = None # E: Incompatible types in assignment (expression has type "None", variable has type "Foo") [assignment]

0 commit comments

Comments
 (0)