Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions respx/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ def _next_side_effect(
return effect

def _call_side_effect(
self, effect: CallableSideEffect, request: httpx.Request, **kwargs: Any
self, effect: CallableSideEffect, request: httpx.Request, is_async: bool, **kwargs: Any
) -> RouteResultTypes:
# Add route kwarg if the side effect wants it
argspec = inspect.getfullargspec(effect)
Expand All @@ -338,7 +338,7 @@ def _call_side_effect(

try:
# Call side effect
result: RouteResultTypes = effect(request, **kwargs)
result: RouteResultTypes = effect(request, is_async, **kwargs)
Copy link
Owner

@lundberg lundberg May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fully backwards compatible, and not force users to change their existing side effects, I think we could be graceful here and only pass is_async among kwargs if the implemented side effect specs it, i.e. like the route kwarg is handled above.

e.g.

if "is_async" in argspec.args:
    kwargs["is_async"] = is_async

.. maybe handle both spec'ed as arg or kwarg 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, done.

except Exception as error:
raise SideEffectError(self, origin=error) from error

Expand All @@ -357,7 +357,7 @@ def _call_side_effect(
return result

def _resolve_side_effect(
self, request: httpx.Request, **kwargs: Any
self, request: httpx.Request, is_async: bool, **kwargs: Any
) -> RouteResultTypes:
effect = self._next_side_effect()

Expand All @@ -379,17 +379,17 @@ def _resolve_side_effect(

# Handle `Callable` side effect
elif callable(effect):
result = self._call_side_effect(effect, request, **kwargs)
result = self._call_side_effect(effect, request, is_async, **kwargs)
return result

# Resolved effect is a mocked response
return effect

def resolve(self, request: httpx.Request, **kwargs: Any) -> RouteResultTypes:
def resolve(self, request: httpx.Request, is_async: bool, **kwargs: Any) -> RouteResultTypes:
result: RouteResultTypes = None

if self._side_effect:
result = self._resolve_side_effect(request, **kwargs)
result = self._resolve_side_effect(request, is_async, **kwargs)
if result is None:
return None # Side effect resolved as a non-matching route

Expand All @@ -406,7 +406,7 @@ def resolve(self, request: httpx.Request, **kwargs: Any) -> RouteResultTypes:

return result

def match(self, request: httpx.Request) -> RouteResultTypes:
def match(self, request: httpx.Request, is_async: bool) -> RouteResultTypes:
"""
Matches and resolves request with given patterns and optional side effect.

Expand All @@ -424,7 +424,7 @@ def match(self, request: httpx.Request) -> RouteResultTypes:
if self._pass_through:
return request

result = self.resolve(request, **context)
result = self.resolve(request, is_async, **context)
return result


Expand Down
4 changes: 2 additions & 2 deletions respx/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def resolver(self, request: httpx.Request) -> Generator[ResolvedRoute, None, Non
def resolve(self, request: httpx.Request) -> ResolvedRoute:
with self.resolver(request) as resolved:
for route in self.routes:
prospect = route.match(request)
prospect = route.match(request, False)
if prospect is not None:
resolved.route = route
resolved.response = cast(ResolvedResponseTypes, prospect)
Expand All @@ -290,7 +290,7 @@ def resolve(self, request: httpx.Request) -> ResolvedRoute:
async def aresolve(self, request: httpx.Request) -> ResolvedRoute:
with self.resolver(request) as resolved:
for route in self.routes:
prospect: RouteResultTypes = route.match(request)
prospect: RouteResultTypes = route.match(request, True)

# Await async side effect and wrap any exception
if inspect.isawaitable(prospect):
Expand Down