Skip to content

Commit b8260f8

Browse files
committed
fix(ci): stop a filterwarnings class path aborting the 3.9/3.10 test session
`[tool.pytest.ini_options] filterwarnings` carried `ignore::starlette.exceptions.StarletteDeprecationWarning`. pytest resolves that class while parsing config, so on the 3.9/3.10 matrix legs - where the resolvable starlette predates the class - it raised AttributeError: module 'starlette.exceptions' has no attribute 'StarletteDeprecationWarning' and aborted the whole session with a usage error (exit 4) before collecting a single test. Register the filter from conftest instead, where a missing class degrades to a no-op. It goes through `addinivalue_line` rather than a module-level `warnings.filterwarnings` call because pytest runs each test inside its own `catch_warnings()` seeded from the ini filters, which discards anything registered at conftest import time. The warning subclasses UserWarning, not DeprecationWarning, so there is no stdlib category to substitute. Suppression behaviour is unchanged on 3.11+; verified the warnings summary is empty again.
1 parent 17e7e6c commit b8260f8

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

pyproject.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,11 @@ python_files = ["test_*.py"]
172172
python_classes = ["Test*"]
173173
python_functions = ["test_*"]
174174
filterwarnings = [
175-
# Starlette's TestClient warns that httpx is deprecated in favor of httpx2;
176-
# this is upstream noise, not actionable from this project.
177-
"ignore::starlette.exceptions.StarletteDeprecationWarning",
175+
# Starlette's TestClient deprecation warning is registered in
176+
# python/tests/conftest.py, NOT here. pytest resolves a class path in this
177+
# list at config-parse time, so naming a class that a older starlette does
178+
# not have aborts the entire session with a usage error (exit 4) on the
179+
# 3.9/3.10 legs. conftest can tolerate its absence; this list cannot.
178180
]
179181

180182
[tool.mypy]

python/tests/conftest.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,29 @@ def _demote_repo_source_dir() -> None:
8585
os.environ.setdefault("QECTOR_TESTS_USE_INSTALLED", "1")
8686

8787

88+
# Starlette's TestClient emits a deprecation warning that is upstream noise, not
89+
# actionable here. This lived in `[tool.pytest.ini_options] filterwarnings` as
90+
# `ignore::starlette.exceptions.StarletteDeprecationWarning`, but pytest resolves
91+
# that class at config-parse time: on the 3.9/3.10 matrix legs the resolvable
92+
# starlette is older, has no such attribute, and pytest aborts the whole session
93+
# with a usage error (exit 4) before collecting a single test. Registering it
94+
# here instead degrades to a no-op when the class is absent.
95+
#
96+
# Note it subclasses UserWarning, not DeprecationWarning, so there is no stdlib
97+
# category to filter on as a substitute.
98+
#
99+
# It has to go through `addinivalue_line` rather than a module-level
100+
# `warnings.filterwarnings` call: pytest runs each test inside its own
101+
# `catch_warnings()` block seeded from the ini filters, which discards anything
102+
# registered at conftest import time.
103+
def pytest_configure(config):
104+
try:
105+
from starlette.exceptions import StarletteDeprecationWarning as _W
106+
except Exception: # pragma: no cover - starlette absent or too old to have it
107+
return
108+
config.addinivalue_line("filterwarnings", f"ignore::{_W.__module__}.{_W.__qualname__}")
109+
110+
88111
def pytest_report_header(config):
89112
"""Make the resolution decision visible in the test header."""
90113
spec = importlib.util.find_spec("qector_decoder_v3")

0 commit comments

Comments
 (0)