diff --git a/CHANGES b/CHANGES index 53f24de1..7ffb0075 100644 --- a/CHANGES +++ b/CHANGES @@ -1,8 +1,9 @@ 0.22.0 ------ -* Add `passthrough` argument to `BaseResponse` object. See #557 * Fix type for the `mock`'s patcher object. See #556 +* Add `passthrough` argument to `BaseResponse` object. See #557 +* Fix `registries` leak. See #563 0.21.0 ------ diff --git a/responses/__init__.py b/responses/__init__.py index ed5d97ee..5cde28d5 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -182,9 +182,6 @@ def get_wrapped( Wrapped function """ - if registry is not None: - responses._set_registry(registry) - assert_mock = std_mock.patch.object( target=responses, attribute="assert_all_requests_are_fired", @@ -196,6 +193,9 @@ def get_wrapped( @wraps(func) async def wrapper(*args: Any, **kwargs: Any) -> Any: # type: ignore[misc] + if registry is not None: + responses._set_registry(registry) + with assert_mock, responses: return await func(*args, **kwargs) @@ -204,6 +204,9 @@ async def wrapper(*args: Any, **kwargs: Any) -> Any: # type: ignore[misc] @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> Any: # type: ignore[misc] + if registry is not None: + responses._set_registry(registry) + with assert_mock, responses: # set 'assert_all_requests_are_fired' temporarily for a single run. # Mock automatically unsets to avoid leakage to another decorated diff --git a/responses/tests/test_registries.py b/responses/tests/test_registries.py index 4dd57652..2ab035b1 100644 --- a/responses/tests/test_registries.py +++ b/responses/tests/test_registries.py @@ -43,6 +43,44 @@ def run(): assert_reset() +def test_set_registry_reversed(): + """See https://github.com/getsentry/responses/issues/563""" + + class CustomRegistry(registries.FirstMatchRegistry): + pass + + @responses.activate + def run(): + # test that registry does not leak to another test + assert type(responses.mock.get_registry()) == registries.FirstMatchRegistry + + @responses.activate(registry=CustomRegistry) + def run_with_registry(): + assert type(responses.mock.get_registry()) == CustomRegistry + + run() + run_with_registry() + assert_reset() + + +async def test_registry_async(): + class CustomRegistry(registries.FirstMatchRegistry): + pass + + @responses.activate + async def run(): + # test that registry does not leak to another test + assert type(responses.mock.get_registry()) == registries.FirstMatchRegistry + + @responses.activate(registry=CustomRegistry) + async def run_with_registry(): + assert type(responses.mock.get_registry()) == CustomRegistry + + await run() + await run_with_registry() + assert_reset() + + def test_set_registry_context_manager(): def run(): class CustomRegistry(registries.FirstMatchRegistry):