Skip to content

Commit 0b28313

Browse files
bluetechpytestbot
authored andcommitted
[8.2.x] Add Python 3.13 (beta) support
1 parent f3dd93a commit 0b28313

File tree

11 files changed

+45
-34
lines changed

11 files changed

+45
-34
lines changed

Diff for: .github/workflows/test.yml

+19-3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ jobs:
5555
"windows-py310",
5656
"windows-py311",
5757
"windows-py312",
58+
"windows-py313",
5859

5960
"ubuntu-py38",
6061
"ubuntu-py38-pluggy",
@@ -63,12 +64,14 @@ jobs:
6364
"ubuntu-py310",
6465
"ubuntu-py311",
6566
"ubuntu-py312",
67+
"ubuntu-py313",
6668
"ubuntu-pypy3",
6769

6870
"macos-py38",
6971
"macos-py39",
7072
"macos-py310",
7173
"macos-py312",
74+
"macos-py313",
7275

7376
"doctesting",
7477
"plugins",
@@ -97,9 +100,13 @@ jobs:
97100
os: windows-latest
98101
tox_env: "py311"
99102
- name: "windows-py312"
100-
python: "3.12-dev"
103+
python: "3.12"
101104
os: windows-latest
102105
tox_env: "py312"
106+
- name: "windows-py313"
107+
python: "3.13-dev"
108+
os: windows-latest
109+
tox_env: "py313"
103110

104111
- name: "ubuntu-py38"
105112
python: "3.8"
@@ -128,10 +135,15 @@ jobs:
128135
tox_env: "py311"
129136
use_coverage: true
130137
- name: "ubuntu-py312"
131-
python: "3.12-dev"
138+
python: "3.12"
132139
os: ubuntu-latest
133140
tox_env: "py312"
134141
use_coverage: true
142+
- name: "ubuntu-py313"
143+
python: "3.13-dev"
144+
os: ubuntu-latest
145+
tox_env: "py313"
146+
use_coverage: true
135147
- name: "ubuntu-pypy3"
136148
python: "pypy-3.8"
137149
os: ubuntu-latest
@@ -151,9 +163,13 @@ jobs:
151163
os: macos-latest
152164
tox_env: "py310-xdist"
153165
- name: "macos-py312"
154-
python: "3.12-dev"
166+
python: "3.12"
155167
os: macos-latest
156168
tox_env: "py312-xdist"
169+
- name: "macos-py313"
170+
python: "3.13-dev"
171+
os: macos-latest
172+
tox_env: "py313-xdist"
157173

158174
- name: "plugins"
159175
python: "3.12"

Diff for: changelog/12334.improvement.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support for Python 3.13 (beta1 at the time of writing).

Diff for: pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ classifiers = [
3131
"Programming Language :: Python :: 3.10",
3232
"Programming Language :: Python :: 3.11",
3333
"Programming Language :: Python :: 3.12",
34+
"Programming Language :: Python :: 3.13",
3435
"Topic :: Software Development :: Libraries",
3536
"Topic :: Software Development :: Testing",
3637
"Topic :: Utilities",

Diff for: src/_pytest/_code/code.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -424,15 +424,14 @@ def recursionindex(self) -> Optional[int]:
424424
# which generates code objects that have hash/value equality
425425
# XXX needs a test
426426
key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno
427-
# print "checking for recursion at", key
428427
values = cache.setdefault(key, [])
428+
# Since Python 3.13 f_locals is a proxy, freeze it.
429+
loc = dict(entry.frame.f_locals)
429430
if values:
430-
f = entry.frame
431-
loc = f.f_locals
432431
for otherloc in values:
433432
if otherloc == loc:
434433
return i
435-
values.append(entry.frame.f_locals)
434+
values.append(loc)
436435
return None
437436

438437

Diff for: src/_pytest/pytester.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ def assert_contains(self, entries: Sequence[Tuple[str, str]]) -> None:
289289
__tracebackhide__ = True
290290
i = 0
291291
entries = list(entries)
292-
backlocals = sys._getframe(1).f_locals
292+
# Since Python 3.13, f_locals is not a dict, but eval requires a dict.
293+
backlocals = dict(sys._getframe(1).f_locals)
293294
while entries:
294295
name, check = entries.pop(0)
295296
for ind, call in enumerate(self.calls[i:]):
@@ -760,6 +761,9 @@ def _makefile(
760761
) -> Path:
761762
items = list(files.items())
762763

764+
if ext is None:
765+
raise TypeError("ext must not be None")
766+
763767
if ext and not ext.startswith("."):
764768
raise ValueError(
765769
f"pytester.makefile expects a file extension, try .{ext} instead of {ext}"

Diff for: testing/code/test_excinfo.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# mypy: allow-untyped-defs
22
from __future__ import annotations
33

4+
import fnmatch
45
import importlib
56
import io
67
import operator
@@ -237,7 +238,7 @@ def f(n):
237238
n += 1
238239
f(n)
239240

240-
excinfo = pytest.raises(RuntimeError, f, 8)
241+
excinfo = pytest.raises(RecursionError, f, 8)
241242
traceback = excinfo.traceback
242243
recindex = traceback.recursionindex()
243244
assert recindex == 3
@@ -373,7 +374,10 @@ def test_excinfo_no_sourcecode():
373374
except ValueError:
374375
excinfo = _pytest._code.ExceptionInfo.from_current()
375376
s = str(excinfo.traceback[-1])
376-
assert s == " File '<string>':1 in <module>\n ???\n"
377+
# TODO: Since Python 3.13b1 under pytest-xdist, the * is `import
378+
# sys;exec(eval(sys.stdin.readline()))` (execnet bootstrap code)
379+
# instead of `???` like before. Is this OK?
380+
fnmatch.fnmatch(s, " File '<string>':1 in <module>\n *\n")
377381

378382

379383
def test_excinfo_no_python_sourcecode(tmp_path: Path) -> None:

Diff for: testing/code/test_source.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,11 @@ class B:
370370
pass
371371

372372
B.__name__ = B.__qualname__ = "B2"
373-
assert getfslineno(B)[1] == -1
373+
# Since Python 3.13 this started working.
374+
if sys.version_info >= (3, 13):
375+
assert getfslineno(B)[1] != -1
376+
else:
377+
assert getfslineno(B)[1] == -1
374378

375379

376380
def test_code_of_object_instance_with_call() -> None:

Diff for: testing/test_cacheprovider.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def test_custom_cache_dir_with_env_var(
194194
assert pytester.path.joinpath("custom_cache_dir").is_dir()
195195

196196

197-
@pytest.mark.parametrize("env", ((), ("TOX_ENV_DIR", "/tox_env_dir")))
197+
@pytest.mark.parametrize("env", ((), ("TOX_ENV_DIR", "mydir/tox-env")))
198198
def test_cache_reportheader(
199199
env: Sequence[str], pytester: Pytester, monkeypatch: MonkeyPatch
200200
) -> None:

Diff for: testing/test_doctest.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,7 @@ def test_doctest_unexpected_exception(self, pytester: Pytester):
224224
"Traceback (most recent call last):",
225225
' File "*/doctest.py", line *, in __run',
226226
" *",
227-
*(
228-
(" *^^^^*",)
229-
if (3, 11, 0, "beta", 4) > sys.version_info >= (3, 11)
230-
else ()
231-
),
227+
*((" *^^^^*", " *", " *") if sys.version_info >= (3, 13) else ()),
232228
' File "<doctest test_doctest_unexpected_exception.txt[1]>", line 1, in <module>',
233229
"ZeroDivisionError: division by zero",
234230
"*/test_doctest_unexpected_exception.txt:2: UnexpectedException",
@@ -385,7 +381,7 @@ def some_property(self):
385381
"*= FAILURES =*",
386382
"*_ [[]doctest[]] test_doctest_linedata_on_property.Sample.some_property _*",
387383
"004 ",
388-
"005 >>> Sample().some_property",
384+
"005 *>>> Sample().some_property",
389385
"Expected:",
390386
" 'another thing'",
391387
"Got:",

Diff for: testing/test_main.py

+1-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import os
44
from pathlib import Path
55
import re
6-
import sys
76
from typing import Optional
87

98
from _pytest.config import ExitCode
@@ -45,32 +44,18 @@ def pytest_internalerror(excrepr, excinfo):
4544
assert result.ret == ExitCode.INTERNAL_ERROR
4645
assert result.stdout.lines[0] == "INTERNALERROR> Traceback (most recent call last):"
4746

48-
end_lines = (
49-
result.stdout.lines[-4:]
50-
if (3, 11, 0, "beta", 4) > sys.version_info >= (3, 11)
51-
else result.stdout.lines[-3:]
52-
)
47+
end_lines = result.stdout.lines[-3:]
5348

5449
if exc == SystemExit:
5550
assert end_lines == [
5651
f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart',
5752
'INTERNALERROR> raise SystemExit("boom")',
58-
*(
59-
("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",)
60-
if (3, 11, 0, "beta", 4) > sys.version_info >= (3, 11)
61-
else ()
62-
),
6353
"INTERNALERROR> SystemExit: boom",
6454
]
6555
else:
6656
assert end_lines == [
6757
f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart',
6858
'INTERNALERROR> raise ValueError("boom")',
69-
*(
70-
("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",)
71-
if (3, 11, 0, "beta", 4) > sys.version_info >= (3, 11)
72-
else ()
73-
),
7459
"INTERNALERROR> ValueError: boom",
7560
]
7661
if returncode is False:

Diff for: tox.ini

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ envlist =
99
py310
1010
py311
1111
py312
12+
py313
1213
pypy3
1314
py38-{pexpect,xdist,unittestextras,numpy,pluggymain,pylib}
1415
doctesting

0 commit comments

Comments
 (0)