Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: getsentry/responses
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.24.1
Choose a base ref
...
head repository: getsentry/responses
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.25.0
Choose a head ref
  • 7 commits
  • 8 files changed
  • 6 contributors

Commits on Nov 14, 2023

  1. Merge branch 'release/0.24.1'

    getsentry-bot committed Nov 14, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4fa24b7 View commit details

Commits on Dec 15, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7706191 View commit details

Commits on Dec 18, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6950c9e View commit details

Commits on Jan 10, 2024

  1. [README] Make "Validate Retry" code snippet complete (#701)

    It was missing the `urllib3.util.Retry` import.
    Priyansh121096 authored Jan 10, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    89d7f37 View commit details

Commits on Jan 30, 2024

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1f36f22 View commit details
  2. Update CHANGES for #702

    markstory committed Jan 30, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    dae83c4 View commit details

Commits on Feb 13, 2024

  1. release: 0.25.0

    getsentry-bot committed Feb 13, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    82d1e53 View commit details
Showing with 49 additions and 18 deletions.
  1. +1 −1 .github/workflows/ci.yml
  2. +7 −0 CHANGES
  3. +1 −0 README.rst
  4. +14 −13 responses/matchers.py
  5. +22 −1 responses/tests/test_matchers.py
  6. +1 −1 responses/tests/test_recorder.py
  7. +2 −1 setup.py
  8. +1 −1 tox.ini
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
requests-version: ['"requests>=2.0,<3.0"']
urllib3-version: ['"urllib3<2"', '"urllib3>=2,<3.0"']

7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
0.25.0
------

* Added support for Python 3.12
* Fixed `matchers.header_matcher` not failing when a matched header is missing from the request. See #702


0.24.1
------

1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1232,6 +1232,7 @@ If you are using the ``Retry`` features of ``urllib3`` and want to cover scenari
import responses
from responses import registries
from urllib3.util import Retry
@responses.activate(registry=registries.OrderedRegistry)
27 changes: 14 additions & 13 deletions responses/matchers.py
Original file line number Diff line number Diff line change
@@ -4,8 +4,9 @@
from json.decoder import JSONDecodeError
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import Mapping
from typing import MutableMapping
from typing import Optional
from typing import Pattern
from typing import Tuple
@@ -17,7 +18,7 @@
from urllib3.util.url import parse_url


def _create_key_val_str(input_dict: Union[Dict[Any, Any], Any]) -> str:
def _create_key_val_str(input_dict: Union[Mapping[Any, Any], Any]) -> str:
"""
Returns string of format {'key': val, 'key2': val2}
Function is called recursively for nested dictionaries
@@ -57,8 +58,8 @@ def list_to_str(input_list: List[str]) -> str:


def _filter_dict_recursively(
dict1: Dict[Any, Any], dict2: Dict[Any, Any]
) -> Dict[Any, Any]:
dict1: Mapping[Any, Any], dict2: Mapping[Any, Any]
) -> Mapping[Any, Any]:
filtered_dict = {}
for k, val in dict1.items():
if k in dict2:
@@ -70,7 +71,7 @@ def _filter_dict_recursively(


def urlencoded_params_matcher(
params: Optional[Dict[str, str]], *, allow_blank: bool = False
params: Optional[Mapping[str, str]], *, allow_blank: bool = False
) -> Callable[..., Any]:
"""
Matches URL encoded data
@@ -100,7 +101,7 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:


def json_params_matcher(
params: Optional[Union[Dict[str, Any], List[Any]]], *, strict_match: bool = True
params: Optional[Union[Mapping[str, Any], List[Any]]], *, strict_match: bool = True
) -> Callable[..., Any]:
"""Matches JSON encoded data of request body.
@@ -192,7 +193,7 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:


def query_param_matcher(
params: Optional[Dict[str, Any]], *, strict_match: bool = True
params: Optional[MutableMapping[str, Any]], *, strict_match: bool = True
) -> Callable[..., Any]:
"""Matcher to match 'params' argument in request.
@@ -276,7 +277,7 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:
return match


def request_kwargs_matcher(kwargs: Optional[Dict[str, Any]]) -> Callable[..., Any]:
def request_kwargs_matcher(kwargs: Optional[Mapping[str, Any]]) -> Callable[..., Any]:
"""
Matcher to match keyword arguments provided to request
@@ -308,7 +309,7 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:


def multipart_matcher(
files: Dict[str, Any], data: Optional[Dict[str, str]] = None
files: Mapping[str, Any], data: Optional[Mapping[str, str]] = None
) -> Callable[..., Any]:
"""
Matcher to match 'multipart/form-data' content-type.
@@ -392,7 +393,7 @@ def match(request: PreparedRequest) -> Tuple[bool, str]:


def header_matcher(
headers: Dict[str, Union[str, Pattern[str]]], strict_match: bool = False
headers: Mapping[str, Union[str, Pattern[str]]], strict_match: bool = False
) -> Callable[..., Any]:
"""
Matcher to match 'headers' argument in request using the responses library.
@@ -408,7 +409,7 @@ def header_matcher(
:return: (func) matcher
"""

def _compare_with_regex(request_headers: Union[Dict[Any, Any], Any]) -> bool:
def _compare_with_regex(request_headers: Union[Mapping[Any, Any], Any]) -> bool:
if strict_match and len(request_headers) != len(headers):
return False

@@ -420,13 +421,13 @@ def _compare_with_regex(request_headers: Union[Dict[Any, Any], Any]) -> bool:
else:
if not v == request_headers[k]:
return False
elif strict_match:
else:
return False

return True

def match(request: PreparedRequest) -> Tuple[bool, str]:
request_headers: Union[Dict[Any, Any], Any] = request.headers or {}
request_headers: Union[Mapping[Any, Any], Any] = request.headers or {}

if not strict_match:
# filter down to just the headers specified in the matcher
23 changes: 22 additions & 1 deletion responses/tests/test_matchers.py
Original file line number Diff line number Diff line change
@@ -626,7 +626,7 @@ def run():
assert_reset()


def test_request_matches_headers_no_match():
def test_request_header_value_mismatch_raises():
@responses.activate
def run():
url = "http://example.com/"
@@ -650,6 +650,27 @@ def run():
assert_reset()


def test_request_headers_missing_raises():
@responses.activate
def run():
url = "http://example.com/"
responses.add(
method=responses.GET,
url=url,
json={"success": True},
match=[matchers.header_matcher({"x-custom-header": "foo"})],
)

with pytest.raises(ConnectionError) as excinfo:
requests.get(url, headers={})

msg = str(excinfo.value)
assert ("Headers do not match: {} doesn't match {x-custom-header: foo}") in msg

run()
assert_reset()


def test_request_matches_headers_strict_match():
@responses.activate
def run():
2 changes: 1 addition & 1 deletion responses/tests/test_recorder.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
try:
import tomli as _toml
except ImportError:
# python 3.11
# python 3.11+
import tomllib as _toml # type: ignore[no-redef]


3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ def run_tests(self):

setup(
name="responses",
version="0.24.1",
version="0.25.0",
author="David Cramer",
description="A utility library for mocking out the `requests` Python library.",
url="https://github.com/getsentry/responses",
@@ -93,6 +93,7 @@ def run_tests(self):
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development",
],
)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py38,py39,py310,py311,mypy,precom
envlist = py38,py39,py310,py311,py312,mypy,precom

[pytest]
filterwarnings =