Skip to content

Commit b2dffb6

Browse files
adamtheturtleclaude
andcommitted
Fix CI: remove local vws-python dependency
Remove the [tool.uv.sources] section that pointed to a local vws-python path which doesn't exist on CI runners. Replace tests that depended on unreleased vws-python features (request_timeout_seconds) with a test that uses tuple timeouts directly with the requests library. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 96578e1 commit b2dffb6

File tree

3 files changed

+38
-76
lines changed

3 files changed

+38
-76
lines changed

pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,3 @@ ignore_decorators = [
495495
[tool.yamlfix]
496496
section_whitelines = 1
497497
whitelines = 1
498-
499-
[tool.uv.sources]
500-
vws-python = { path = "../vws-python", editable = true }

src/mock_vws/_requests_mock_server/decorators.py

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
"""Decorators for using the mock."""
22

33
import re
4-
import threading
54
import time
65
from contextlib import ContextDecorator
7-
from typing import TYPE_CHECKING, Any, Literal, Self
6+
from typing import TYPE_CHECKING, Any, Literal, Self, cast
87
from urllib.parse import urljoin, urlparse
98

109
import requests as requests_lib
@@ -26,16 +25,7 @@
2625
from .mock_web_services_api import MockVuforiaWebServicesAPI
2726

2827
if TYPE_CHECKING:
29-
from collections.abc import Callable, Iterable, Mapping
30-
31-
from requests import PreparedRequest
32-
from requests.adapters import HTTPAdapter # noqa: F401
33-
34-
ResponseType = tuple[int, Mapping[str, str], str]
35-
Callback = Callable[[PreparedRequest], ResponseType] # noqa: F841
36-
37-
# Thread-local storage to capture the request timeout
38-
_timeout_storage = threading.local()
28+
from collections.abc import Iterable
3929

4030
_STRUCTURAL_SIMILARITY_MATCHER = StructuralSimilarityMatcher()
4131
_BRISQUE_TRACKING_RATER = BrisqueTargetTrackingRater()
@@ -149,44 +139,32 @@ def __enter__(self) -> Self:
149139
compiled_url_patterns: Iterable[re.Pattern[str]] = set()
150140
delay_seconds = self._response_delay_seconds
151141

152-
def wrap_callback(callback: "Callback") -> "Callback":
153-
"""Wrap a callback to add a response delay."""
142+
mock = RequestsMock(assert_all_requests_are_fired=False)
143+
144+
if delay_seconds > 0:
145+
mock_any = cast(Any, mock)
146+
original_on_request = mock_any._on_request # noqa: SLF001
154147

155-
def wrapped(request: "PreparedRequest") -> "ResponseType":
156-
# Check if the delay would exceed the request timeout
157-
timeout = getattr(_timeout_storage, "timeout", None)
158-
if timeout is not None and delay_seconds > 0:
159-
# timeout can be a float or a tuple (connect, read)
148+
def patched_on_request(
149+
*args: Any, # noqa: ANN401
150+
**kwargs: Any, # noqa: ANN401
151+
) -> Any: # noqa: ANN401
152+
timeout = kwargs.get("timeout")
153+
if timeout is not None:
160154
if isinstance(timeout, tuple):
161-
effective_timeout: float | None = timeout[1] # read timeout
155+
effective: float | None = timeout[1]
162156
else:
163-
effective_timeout = timeout
157+
effective = timeout
164158
if (
165-
effective_timeout is not None
166-
and delay_seconds > effective_timeout
159+
isinstance(effective, (int, float))
160+
and delay_seconds > effective
167161
):
168162
raise requests_lib.exceptions.Timeout
169-
170-
result = callback(request)
163+
result = original_on_request(*args, **kwargs)
171164
time.sleep(delay_seconds)
172165
return result
173166

174-
return wrapped
175-
176-
mock = RequestsMock(assert_all_requests_are_fired=False)
177-
178-
# Patch _on_request to capture the timeout parameter
179-
original_on_request = mock._on_request # noqa: SLF001
180-
181-
def patched_on_request(
182-
adapter: "HTTPAdapter",
183-
request: "PreparedRequest",
184-
**kwargs: Any, # noqa: ANN401
185-
) -> Any: # noqa: ANN401
186-
_timeout_storage.timeout = kwargs.get("timeout")
187-
return original_on_request(adapter, request, **kwargs) # type: ignore[misc]
188-
189-
mock._on_request = patched_on_request # type: ignore[method-assign] # noqa: SLF001
167+
mock_any._on_request = patched_on_request # noqa: SLF001
190168
for vws_route in self._mock_vws_api.routes:
191169
url_pattern = urljoin(
192170
base=self._base_vws_url,
@@ -205,7 +183,7 @@ def patched_on_request(
205183
mock.add_callback(
206184
method=vws_http_method,
207185
url=compiled_url_pattern,
208-
callback=wrap_callback(callback=original_callback),
186+
callback=original_callback,
209187
content_type=None,
210188
)
211189

@@ -227,7 +205,7 @@ def patched_on_request(
227205
mock.add_callback(
228206
method=vwq_http_method,
229207
url=compiled_url_pattern,
230-
callback=wrap_callback(callback=original_callback),
208+
callback=original_callback,
231209
content_type=None,
232210
)
233211

tests/mock_vws/test_requests_mock_usage.py

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -174,39 +174,26 @@ def test_delay_allows_completion() -> None:
174174
assert response.status_code is not None
175175

176176
@staticmethod
177-
def test_vws_client_with_timeout() -> None:
177+
def test_delay_with_tuple_timeout() -> None:
178178
"""
179-
The VWS client's request_timeout_seconds parameter works with
180-
response_delay_seconds.
179+
The response delay works correctly with tuple timeouts
180+
(connect_timeout, read_timeout).
181181
"""
182-
database = VuforiaDatabase()
183-
with MockVWS(response_delay_seconds=0.5) as mock:
184-
mock.add_database(database=database)
185-
vws_client = VWS(
186-
server_access_key=database.server_access_key,
187-
server_secret_key=database.server_secret_key,
188-
request_timeout_seconds=0.1,
182+
with (
183+
MockVWS(response_delay_seconds=0.5),
184+
pytest.raises(expected_exception=requests.exceptions.Timeout),
185+
):
186+
# Tuple timeout: (connect_timeout, read_timeout)
187+
# The read timeout (0.1) is less than the delay (0.5)
188+
requests.get(
189+
url="https://vws.vuforia.com/summary",
190+
headers={
191+
"Date": rfc_1123_date(),
192+
"Authorization": "bad_auth_token",
193+
},
194+
data=b"",
195+
timeout=(5.0, 0.1),
189196
)
190-
with pytest.raises(expected_exception=requests.exceptions.Timeout):
191-
vws_client.list_targets()
192-
193-
@staticmethod
194-
def test_vws_client_without_timeout() -> None:
195-
"""
196-
The VWS client completes successfully when the timeout exceeds
197-
the response delay.
198-
"""
199-
database = VuforiaDatabase()
200-
with MockVWS(response_delay_seconds=0.1) as mock:
201-
mock.add_database(database=database)
202-
vws_client = VWS(
203-
server_access_key=database.server_access_key,
204-
server_secret_key=database.server_secret_key,
205-
request_timeout_seconds=2.0,
206-
)
207-
# This should succeed
208-
targets = vws_client.list_targets()
209-
assert targets == []
210197

211198

212199
class TestProcessingTime:

0 commit comments

Comments
 (0)