Skip to content

Commit cece2d6

Browse files
authored
declare timeout ini options as float (#200)
Fixes #194. With pytest 9's native `[tool.pytest]` table, `timeout = 1200` (a TOML int) makes the whole session die at configure time: ``` INTERNALERROR> TypeError: pyproject.toml: config option 'timeout' expects a string, got int: 1200 ``` because `timeout` and `session_timeout` are registered with the default string ini type. Registering them with `type="float"` fixes it, matching what the values actually are. Legacy `[pytest]` ini strings like `timeout = 2.5` still parse the same way, and `timeout = 0` still means disabled (the `> 0` checks are unchanged). One catch: `type="float"` was added to `addini` in pytest 8.4, and registering it under 8.0.x fails at plugin load, so this bumps the floor in setup.cfg to `pytest>=8.4.0`. If keeping 8.0 support matters more, the alternative is a try/except shim around the registration; happy to switch if you prefer that. Added a regression test using `makepyprojecttoml` with int values for both options (skipped below pytest 9, where the native table doesn't exist). Suite passes locally on 3.12: 35 passed, 21 skipped (the pexpect spawn skips, this is a Windows machine).
1 parent 857be8f commit cece2d6

3 files changed

Lines changed: 28 additions & 3 deletions

File tree

‎pytest_timeout.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def pytest_addoption(parser):
9393
metavar="SECONDS",
9494
help=SESSION_TIMEOUT_DESC,
9595
)
96-
parser.addini("timeout", TIMEOUT_DESC)
96+
parser.addini("timeout", TIMEOUT_DESC, type="float")
9797
parser.addini("timeout_method", METHOD_DESC)
9898
parser.addini("timeout_func_only", FUNC_ONLY_DESC, type="bool", default=False)
9999
parser.addini(
@@ -102,7 +102,7 @@ def pytest_addoption(parser):
102102
type="bool",
103103
default=False,
104104
)
105-
parser.addini("session_timeout", SESSION_TIMEOUT_DESC)
105+
parser.addini("session_timeout", SESSION_TIMEOUT_DESC, type="float")
106106

107107

108108
class TimeoutHooks:

‎setup.cfg‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ classifiers =
3232
[options]
3333
py_modules = pytest_timeout
3434
install_requires =
35-
pytest>=8.0.0
35+
pytest>=8.4.0
3636
python_requires = >=3.10
3737

3838
[options.entry_points]

‎test_pytest_timeout.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,31 @@ def test_foo():
347347
assert result.ret
348348

349349

350+
@pytest.mark.skipif(
351+
pytest.version_tuple < (9, 0),
352+
reason="native [tool.pytest] table requires pytest 9",
353+
)
354+
def test_pyproject_toml_int_timeout(pytester):
355+
pytester.makepyfile(
356+
"""
357+
import time
358+
359+
def test_foo():
360+
time.sleep(2)
361+
"""
362+
)
363+
pytester.makepyprojecttoml(
364+
"""
365+
[tool.pytest]
366+
timeout = 1
367+
session_timeout = 60
368+
"""
369+
)
370+
result = pytester.runpytest_subprocess()
371+
result.stdout.no_fnmatch_line("INTERNALERROR*")
372+
assert result.ret
373+
374+
350375
def test_ini_timeout_func_only(pytester):
351376
pytester.makepyfile(
352377
"""

0 commit comments

Comments
 (0)