Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-responses for
openSUSE:Factory checked in at 2026-03-05 17:14:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-responses (Old)
and /work/SRC/openSUSE:Factory/.python-responses.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-responses"
Thu Mar 5 17:14:03 2026 rev:36 rq:1336245 version:0.26.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-responses/python-responses.changes
2025-09-25 18:44:46.020844380 +0200
+++
/work/SRC/openSUSE:Factory/.python-responses.new.561/python-responses.changes
2026-03-05 17:15:24.843312821 +0100
@@ -1,0 +2,11 @@
+Tue Mar 3 23:26:35 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.26.0:
+ * When using `assert_all_requests_are_fired=True`, assertions
+ about unfired requests are now raised even when an exception
+ occurs in the context manager or decorated function.
+ Previously, these assertions were suppressed when exceptions
+ occurred.
+ * Consider the `Retry-After` header when handling retries
+
+-------------------------------------------------------------------
Old:
----
responses-0.25.8.tar.gz
New:
----
responses-0.26.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-responses.spec ++++++
--- /var/tmp/diff_new_pack.cIjAnd/_old 2026-03-05 17:15:25.787352060 +0100
+++ /var/tmp/diff_new_pack.cIjAnd/_new 2026-03-05 17:15:25.791352226 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-responses
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-responses
-Version: 0.25.8
+Version: 0.26.0
Release: 0
Summary: A utility library for mocking out the `requests` Python library
License: Apache-2.0
++++++ responses-0.25.8.tar.gz -> responses-0.26.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/CHANGES new/responses-0.26.0/CHANGES
--- old/responses-0.25.8/CHANGES 2025-08-08 21:00:15.000000000 +0200
+++ new/responses-0.26.0/CHANGES 2026-02-19 15:36:42.000000000 +0100
@@ -1,3 +1,14 @@
+0.26.0
+------
+
+* When using `assert_all_requests_are_fired=True`, assertions about
+ unfired requests are now raised even when an exception occurs in the context
manager or
+ decorated function. Previously, these assertions were suppressed when
exceptions occurred.
+ This new behavior provides valuable debugging context about which mocked
requests were
+ or weren't called.
+* Consider the `Retry-After` header when handling retries
+
+
0.25.8
------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/PKG-INFO
new/responses-0.26.0/PKG-INFO
--- old/responses-0.25.8/PKG-INFO 2025-08-08 21:00:20.282436400 +0200
+++ new/responses-0.26.0/PKG-INFO 2026-02-19 15:36:52.756099500 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: responses
-Version: 0.25.8
+Version: 0.26.0
Summary: A utility library for mocking out the `requests` Python library.
Home-page: https://github.com/getsentry/responses
Author: David Cramer
@@ -9,7 +9,6 @@
Project-URL: Changes,
https://github.com/getsentry/responses/blob/master/CHANGES
Project-URL: Documentation,
https://github.com/getsentry/responses/blob/master/README.rst
Project-URL: Source Code, https://github.com/getsentry/responses
-Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
@@ -24,8 +23,34 @@
Classifier: Topic :: Software Development
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
-Provides-Extra: tests
License-File: LICENSE
+Requires-Dist: requests<3.0,>=2.30.0
+Requires-Dist: urllib3<3.0,>=1.25.10
+Requires-Dist: pyyaml
+Provides-Extra: tests
+Requires-Dist: pytest>=7.0.0; extra == "tests"
+Requires-Dist: coverage>=6.0.0; extra == "tests"
+Requires-Dist: pytest-cov; extra == "tests"
+Requires-Dist: pytest-asyncio; extra == "tests"
+Requires-Dist: pytest-httpserver; extra == "tests"
+Requires-Dist: flake8; extra == "tests"
+Requires-Dist: types-PyYAML; extra == "tests"
+Requires-Dist: types-requests; extra == "tests"
+Requires-Dist: mypy; extra == "tests"
+Requires-Dist: tomli; python_version < "3.11" and extra == "tests"
+Requires-Dist: tomli-w; extra == "tests"
+Dynamic: author
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: license
+Dynamic: license-file
+Dynamic: project-url
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
Responses
=========
@@ -946,6 +971,31 @@
content_type="application/json",
)
+When ``assert_all_requests_are_fired=True`` and an exception occurs within the
+context manager, assertions about unfired requests will still be raised. This
+provides valuable context about which mocked requests were or weren't called
+when debugging test failures.
+
+.. code-block:: python
+
+ import responses
+ import requests
+
+
+ def test_with_exception():
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as
rsps:
+ rsps.add(responses.GET, "http://example.com/users", body="test")
+ rsps.add(responses.GET, "http://example.com/profile", body="test")
+ requests.get("http://example.com/users")
+ raise ValueError("Something went wrong")
+
+ # Output:
+ # ValueError: Something went wrong
+ #
+ # During handling of the above exception, another exception occurred:
+ #
+ # AssertionError: Not all requests have been executed [('GET',
'http://example.com/profile')]
+
Assert Request Call Count
-------------------------
@@ -1548,5 +1598,3 @@
.. code-block:: shell
pre-commit run --all-files
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/README.rst
new/responses-0.26.0/README.rst
--- old/responses-0.25.8/README.rst 2025-08-08 21:00:15.000000000 +0200
+++ new/responses-0.26.0/README.rst 2026-02-19 15:36:42.000000000 +0100
@@ -917,6 +917,31 @@
content_type="application/json",
)
+When ``assert_all_requests_are_fired=True`` and an exception occurs within the
+context manager, assertions about unfired requests will still be raised. This
+provides valuable context about which mocked requests were or weren't called
+when debugging test failures.
+
+.. code-block:: python
+
+ import responses
+ import requests
+
+
+ def test_with_exception():
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as
rsps:
+ rsps.add(responses.GET, "http://example.com/users", body="test")
+ rsps.add(responses.GET, "http://example.com/profile", body="test")
+ requests.get("http://example.com/users")
+ raise ValueError("Something went wrong")
+
+ # Output:
+ # ValueError: Something went wrong
+ #
+ # During handling of the above exception, another exception occurred:
+ #
+ # AssertionError: Not all requests have been executed [('GET',
'http://example.com/profile')]
+
Assert Request Call Count
-------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/responses/__init__.py
new/responses-0.26.0/responses/__init__.py
--- old/responses-0.25.8/responses/__init__.py 2025-08-08 21:00:15.000000000
+0200
+++ new/responses-0.26.0/responses/__init__.py 2026-02-19 15:36:42.000000000
+0100
@@ -39,7 +39,7 @@
try:
from typing_extensions import Literal
except ImportError: # pragma: no cover
- from typing import Literal # type: ignore # pragma: no cover
+ from typing import Literal # pragma: no cover
from io import BufferedReader
from io import BytesIO
@@ -226,8 +226,8 @@
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
+ # set 'assert_all_requests_are_fired' temporarily for a
+ # single run. Mock automatically unsets to avoid leakage to
another decorated
# function since we still apply the value on 'responses.mock'
object
return func(*args, **kwargs)
@@ -991,9 +991,8 @@
return self
def __exit__(self, type: Any, value: Any, traceback: Any) -> None:
- success = type is None
try:
- self.stop(allow_assert=success)
+ self.stop(allow_assert=True)
finally:
self.reset()
@@ -1008,8 +1007,7 @@
registry: Type[Any] = ...,
assert_all_requests_are_fired: bool = ...,
) -> Callable[["_F"], "_F"]:
- """Overload for scenario when
- 'responses.activate(registry=, assert_all_requests_are_fired=True)' is
used.
+ """Overload for scenario when 'responses.activate(...)' is used.
See https://github.com/getsentry/responses/pull/469 for more details
"""
@@ -1051,7 +1049,10 @@
self, url: str
) -> Dict[str, Union[str, int, float, List[Optional[Union[str, int,
float]]]]]:
params: Dict[str, Union[str, int, float, List[Any]]] = {}
- for key, val in groupby(parse_qsl(urlsplit(url).query), lambda kv:
kv[0]):
+ for key, val in groupby(
+ parse_qsl(urlsplit(url).query, keep_blank_values=True),
+ lambda kv: kv[0],
+ ):
values = list(map(lambda x: x[1], val))
if len(values) == 1:
values = values[0] # type: ignore[assignment]
@@ -1151,7 +1152,9 @@
# first validate that current request is eligible to be retried.
# See ``urllib3.util.retry.Retry`` documentation.
if retries.is_retry(
- method=response.request.method, status_code=response.status_code
# type: ignore[misc]
+ method=response.request.method, # type: ignore[misc]
+ status_code=response.status_code, # type: ignore[misc]
+ has_retry_after="Retry-After" in response.headers, # type:
ignore[misc]
):
try:
retries = retries.increment(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/responses/tests/test_matchers.py
new/responses-0.26.0/responses/tests/test_matchers.py
--- old/responses-0.25.8/responses/tests/test_matchers.py 2025-08-08
21:00:15.000000000 +0200
+++ new/responses-0.26.0/responses/tests/test_matchers.py 2026-02-19
15:36:42.000000000 +0100
@@ -260,6 +260,24 @@
assert_reset()
+def test_query_param_matcher_empty_value():
+ @responses.activate
+ def run():
+ responses.add(
+ responses.GET,
+ "https://example.com/foo",
+ match=[
+ matchers.query_param_matcher({"bar": ""}),
+ ],
+ json={},
+ )
+ resp = requests.get("https://example.com/foo?bar=")
+ assert resp.status_code == 200
+
+ run()
+ assert_reset()
+
+
def test_query_param_matcher_loose():
@responses.activate
def run():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/responses/tests/test_responses.py
new/responses-0.26.0/responses/tests/test_responses.py
--- old/responses-0.25.8/responses/tests/test_responses.py 2025-08-08
21:00:15.000000000 +0200
+++ new/responses-0.26.0/responses/tests/test_responses.py 2026-02-19
15:36:42.000000000 +0100
@@ -1163,11 +1163,13 @@
with responses.RequestsMock() as m:
m.add(responses.GET, "http://example.com", body=b"test")
- # check that assert_all_requests_are_fired doesn't swallow exceptions
- with pytest.raises(ValueError):
+ # check that assert_all_requests_are_fired raises assertions even with
exceptions
+ with pytest.raises(AssertionError) as exc_info:
with responses.RequestsMock() as m:
m.add(responses.GET, "http://example.com", body=b"test")
raise ValueError()
+ # The ValueError should be chained as the context
+ assert isinstance(exc_info.value.__context__, ValueError)
# check that assert_all_requests_are_fired=True doesn't remove urls
with responses.RequestsMock(assert_all_requests_are_fired=True) as m:
@@ -1217,6 +1219,65 @@
assert_reset()
+def test_assert_all_requests_are_fired_during_exception():
+ """Test that assertions are raised even when an exception occurs."""
+
+ def run():
+ # Assertions WILL be raised even with an exception
+ # The AssertionError will be the primary exception, with the
ValueError as context
+ with pytest.raises(AssertionError) as assert_exc_info:
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as
m:
+ m.add(responses.GET, "http://example.com", body=b"test")
+ m.add(responses.GET, "http://not-called.com", body=b"test")
+ requests.get("http://example.com")
+ raise ValueError("Main error")
+
+ # The AssertionError should mention the unfired request
+ assert "not-called.com" in str(assert_exc_info.value)
+ # Python automatically chains exceptions, so we should see both in the
traceback
+ assert isinstance(assert_exc_info.value.__context__, ValueError)
+ assert "Main error" in str(assert_exc_info.value.__context__)
+
+ # Test that it also works normally when no other exception occurs
+ with pytest.raises(AssertionError) as assert_exc_info2:
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as
m:
+ m.add(responses.GET, "http://example.com", body=b"test")
+ m.add(responses.GET, "http://not-called.com", body=b"test")
+ requests.get("http://example.com")
+
+ assert "not-called.com" in str(assert_exc_info2.value)
+
+ run()
+ assert_reset()
+
+
+def test_assert_all_requests_are_fired_during_exception_with_decorator():
+ """Test that assertions are raised even when an exception occurs.
+
+ This tests the behavior with the @responses.activate decorator.
+ """
+
+ # Assertions WILL be raised even with an exception when using the decorator
+ with pytest.raises(AssertionError) as assert_exc_info:
+
+ @responses.activate(assert_all_requests_are_fired=True)
+ def test_with_exception():
+ responses.add(responses.GET, "http://example.com", body=b"test")
+ responses.add(responses.GET, "http://not-called.com", body=b"test")
+ requests.get("http://example.com")
+ raise ValueError("Main error")
+
+ test_with_exception()
+
+ # The AssertionError should mention the unfired request
+ assert "not-called.com" in str(assert_exc_info.value)
+ # Python automatically chains exceptions, so we should see both in the
traceback
+ assert isinstance(assert_exc_info.value.__context__, ValueError)
+ assert "Main error" in str(assert_exc_info.value.__context__)
+
+ assert_reset()
+
+
def test_allow_redirects_samehost():
redirecting_url = "http://example.com"
final_url_path = "/1"
@@ -2717,6 +2778,51 @@
run()
assert_reset()
+ def test_retry_with_retry_after_header(self):
+ """Validate that Retry-After header is detected and passed to retry
logic"""
+
+ @responses.activate(registry=registries.OrderedRegistry)
+ def run():
+ url = "https://example.com"
+ # Add responses with Retry-After header
+ rsp1 = responses.get(
+ url,
+ body="Error",
+ status=429,
+ headers={"Retry-After": "1"},
+ )
+ rsp2 = responses.get(
+ url,
+ body="Error",
+ status=429,
+ headers={"Retry-After": "1"},
+ )
+ rsp3 = responses.get(url, body="OK", status=200)
+
+ # Create session with retry configuration for 429 status
+ session = requests.Session()
+ adapter = requests.adapters.HTTPAdapter(
+ max_retries=Retry(
+ total=4,
+ backoff_factor=0.1,
+ status_forcelist=[429],
+ allowed_methods=["GET"],
+ raise_on_status=True,
+ respect_retry_after_header=True,
+ )
+ )
+ session.mount("https://", adapter)
+
+ resp = session.get(url)
+
+ assert resp.status_code == 200
+ assert rsp1.call_count == 1
+ assert rsp2.call_count == 1
+ assert rsp3.call_count == 1
+
+ run()
+ assert_reset()
+
def test_request_object_attached_to_exception():
"""Validate that we attach `request` object to custom exception supplied
as body"""
@@ -2729,7 +2835,7 @@
try:
requests.get(url, timeout=1)
except requests.ReadTimeout as exc:
- assert type(exc.request) == requests.models.PreparedRequest
+ assert isinstance(exc.request, requests.models.PreparedRequest)
run()
assert_reset()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/responses.egg-info/PKG-INFO
new/responses-0.26.0/responses.egg-info/PKG-INFO
--- old/responses-0.25.8/responses.egg-info/PKG-INFO 2025-08-08
21:00:20.000000000 +0200
+++ new/responses-0.26.0/responses.egg-info/PKG-INFO 2026-02-19
15:36:52.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: responses
-Version: 0.25.8
+Version: 0.26.0
Summary: A utility library for mocking out the `requests` Python library.
Home-page: https://github.com/getsentry/responses
Author: David Cramer
@@ -9,7 +9,6 @@
Project-URL: Changes,
https://github.com/getsentry/responses/blob/master/CHANGES
Project-URL: Documentation,
https://github.com/getsentry/responses/blob/master/README.rst
Project-URL: Source Code, https://github.com/getsentry/responses
-Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
@@ -24,8 +23,34 @@
Classifier: Topic :: Software Development
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
-Provides-Extra: tests
License-File: LICENSE
+Requires-Dist: requests<3.0,>=2.30.0
+Requires-Dist: urllib3<3.0,>=1.25.10
+Requires-Dist: pyyaml
+Provides-Extra: tests
+Requires-Dist: pytest>=7.0.0; extra == "tests"
+Requires-Dist: coverage>=6.0.0; extra == "tests"
+Requires-Dist: pytest-cov; extra == "tests"
+Requires-Dist: pytest-asyncio; extra == "tests"
+Requires-Dist: pytest-httpserver; extra == "tests"
+Requires-Dist: flake8; extra == "tests"
+Requires-Dist: types-PyYAML; extra == "tests"
+Requires-Dist: types-requests; extra == "tests"
+Requires-Dist: mypy; extra == "tests"
+Requires-Dist: tomli; python_version < "3.11" and extra == "tests"
+Requires-Dist: tomli-w; extra == "tests"
+Dynamic: author
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: license
+Dynamic: license-file
+Dynamic: project-url
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
Responses
=========
@@ -946,6 +971,31 @@
content_type="application/json",
)
+When ``assert_all_requests_are_fired=True`` and an exception occurs within the
+context manager, assertions about unfired requests will still be raised. This
+provides valuable context about which mocked requests were or weren't called
+when debugging test failures.
+
+.. code-block:: python
+
+ import responses
+ import requests
+
+
+ def test_with_exception():
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as
rsps:
+ rsps.add(responses.GET, "http://example.com/users", body="test")
+ rsps.add(responses.GET, "http://example.com/profile", body="test")
+ requests.get("http://example.com/users")
+ raise ValueError("Something went wrong")
+
+ # Output:
+ # ValueError: Something went wrong
+ #
+ # During handling of the above exception, another exception occurred:
+ #
+ # AssertionError: Not all requests have been executed [('GET',
'http://example.com/profile')]
+
Assert Request Call Count
-------------------------
@@ -1548,5 +1598,3 @@
.. code-block:: shell
pre-commit run --all-files
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.25.8/setup.py
new/responses-0.26.0/setup.py
--- old/responses-0.25.8/setup.py 2025-08-08 21:00:15.000000000 +0200
+++ new/responses-0.26.0/setup.py 2026-02-19 15:36:42.000000000 +0100
@@ -36,7 +36,7 @@
setup(
name="responses",
- version="0.25.8",
+ version="0.26.0",
author="David Cramer",
description="A utility library for mocking out the `requests` Python
library.",
url="https://github.com/getsentry/responses",