Skip to content

Commit bb5ed19

Browse files
committed
test Python 3.14
co-authored-by: David Lord <[email protected]>
1 parent ee7ad40 commit bb5ed19

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

.github/workflows/tests.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
include:
16+
- {python: '3.14'}
17+
- {python: '3.14t'}
18+
- {name: Windows, python: '3.14', os: windows-latest}
19+
- {name: Mac, python: '3.14', os: macos-14}
1620
- {python: '3.13'}
17-
- {name: Windows, python: '3.13', os: windows-latest}
18-
- {name: Mac, python: '3.13', os: macos-latest}
1921
- {python: '3.12'}
2022
- {python: '3.11'}
2123
- {python: '3.10'}

pyproject.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ order-by-type = false
158158

159159
[tool.tox]
160160
env_list = [
161-
"py3.13", "py3.12", "py3.11", "py3.10", "py3.9",
161+
"py3.14", "py3.14t",
162+
"py3.13",
163+
"py3.12", "py3.11", "py3.10", "py3.9",
162164
"pypy3.11",
163165
"style",
164166
"typing",
@@ -179,6 +181,13 @@ commands = [[
179181
{replace = "posargs", default = [], extend = true},
180182
]]
181183

184+
[tool.tox.env.py3.14t]
185+
commands_pre = [
186+
# watchdog doesn't support free threading yet, no marker to exclude it yet
187+
# watchdog_fsevents.c extension on macOS, and stability on Windows.
188+
["uv", "pip", "uninstall", "watchdog"],
189+
]
190+
182191
[tool.tox.env.style]
183192
description = "run all pre-commit hooks on all files"
184193
dependency_groups = ["pre-commit"]

tests/test_serving.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,21 @@
22

33
import collections.abc as cabc
44
import http.client
5+
import importlib.metadata
56
import json
67
import os
78
import shutil
89
import socket
910
import ssl
1011
import sys
1112
import typing as t
13+
from importlib.metadata import PackageNotFoundError
1214
from io import BytesIO
1315
from pathlib import Path
1416
from unittest.mock import Mock
1517
from unittest.mock import patch
1618

1719
import pytest
18-
from watchdog import version as watchdog_version
19-
from watchdog.events import EVENT_TYPE_MODIFIED
20-
from watchdog.events import EVENT_TYPE_OPENED
21-
from watchdog.events import FileModifiedEvent
2220

2321
from werkzeug import run_simple
2422
from werkzeug._reloader import _find_stat_paths
@@ -33,6 +31,11 @@
3331
from conftest import DevServerClient
3432
from conftest import StartDevServer
3533

34+
try:
35+
watchdog_version: str = importlib.metadata.version("watchdog")
36+
except PackageNotFoundError:
37+
watchdog_version = ""
38+
3639

3740
@pytest.mark.parametrize(
3841
"kwargs",
@@ -103,7 +106,14 @@ def test_ssl_object(dev_server: StartDevServer) -> None:
103106
assert r.json["wsgi.url_scheme"] == "https"
104107

105108

106-
@pytest.mark.parametrize("reloader_type", ["stat", "watchdog"])
109+
require_watchdog = pytest.mark.skipif(
110+
not watchdog_version, reason="watchdog not installed"
111+
)
112+
113+
114+
@pytest.mark.parametrize(
115+
"reloader_type", ["stat", pytest.param("watchdog", marks=[require_watchdog])]
116+
)
107117
@pytest.mark.skipif(
108118
os.name == "nt" and "CI" in os.environ, reason="unreliable on Windows during CI"
109119
)
@@ -127,8 +137,13 @@ def test_reloader_sys_path(
127137
assert client.request().status == 200
128138

129139

140+
@require_watchdog
130141
@patch.object(WatchdogReloaderLoop, "trigger_reload")
131142
def test_watchdog_reloader_ignores_opened(mock_trigger_reload: Mock) -> None:
143+
from watchdog.events import EVENT_TYPE_MODIFIED
144+
from watchdog.events import EVENT_TYPE_OPENED
145+
from watchdog.events import FileModifiedEvent
146+
132147
reloader = WatchdogReloaderLoop()
133148
modified_event = FileModifiedEvent("")
134149
modified_event.event_type = EVENT_TYPE_MODIFIED
@@ -143,12 +158,14 @@ def test_watchdog_reloader_ignores_opened(mock_trigger_reload: Mock) -> None:
143158

144159

145160
@pytest.mark.skipif(
146-
watchdog_version.VERSION_MAJOR < 5,
161+
watchdog_version < "5",
147162
reason="'closed no write' event introduced in watchdog 5.0",
148163
)
149164
@patch.object(WatchdogReloaderLoop, "trigger_reload")
150165
def test_watchdog_reloader_ignores_closed_no_write(mock_trigger_reload: Mock) -> None:
151-
from watchdog.events import EVENT_TYPE_CLOSED_NO_WRITE # type: ignore[attr-defined]
166+
from watchdog.events import EVENT_TYPE_CLOSED_NO_WRITE
167+
from watchdog.events import EVENT_TYPE_MODIFIED
168+
from watchdog.events import FileModifiedEvent
152169

153170
reloader = WatchdogReloaderLoop()
154171
modified_event = FileModifiedEvent("")

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)