Skip to content

Commit ddb3f0a

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 ddb3f0a

File tree

3 files changed

+46
-42
lines changed

3 files changed

+46
-42
lines changed

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ ignore_names = [
480480
"REQUEST_QUOTA_REACHED",
481481
# pydantic-settings
482482
"model_config",
483+
# TYPE_CHECKING imports used in string annotations
484+
"HTTPAdapter",
485+
"Callback",
483486
]
484487

485488
# Duplicate some of .gitignore
@@ -495,6 +498,3 @@ ignore_decorators = [
495498
[tool.yamlfix]
496499
section_whitelines = 1
497500
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: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import threading
55
import time
66
from contextlib import ContextDecorator
7-
from typing import TYPE_CHECKING, Any, Literal, Self
7+
from typing import TYPE_CHECKING, Any, Literal, Self, cast
88
from urllib.parse import urljoin, urlparse
99

1010
import requests as requests_lib
@@ -29,10 +29,10 @@
2929
from collections.abc import Callable, Iterable, Mapping
3030

3131
from requests import PreparedRequest
32-
from requests.adapters import HTTPAdapter # noqa: F401
32+
from requests.adapters import HTTPAdapter
3333

3434
ResponseType = tuple[int, Mapping[str, str], str]
35-
Callback = Callable[[PreparedRequest], ResponseType] # noqa: F841
35+
Callback = Callable[[PreparedRequest], ResponseType]
3636

3737
# Thread-local storage to capture the request timeout
3838
_timeout_storage = threading.local()
@@ -157,10 +157,24 @@ def wrapped(request: "PreparedRequest") -> "ResponseType":
157157
timeout = getattr(_timeout_storage, "timeout", None)
158158
if timeout is not None and delay_seconds > 0:
159159
# timeout can be a float or a tuple (connect, read)
160+
effective_timeout: float | None
161+
min_tuple_length_for_read_timeout = 2
160162
if isinstance(timeout, tuple):
161-
effective_timeout: float | None = timeout[1] # read timeout
163+
timeout_tuple = cast(
164+
tuple[float | None, float | None], timeout
165+
)
166+
if len(timeout_tuple) >= min_tuple_length_for_read_timeout:
167+
read_timeout_value = timeout_tuple[1]
168+
if isinstance(read_timeout_value, (int, float)):
169+
effective_timeout = float(read_timeout_value)
170+
else:
171+
effective_timeout = None
172+
else:
173+
effective_timeout = None
174+
elif isinstance(timeout, (int, float)):
175+
effective_timeout = float(timeout)
162176
else:
163-
effective_timeout = timeout
177+
effective_timeout = None
164178
if (
165179
effective_timeout is not None
166180
and delay_seconds > effective_timeout
@@ -175,18 +189,21 @@ def wrapped(request: "PreparedRequest") -> "ResponseType":
175189

176190
mock = RequestsMock(assert_all_requests_are_fired=False)
177191

178-
# Patch _on_request to capture the timeout parameter
179-
original_on_request = mock._on_request # noqa: SLF001
192+
# Patch _on_request to capture the timeout parameter.
193+
# We cast to Any to bypass type checkers as we're intentionally
194+
# accessing a private member of the responses library.
195+
mock_any = cast(Any, mock)
196+
original_on_request = mock_any._on_request # noqa: SLF001
180197

181198
def patched_on_request(
182199
adapter: "HTTPAdapter",
183200
request: "PreparedRequest",
184201
**kwargs: Any, # noqa: ANN401
185202
) -> Any: # noqa: ANN401
186203
_timeout_storage.timeout = kwargs.get("timeout")
187-
return original_on_request(adapter, request, **kwargs) # type: ignore[misc]
204+
return original_on_request(adapter, request, **kwargs)
188205

189-
mock._on_request = patched_on_request # type: ignore[method-assign] # noqa: SLF001
206+
mock_any._on_request = patched_on_request # noqa: SLF001
190207
for vws_route in self._mock_vws_api.routes:
191208
url_pattern = urljoin(
192209
base=self._base_vws_url,

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)