Skip to content

Commit e726f6c

Browse files
Add model request function transport boundary architecture guard
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 9d3f7d9 commit e726f6c

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ This runs lint, format checks, compile checks, tests, and package build.
134134
- `tests/test_manager_transport_boundary.py` (manager transport boundary enforcement through shared request helpers),
135135
- `tests/test_mapping_keys_access_usage.py` (centralized key-iteration boundaries),
136136
- `tests/test_mapping_reader_usage.py` (shared mapping-read parser usage),
137+
- `tests/test_model_request_function_transport_boundary.py` (model-request function-level transport boundary enforcement between parsed wrappers and raw helpers),
137138
- `tests/test_model_request_internal_reuse.py` (request-helper internal reuse of shared model request helper primitives),
138139
- `tests/test_model_request_wrapper_internal_reuse.py` (parsed model-request wrapper internal reuse of shared raw response-data helpers),
139140
- `tests/test_optional_serialization_helper_usage.py` (optional model serialization helper usage enforcement),

tests/test_architecture_marker_usage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"tests/test_manager_transport_boundary.py",
2525
"tests/test_mapping_reader_usage.py",
2626
"tests/test_mapping_keys_access_usage.py",
27+
"tests/test_model_request_function_transport_boundary.py",
2728
"tests/test_model_request_internal_reuse.py",
2829
"tests/test_model_request_wrapper_internal_reuse.py",
2930
"tests/test_tool_mapping_reader_usage.py",
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import ast
2+
from pathlib import Path
3+
4+
import pytest
5+
6+
pytestmark = pytest.mark.architecture
7+
8+
9+
MODULE_PATH = Path("hyperbrowser/client/managers/model_request_utils.py")
10+
11+
PARSED_WRAPPER_FUNCTIONS = (
12+
"post_model_request",
13+
"get_model_request",
14+
"delete_model_request",
15+
"put_model_request",
16+
"post_model_request_async",
17+
"get_model_request_async",
18+
"delete_model_request_async",
19+
"put_model_request_async",
20+
"post_model_request_to_endpoint",
21+
"post_model_request_to_endpoint_async",
22+
)
23+
24+
RAW_HELPER_FUNCTIONS = (
25+
"post_model_response_data",
26+
"get_model_response_data",
27+
"delete_model_response_data",
28+
"put_model_response_data",
29+
"post_model_response_data_async",
30+
"get_model_response_data_async",
31+
"delete_model_response_data_async",
32+
"put_model_response_data_async",
33+
"post_model_response_data_to_endpoint",
34+
"post_model_response_data_to_endpoint_async",
35+
)
36+
37+
38+
def _collect_function_sources() -> dict[str, str]:
39+
module_text = MODULE_PATH.read_text(encoding="utf-8")
40+
module_ast = ast.parse(module_text)
41+
function_sources: dict[str, str] = {}
42+
for node in module_ast.body:
43+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
44+
function_source = ast.get_source_segment(module_text, node)
45+
if function_source is not None:
46+
function_sources[node.name] = function_source
47+
return function_sources
48+
49+
50+
def test_parsed_model_request_wrappers_do_not_call_transport_directly():
51+
function_sources = _collect_function_sources()
52+
for function_name in PARSED_WRAPPER_FUNCTIONS:
53+
function_source = function_sources[function_name]
54+
assert "client.transport." not in function_source
55+
56+
57+
def test_raw_model_request_helpers_are_transport_boundary():
58+
function_sources = _collect_function_sources()
59+
for function_name in RAW_HELPER_FUNCTIONS:
60+
function_source = function_sources[function_name]
61+
assert "client.transport." in function_source

0 commit comments

Comments
 (0)