Skip to content

Commit 8317542

Browse files
authored
Merge pull request #8639 from mgorny/backport-8494-8555
2 parents 15a4538 + 48f78f9 commit 8317542

17 files changed

+95
-44
lines changed

.github/workflows/main.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ jobs:
2727
"windows-py37",
2828
"windows-py37-pluggy",
2929
"windows-py38",
30+
"windows-py39",
31+
"windows-py310",
3032

3133
"ubuntu-py36",
3234
"ubuntu-py37",
3335
"ubuntu-py37-pluggy",
3436
"ubuntu-py37-freeze",
3537
"ubuntu-py38",
3638
"ubuntu-py39",
39+
"ubuntu-py310",
3740
"ubuntu-pypy3",
3841

3942
"macos-py37",
@@ -62,6 +65,14 @@ jobs:
6265
os: windows-latest
6366
tox_env: "py38-unittestextras"
6467
use_coverage: true
68+
- name: "windows-py39"
69+
python: "3.9"
70+
os: windows-latest
71+
tox_env: "py39-xdist"
72+
- name: "windows-py310"
73+
python: "3.10-dev"
74+
os: windows-latest
75+
tox_env: "py310-xdist"
6576

6677
- name: "ubuntu-py36"
6778
python: "3.6"
@@ -88,6 +99,10 @@ jobs:
8899
python: "3.9"
89100
os: ubuntu-latest
90101
tox_env: "py39-xdist"
102+
- name: "ubuntu-py310"
103+
python: "3.10-dev"
104+
os: ubuntu-latest
105+
tox_env: "py310-xdist"
91106
- name: "ubuntu-pypy3"
92107
python: "pypy3"
93108
os: ubuntu-latest

.pre-commit-config.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ repos:
3939
- id: pyupgrade
4040
args: [--py36-plus]
4141
- repo: https://github.com/asottile/setup-cfg-fmt
42-
rev: v1.11.0
42+
rev: v1.17.0
4343
hooks:
4444
- id: setup-cfg-fmt
45-
# TODO: when upgrading setup-cfg-fmt this can be removed
46-
args: [--max-py-version=3.9]
45+
args: [--max-py-version=3.10]
4746
- repo: https://github.com/pre-commit/pygrep-hooks
4847
rev: v1.6.0
4948
hooks:

changelog/8494.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Python 3.10 is now supported.

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ filterwarnings = [
2626
# produced by older pyparsing<=2.2.0.
2727
"default:Using or importing the ABCs:DeprecationWarning:pyparsing.*",
2828
"default:the imp module is deprecated in favour of importlib:DeprecationWarning:nose.*",
29+
# distutils is deprecated in 3.10, scheduled for removal in 3.12
30+
"ignore:The distutils package is deprecated:DeprecationWarning",
2931
# produced by python3.6/site.py itself (3.6.7 on Travis, could not trigger it with 3.6.8)."
3032
"ignore:.*U.*mode is deprecated:DeprecationWarning:(?!(pytest|_pytest))",
3133
# produced by pytest-xdist
@@ -40,6 +42,14 @@ filterwarnings = [
4042
"default:invalid escape sequence:DeprecationWarning",
4143
# ignore use of unregistered marks, because we use many to test the implementation
4244
"ignore::_pytest.warning_types.PytestUnknownMarkWarning",
45+
# https://github.com/benjaminp/six/issues/341
46+
"ignore:_SixMetaPathImporter\\.exec_module\\(\\) not found; falling back to load_module\\(\\):ImportWarning",
47+
# https://github.com/benjaminp/six/pull/352
48+
"ignore:_SixMetaPathImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning",
49+
# https://github.com/pypa/setuptools/pull/2517
50+
"ignore:VendorImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning",
51+
# https://github.com/pytest-dev/execnet/pull/127
52+
"ignore:isSet\\(\\) is deprecated, use is_set\\(\\) instead:DeprecationWarning",
4353
]
4454
pytester_example_dir = "testing/example_scripts"
4555
markers = [

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ classifiers =
2121
Programming Language :: Python :: 3.7
2222
Programming Language :: Python :: 3.8
2323
Programming Language :: Python :: 3.9
24+
Programming Language :: Python :: 3.10
2425
Topic :: Software Development :: Libraries
2526
Topic :: Software Development :: Testing
2627
Topic :: Utilities

testing/acceptance_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ def test_usage_error_code(pytester: Pytester) -> None:
11731173
assert result.ret == ExitCode.USAGE_ERROR
11741174

11751175

1176-
@pytest.mark.filterwarnings("default")
1176+
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning")
11771177
def test_warn_on_async_function(pytester: Pytester) -> None:
11781178
# In the below we .close() the coroutine only to avoid
11791179
# "RuntimeWarning: coroutine 'test_2' was never awaited"
@@ -1206,7 +1206,7 @@ def test_3():
12061206
)
12071207

12081208

1209-
@pytest.mark.filterwarnings("default")
1209+
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning")
12101210
def test_warn_on_async_gen_function(pytester: Pytester) -> None:
12111211
pytester.makepyfile(
12121212
test_async="""

testing/python/collect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ class Test(object):
12101210
assert result.ret == ExitCode.NO_TESTS_COLLECTED
12111211

12121212

1213-
@pytest.mark.filterwarnings("default")
1213+
@pytest.mark.filterwarnings("default::pytest.PytestCollectionWarning")
12141214
def test_dont_collect_non_function_callable(testdir):
12151215
"""Test for issue https://github.com/pytest-dev/pytest/issues/331
12161216

testing/python/metafunc.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,10 @@ def test_idmaker_enum(self) -> None:
448448
enum = pytest.importorskip("enum")
449449
e = enum.Enum("Foo", "one, two")
450450
result = idmaker(("a", "b"), [pytest.param(e.one, e.two)])
451-
assert result == ["Foo.one-Foo.two"]
451+
if sys.version_info[:2] >= (3, 10):
452+
assert result == ["one-two"]
453+
else:
454+
assert result == ["Foo.one-Foo.two"]
452455

453456
def test_idmaker_idfn(self) -> None:
454457
"""#351"""

testing/test_collection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ def test_collect_symlink_dir(pytester: Pytester) -> None:
12121212
"""A symlinked directory is collected."""
12131213
dir = pytester.mkdir("dir")
12141214
dir.joinpath("test_it.py").write_text("def test_it(): pass", "utf-8")
1215-
pytester.path.joinpath("symlink_dir").symlink_to(dir)
1215+
symlink_or_skip(pytester.path.joinpath("symlink_dir"), dir)
12161216
result = pytester.runpytest()
12171217
result.assert_outcomes(passed=2)
12181218

testing/test_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def test_silence_unknown_key_warning(self, pytester: Pytester) -> None:
290290
result = pytester.runpytest()
291291
result.stdout.no_fnmatch_line("*PytestConfigWarning*")
292292

293-
@pytest.mark.filterwarnings("default")
293+
@pytest.mark.filterwarnings("default::pytest.PytestConfigWarning")
294294
def test_disable_warnings_plugin_disables_config_warnings(
295295
self, pytester: Pytester
296296
) -> None:

testing/test_pytester.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -741,10 +741,16 @@ def test_run_result_repr() -> None:
741741

742742
# known exit code
743743
r = pytester.RunResult(1, outlines, errlines, duration=0.5)
744-
assert (
745-
repr(r) == "<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
746-
" len(stderr.lines)=4 duration=0.50s>"
747-
)
744+
if sys.version_info[:2] >= (3, 10):
745+
assert repr(r) == (
746+
"<RunResult ret=TESTS_FAILED len(stdout.lines)=3"
747+
" len(stderr.lines)=4 duration=0.50s>"
748+
)
749+
else:
750+
assert repr(r) == (
751+
"<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
752+
" len(stderr.lines)=4 duration=0.50s>"
753+
)
748754

749755
# unknown exit code: just the number
750756
r = pytester.RunResult(99, outlines, errlines, duration=0.5)

testing/test_skipping.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,21 +1126,34 @@ def test_func():
11261126
pypy_version_info = getattr(sys, "pypy_version_info", None)
11271127
if pypy_version_info is not None and pypy_version_info < (6,):
11281128
markline = markline[5:]
1129+
elif sys.version_info[:2] >= (3, 10):
1130+
markline = markline[11:]
11291131
elif sys.version_info >= (3, 8) or hasattr(sys, "pypy_version_info"):
11301132
markline = markline[4:]
1131-
result.stdout.fnmatch_lines(
1132-
[
1133+
1134+
if sys.version_info[:2] >= (3, 10):
1135+
expected = [
11331136
"*ERROR*test_nameerror*",
1134-
"*evaluating*skipif*condition*",
11351137
"*asd*",
1136-
"*ERROR*test_syntax*",
1137-
"*evaluating*xfail*condition*",
1138-
" syntax error",
1139-
markline,
1140-
"SyntaxError: invalid syntax",
1141-
"*1 pass*2 errors*",
1138+
"",
1139+
"During handling of the above exception, another exception occurred:",
11421140
]
1143-
)
1141+
else:
1142+
expected = [
1143+
"*ERROR*test_nameerror*",
1144+
]
1145+
1146+
expected += [
1147+
"*evaluating*skipif*condition*",
1148+
"*asd*",
1149+
"*ERROR*test_syntax*",
1150+
"*evaluating*xfail*condition*",
1151+
" syntax error",
1152+
markline,
1153+
"SyntaxError: invalid syntax",
1154+
"*1 pass*2 errors*",
1155+
]
1156+
result.stdout.fnmatch_lines(expected)
11441157

11451158

11461159
def test_xfail_skipif_with_globals(pytester: Pytester) -> None:

testing/test_terminal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@ def pytest_terminal_summary(terminalreporter, exitstatus):
16181618
)
16191619

16201620

1621-
@pytest.mark.filterwarnings("default")
1621+
@pytest.mark.filterwarnings("default::UserWarning")
16221622
def test_terminal_summary_warnings_are_displayed(pytester: Pytester) -> None:
16231623
"""Test that warnings emitted during pytest_terminal_summary are displayed.
16241624
(#1305).
@@ -1655,7 +1655,7 @@ def test_failure():
16551655
assert stdout.count("=== warnings summary ") == 2
16561656

16571657

1658-
@pytest.mark.filterwarnings("default")
1658+
@pytest.mark.filterwarnings("default::UserWarning")
16591659
def test_terminal_summary_warnings_header_once(pytester: Pytester) -> None:
16601660
pytester.makepyfile(
16611661
"""

testing/test_threadexception.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
pytest.skip("threadexception plugin needs Python>=3.8", allow_module_level=True)
99

1010

11-
@pytest.mark.filterwarnings("default")
11+
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
1212
def test_unhandled_thread_exception(pytester: Pytester) -> None:
1313
pytester.makepyfile(
1414
test_it="""
@@ -42,7 +42,7 @@ def test_2(): pass
4242
)
4343

4444

45-
@pytest.mark.filterwarnings("default")
45+
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
4646
def test_unhandled_thread_exception_in_setup(pytester: Pytester) -> None:
4747
pytester.makepyfile(
4848
test_it="""
@@ -78,7 +78,7 @@ def test_2(): pass
7878
)
7979

8080

81-
@pytest.mark.filterwarnings("default")
81+
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
8282
def test_unhandled_thread_exception_in_teardown(pytester: Pytester) -> None:
8383
pytester.makepyfile(
8484
test_it="""

testing/test_unraisableexception.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
pytest.skip("unraisableexception plugin needs Python>=3.8", allow_module_level=True)
99

1010

11-
@pytest.mark.filterwarnings("default")
11+
@pytest.mark.filterwarnings("default::pytest.PytestUnraisableExceptionWarning")
1212
def test_unraisable(pytester: Pytester) -> None:
1313
pytester.makepyfile(
1414
test_it="""
@@ -40,7 +40,7 @@ def test_2(): pass
4040
)
4141

4242

43-
@pytest.mark.filterwarnings("default")
43+
@pytest.mark.filterwarnings("default::pytest.PytestUnraisableExceptionWarning")
4444
def test_unraisable_in_setup(pytester: Pytester) -> None:
4545
pytester.makepyfile(
4646
test_it="""
@@ -76,7 +76,7 @@ def test_2(): pass
7676
)
7777

7878

79-
@pytest.mark.filterwarnings("default")
79+
@pytest.mark.filterwarnings("default::pytest.PytestUnraisableExceptionWarning")
8080
def test_unraisable_in_teardown(pytester: Pytester) -> None:
8181
pytester.makepyfile(
8282
test_it="""

0 commit comments

Comments
 (0)