Hello community,
here is the log from the commit of package python-responses for
openSUSE:Leap:15.2 checked in at 2020-03-29 14:55:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-responses (Old)
and /work/SRC/openSUSE:Leap:15.2/.python-responses.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-responses"
Sun Mar 29 14:55:46 2020 rev:16 rq:789145 version:0.10.12
Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-responses/python-responses.changes
2020-03-02 13:22:17.190270612 +0100
+++
/work/SRC/openSUSE:Leap:15.2/.python-responses.new.3160/python-responses.changes
2020-03-29 14:55:47.151162252 +0200
@@ -1,0 +2,22 @@
+Thu Mar 19 08:22:52 UTC 2020 - [email protected]
+
+- version update to 0.10.12
+ - Fixed incorrect content-type in `add_callback()` when headers are provided
as a list of tuples.
+ - Fixed invalid README formatted.
+ - Fixed string formatting in error message.
+ - Added Python 3.8 support
+ - Remove Python 3.4 from test suite matrix.
+ - The `response.request` object now has a `params` attribute that contains
the query string parameters from the request that was captured.
+ - `add_passthru` now supports `re` pattern objects to match URLs.
+ - ConnectionErrors raised by responses now include more details on the
request that was attempted and the mocks registered.
+ - Fixed regression with `add_callback()` and content-type header.
+ - Fixed implicit dependency on urllib3>1.23.0
+ - Fixed cookie parsing and enabled multiple cookies to be set by using a
list of
+ tuple values.
+ - Added pypi badges to README.
+ - Fixed formatting issues in README.
+ - Quoted cookie values are returned correctly now.
+ - Improved compatibility for pytest 5
+ - Module level method names are no longer generated dynamically improving
IDE navigation.
+
+-------------------------------------------------------------------
Old:
----
responses-0.10.6.tar.gz
New:
----
responses-0.10.12.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-responses.spec ++++++
--- /var/tmp/diff_new_pack.97BnqY/_old 2020-03-29 14:55:47.519162539 +0200
+++ /var/tmp/diff_new_pack.97BnqY/_new 2020-03-29 14:55:47.519162539 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-responses
#
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
#
# 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 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-responses
-Version: 0.10.6
+Version: 0.10.12
Release: 0
Summary: A utility library for mocking out the `requests` Python library
License: Apache-2.0
@@ -28,8 +28,8 @@
# test requirements
BuildRequires: %{python_module cookies}
BuildRequires: %{python_module mock}
-BuildRequires: %{python_module pytest < 5.0}
BuildRequires: %{python_module pytest-localserver}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module requests >= 2.0}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module six}
++++++ responses-0.10.6.tar.gz -> responses-0.10.12.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/CHANGES
new/responses-0.10.12/CHANGES
--- old/responses-0.10.6/CHANGES 2019-03-15 17:00:18.000000000 +0100
+++ new/responses-0.10.12/CHANGES 2020-03-03 03:50:19.000000000 +0100
@@ -1,3 +1,44 @@
+0.10.12
+-------
+
+- Fixed incorrect content-type in `add_callback()` when headers are provided
as a list of tuples.
+
+0.10.11
+-------
+
+- Fixed invalid README formatted.
+- Fixed string formatting in error message.
+
+0.10.10
+------
+
+- Added Python 3.8 support
+- Remove Python 3.4 from test suite matrix.
+- The `response.request` object now has a `params` attribute that contains the
query string parameters from the request that was captured.
+- `add_passthru` now supports `re` pattern objects to match URLs.
+- ConnectionErrors raised by responses now include more details on the request
that was attempted and the mocks registered.
+
+0.10.9
+------
+
+- Fixed regression with `add_callback()` and content-type header.
+- Fixed implicit dependency on urllib3>1.23.0
+
+0.10.8
+------
+
+- Fixed cookie parsing and enabled multiple cookies to be set by using a list
of
+ tuple values.
+
+0.10.7
+------
+
+- Added pypi badges to README.
+- Fixed formatting issues in README.
+- Quoted cookie values are returned correctly now.
+- Improved compatibility for pytest 5
+- Module level method names are no longer generated dynamically improving IDE
navigation.
+
0.10.6
------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/PKG-INFO
new/responses-0.10.12/PKG-INFO
--- old/responses-0.10.6/PKG-INFO 2019-03-15 17:01:04.000000000 +0100
+++ new/responses-0.10.12/PKG-INFO 2020-03-03 03:50:59.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: responses
-Version: 0.10.6
+Version: 0.10.12
Summary: A utility library for mocking out the `requests` Python library.
Home-page: https://github.com/getsentry/responses
Author: David Cramer
@@ -8,9 +8,15 @@
Description: Responses
=========
+ .. image:: https://img.shields.io/pypi/v/responses.svg
+ :target: https://pypi.python.org/pypi/responses/
+
.. image:: https://travis-ci.org/getsentry/responses.svg?branch=master
:target: https://travis-ci.org/getsentry/responses
+ .. image:: https://img.shields.io/pypi/pyversions/responses.svg
+ :target: https://pypi.org/project/responses/
+
A utility library for mocking out the `requests` Python library.
.. note::
@@ -240,6 +246,25 @@
)
+ You can see params passed in the original ``request`` in
``responses.calls[].request.params``:
+
+ .. code-block:: python
+
+ import responses
+ import requests
+
+ @responses.activate
+ def test_request_params():
+ responses.add(
+ method=responses.GET,
+ url="http://example.com?hello=world",
+ body="test",
+ match_querystring=False,
+ )
+
+ resp = requests.get('http://example.com', params={"hello":
"world"})
+ assert response.calls[0].request.params == {"hello": "world"}
+
Responses as a context manager
------------------------------
@@ -353,7 +378,7 @@
--------------------------
In some cases you may wish to allow for certain requests to pass thru
responses
- and hit a real server. This can be done with the 'passthru' methods:
+ and hit a real server. This can be done with the ``add_passthru``
methods:
.. code-block:: python
@@ -366,6 +391,12 @@
This will allow any requests matching that prefix, that is otherwise
not registered
as a mock response, to passthru using the standard behavior.
+ Regex can be used like:
+
+ .. code-block:: python
+
+ responses.add_passthru(re.compile('https://percy.io/\\w+'))
+
Viewing/Modifying registered responses
--------------------------------------
@@ -395,12 +426,10 @@
assert resp.json() == {'data': 2}
- ``remove`` takes a ``method`` and ``url`` argument and will remove
*all*
- matched ``response``s from the registered list.
-
- Finally, ``clear`` will reset all registered ``response``s
-
+ ``remove`` takes a ``method`` and ``url`` argument and will remove
**all**
+ matched responses from the registered list.
+ Finally, ``reset`` will reset all registered responses.
Contributing
------------
@@ -426,6 +455,19 @@
make develop
+ Responses uses `Pytest <https://docs.pytest.org/en/latest/>`_ for
+ testing. You can run all tests by:
+
+ .. code-block:: shell
+
+ pytest
+
+ And run a single test by:
+
+ .. code-block:: shell
+
+ pytest -k '<test_function_name>'
+
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
@@ -438,6 +480,8 @@
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Software Development
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Description-Content-Type: text/x-rst
Provides-Extra: tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/README.rst
new/responses-0.10.12/README.rst
--- old/responses-0.10.6/README.rst 2019-03-15 17:00:18.000000000 +0100
+++ new/responses-0.10.12/README.rst 2020-03-03 03:50:19.000000000 +0100
@@ -1,9 +1,15 @@
Responses
=========
+.. image:: https://img.shields.io/pypi/v/responses.svg
+ :target: https://pypi.python.org/pypi/responses/
+
.. image:: https://travis-ci.org/getsentry/responses.svg?branch=master
:target: https://travis-ci.org/getsentry/responses
+.. image:: https://img.shields.io/pypi/pyversions/responses.svg
+ :target: https://pypi.org/project/responses/
+
A utility library for mocking out the `requests` Python library.
.. note::
@@ -233,6 +239,25 @@
)
+You can see params passed in the original ``request`` in
``responses.calls[].request.params``:
+
+.. code-block:: python
+
+ import responses
+ import requests
+
+ @responses.activate
+ def test_request_params():
+ responses.add(
+ method=responses.GET,
+ url="http://example.com?hello=world",
+ body="test",
+ match_querystring=False,
+ )
+
+ resp = requests.get('http://example.com', params={"hello": "world"})
+ assert response.calls[0].request.params == {"hello": "world"}
+
Responses as a context manager
------------------------------
@@ -346,7 +371,7 @@
--------------------------
In some cases you may wish to allow for certain requests to pass thru responses
-and hit a real server. This can be done with the 'passthru' methods:
+and hit a real server. This can be done with the ``add_passthru`` methods:
.. code-block:: python
@@ -359,6 +384,12 @@
This will allow any requests matching that prefix, that is otherwise not
registered
as a mock response, to passthru using the standard behavior.
+Regex can be used like:
+
+.. code-block:: python
+
+ responses.add_passthru(re.compile('https://percy.io/\\w+'))
+
Viewing/Modifying registered responses
--------------------------------------
@@ -388,12 +419,10 @@
assert resp.json() == {'data': 2}
-``remove`` takes a ``method`` and ``url`` argument and will remove *all*
-matched ``response``s from the registered list.
-
-Finally, ``clear`` will reset all registered ``response``s
-
+``remove`` takes a ``method`` and ``url`` argument and will remove **all**
+matched responses from the registered list.
+Finally, ``reset`` will reset all registered responses.
Contributing
------------
@@ -418,3 +447,16 @@
.. code-block:: shell
make develop
+
+Responses uses `Pytest <https://docs.pytest.org/en/latest/>`_ for
+testing. You can run all tests by:
+
+.. code-block:: shell
+
+ pytest
+
+And run a single test by:
+
+.. code-block:: shell
+
+ pytest -k '<test_function_name>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/responses.egg-info/PKG-INFO
new/responses-0.10.12/responses.egg-info/PKG-INFO
--- old/responses-0.10.6/responses.egg-info/PKG-INFO 2019-03-15
17:01:04.000000000 +0100
+++ new/responses-0.10.12/responses.egg-info/PKG-INFO 2020-03-03
03:50:59.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: responses
-Version: 0.10.6
+Version: 0.10.12
Summary: A utility library for mocking out the `requests` Python library.
Home-page: https://github.com/getsentry/responses
Author: David Cramer
@@ -8,9 +8,15 @@
Description: Responses
=========
+ .. image:: https://img.shields.io/pypi/v/responses.svg
+ :target: https://pypi.python.org/pypi/responses/
+
.. image:: https://travis-ci.org/getsentry/responses.svg?branch=master
:target: https://travis-ci.org/getsentry/responses
+ .. image:: https://img.shields.io/pypi/pyversions/responses.svg
+ :target: https://pypi.org/project/responses/
+
A utility library for mocking out the `requests` Python library.
.. note::
@@ -240,6 +246,25 @@
)
+ You can see params passed in the original ``request`` in
``responses.calls[].request.params``:
+
+ .. code-block:: python
+
+ import responses
+ import requests
+
+ @responses.activate
+ def test_request_params():
+ responses.add(
+ method=responses.GET,
+ url="http://example.com?hello=world",
+ body="test",
+ match_querystring=False,
+ )
+
+ resp = requests.get('http://example.com', params={"hello":
"world"})
+ assert response.calls[0].request.params == {"hello": "world"}
+
Responses as a context manager
------------------------------
@@ -353,7 +378,7 @@
--------------------------
In some cases you may wish to allow for certain requests to pass thru
responses
- and hit a real server. This can be done with the 'passthru' methods:
+ and hit a real server. This can be done with the ``add_passthru``
methods:
.. code-block:: python
@@ -366,6 +391,12 @@
This will allow any requests matching that prefix, that is otherwise
not registered
as a mock response, to passthru using the standard behavior.
+ Regex can be used like:
+
+ .. code-block:: python
+
+ responses.add_passthru(re.compile('https://percy.io/\\w+'))
+
Viewing/Modifying registered responses
--------------------------------------
@@ -395,12 +426,10 @@
assert resp.json() == {'data': 2}
- ``remove`` takes a ``method`` and ``url`` argument and will remove
*all*
- matched ``response``s from the registered list.
-
- Finally, ``clear`` will reset all registered ``response``s
-
+ ``remove`` takes a ``method`` and ``url`` argument and will remove
**all**
+ matched responses from the registered list.
+ Finally, ``reset`` will reset all registered responses.
Contributing
------------
@@ -426,6 +455,19 @@
make develop
+ Responses uses `Pytest <https://docs.pytest.org/en/latest/>`_ for
+ testing. You can run all tests by:
+
+ .. code-block:: shell
+
+ pytest
+
+ And run a single test by:
+
+ .. code-block:: shell
+
+ pytest -k '<test_function_name>'
+
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
@@ -438,6 +480,8 @@
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Software Development
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Description-Content-Type: text/x-rst
Provides-Extra: tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/responses.egg-info/requires.txt
new/responses-0.10.12/responses.egg-info/requires.txt
--- old/responses-0.10.6/responses.egg-info/requires.txt 2019-03-15
17:01:04.000000000 +0100
+++ new/responses-0.10.12/responses.egg-info/requires.txt 2020-03-03
03:50:59.000000000 +0100
@@ -8,8 +8,13 @@
cookies
[tests]
-pytest
coverage<5.0.0,>=3.7.1
pytest-cov
pytest-localserver
flake8
+
+[tests:python_version < "3.5"]
+pytest<5.0,>=4.6
+
+[tests:python_version >= "3.5"]
+pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/responses.py
new/responses-0.10.12/responses.py
--- old/responses-0.10.6/responses.py 2019-03-15 17:00:18.000000000 +0100
+++ new/responses-0.10.12/responses.py 2020-03-03 03:50:19.000000000 +0100
@@ -23,6 +23,10 @@
from requests.packages.urllib3.response import HTTPResponse
except ImportError:
from urllib3.response import HTTPResponse
+try:
+ from requests.packages.urllib3.connection import HTTPHeaderDict
+except ImportError:
+ from urllib3.connection import HTTPHeaderDict
if six.PY2:
from urlparse import urlparse, parse_qsl, urlsplit, urlunsplit
@@ -104,6 +108,12 @@
)
+def _ensure_str(s):
+ if six.PY2:
+ s = s.encode("utf-8") if isinstance(s, six.text_type) else s
+ return s
+
+
def _cookies_from_headers(headers):
try:
import http.cookies as cookies
@@ -115,8 +125,10 @@
except ImportError:
from cookies import Cookies
- resp_cookies = Cookies.from_request(headers["set-cookie"])
- cookies_dict = {v.name: v.value for _, v in resp_cookies.items()}
+ resp_cookies = Cookies.from_request(_ensure_str(headers["set-cookie"]))
+ cookies_dict = {
+ v.name: quote(_ensure_str(v.value)) for _, v in
resp_cookies.items()
+ }
return cookiejar_from_dict(cookies_dict)
@@ -237,7 +249,7 @@
if self.method != other.method:
return False
- # Can't simply do a equality check on the objects directly here since
__eq__ isn't
+ # Can't simply do an equality check on the objects directly here since
__eq__ isn't
# implemented for regex. It might seem to work as regex is using a
cache to return
# the same regex instances, but it doesn't in all cases.
self_url = self.url.pattern if isinstance(self.url, Pattern) else
self.url
@@ -301,11 +313,11 @@
return False
def get_headers(self):
- headers = {}
+ headers = HTTPHeaderDict() # Duplicate headers are legal
if self.content_type is not None:
headers["Content-Type"] = self.content_type
if self.headers:
- headers.update(self.headers)
+ headers.extend(self.headers)
return headers
def get_response(self, request):
@@ -363,12 +375,12 @@
headers = self.get_headers()
status = self.status
body = _handle_body(self.body)
-
return HTTPResponse(
status=status,
reason=six.moves.http_client.responses.get(status),
body=body,
headers=headers,
+ original_response=OriginalResponseShim(headers),
preload_content=False,
)
@@ -393,18 +405,52 @@
if isinstance(body, Exception):
raise body
+ # If the callback set a content-type remove the one
+ # set in add_callback() so that we don't have multiple
+ # content type values.
+ has_content_type = False
+ if isinstance(r_headers, dict) and "Content-Type" in r_headers:
+ has_content_type = True
+ elif isinstance(r_headers, list):
+ has_content_type = any(
+ [h for h in r_headers if h and h[0].lower() == "content-type"]
+ )
+ if has_content_type:
+ headers.pop("Content-Type", None)
+
body = _handle_body(body)
- headers.update(r_headers)
+ headers.extend(r_headers)
return HTTPResponse(
status=status,
reason=six.moves.http_client.responses.get(status),
body=body,
headers=headers,
+ original_response=OriginalResponseShim(headers),
preload_content=False,
)
+class OriginalResponseShim(object):
+ """
+ Shim for compatibility with older versions of urllib3
+
+ requests cookie handling depends on responses having a property chain of
+ `response._original_response.msg` which contains the response headers [1]
+
+ Using HTTPResponse() for this purpose causes compatibility errors with
+ urllib3<1.23.0. To avoid adding more dependencies we can use this shim.
+
+ [1]:
https://github.com/psf/requests/blob/75bdc998e2d/requests/cookies.py#L125
+ """
+
+ def __init__(self, headers):
+ self.msg = headers
+
+ def isclosed(self):
+ return True
+
+
class RequestsMock(object):
DELETE = "DELETE"
GET = "GET"
@@ -488,14 +534,18 @@
def add_passthru(self, prefix):
"""
- Register a URL prefix to passthru any non-matching mock requests to.
+ Register a URL prefix or regex to passthru any non-matching mock
requests to.
For example, to allow any request to 'https://example.com', but require
mocks for the remainder, you would add the prefix as so:
>>> responses.add_passthru('https://example.com')
+
+ Regex can be used like:
+
+ >>> responses.add_passthru(re.compile('https://example.com/\\w+'))
"""
- if _has_unicode(prefix):
+ if not isinstance(prefix, Pattern) and _has_unicode(prefix):
prefix = _clean_unicode(prefix)
self.passthru_prefixes += (prefix,)
@@ -583,16 +633,30 @@
def _on_request(self, adapter, request, **kwargs):
match = self._find_match(request)
resp_callback = self.response_callback
+ request.params = dict(parse_qsl(request.path_url.replace("/?", "")))
if match is None:
- if request.url.startswith(self.passthru_prefixes):
+ if any(
+ [
+ p.match(request.url)
+ if isinstance(p, Pattern)
+ else request.url.startswith(p)
+ for p in self.passthru_prefixes
+ ]
+ ):
logger.info("request.allowed-passthru", extra={"url":
request.url})
return _real_send(adapter, request, **kwargs)
error_msg = (
- "Connection refused by Responses: {0} {1} doesn't "
- "match Responses Mock".format(request.method, request.url)
+ "Connection refused by Responses - the call doesn't "
+ "match any registered mock.\n\n"
+ "Request: \n"
+ "- %s %s\n\n"
+ "Available matches:\n" % (request.method, request.url)
)
+ for m in self._matches:
+ error_msg += "- {} {}\n".format(m.method, m.url)
+
response = ConnectionError(error_msg)
response.request = request
@@ -602,7 +666,7 @@
try:
response = adapter.build_response(request,
match.get_response(request))
- except Exception as response:
+ except BaseException as response:
match.call_count += 1
self._calls.add(request, response)
response = resp_callback(response) if resp_callback else response
@@ -611,11 +675,6 @@
if not match.stream:
response.content # NOQA
- try:
- response.cookies = _cookies_from_headers(response.headers)
- except (KeyError, TypeError):
- pass
-
response = resp_callback(response) if resp_callback else response
match.call_count += 1
self._calls.add(request, response)
@@ -647,7 +706,52 @@
# expose default mock namespace
mock = _default_mock = RequestsMock(assert_all_requests_are_fired=False)
-__all__ = ["CallbackResponse", "Response", "RequestsMock"]
-for __attr in (a for a in dir(_default_mock) if not a.startswith("_")):
- __all__.append(__attr)
- globals()[__attr] = getattr(_default_mock, __attr)
+__all__ = [
+ "CallbackResponse",
+ "Response",
+ "RequestsMock",
+ # Exposed by the RequestsMock class:
+ "activate",
+ "add",
+ "add_callback",
+ "add_passthru",
+ "assert_all_requests_are_fired",
+ "calls",
+ "DELETE",
+ "GET",
+ "HEAD",
+ "OPTIONS",
+ "passthru_prefixes",
+ "PATCH",
+ "POST",
+ "PUT",
+ "remove",
+ "replace",
+ "reset",
+ "response_callback",
+ "start",
+ "stop",
+ "target",
+]
+
+activate = _default_mock.activate
+add = _default_mock.add
+add_callback = _default_mock.add_callback
+add_passthru = _default_mock.add_passthru
+assert_all_requests_are_fired = _default_mock.assert_all_requests_are_fired
+calls = _default_mock.calls
+DELETE = _default_mock.DELETE
+GET = _default_mock.GET
+HEAD = _default_mock.HEAD
+OPTIONS = _default_mock.OPTIONS
+passthru_prefixes = _default_mock.passthru_prefixes
+PATCH = _default_mock.PATCH
+POST = _default_mock.POST
+PUT = _default_mock.PUT
+remove = _default_mock.remove
+replace = _default_mock.replace
+reset = _default_mock.reset
+response_callback = _default_mock.response_callback
+start = _default_mock.start
+stop = _default_mock.stop
+target = _default_mock.target
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/setup.py
new/responses-0.10.12/setup.py
--- old/responses-0.10.6/setup.py 2019-03-15 17:00:18.000000000 +0100
+++ new/responses-0.10.12/setup.py 2020-03-03 03:50:19.000000000 +0100
@@ -27,7 +27,8 @@
]
tests_require = [
- "pytest",
+ "pytest>=4.6,<5.0; python_version < '3.5'",
+ "pytest; python_version >= '3.5'",
"coverage >= 3.7.1, < 5.0.0",
"pytest-cov",
"pytest-localserver",
@@ -53,12 +54,13 @@
setup(
name="responses",
- version="0.10.6",
+ version="0.10.12",
author="David Cramer",
description=("A utility library for mocking out the `requests` Python
library."),
url="https://github.com/getsentry/responses",
license="Apache 2.0",
long_description=open("README.rst").read(),
+ long_description_content_type="text/x-rst",
py_modules=["responses"],
zip_safe=False,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
@@ -80,6 +82,7 @@
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
"Topic :: Software Development",
],
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/test_responses.py
new/responses-0.10.12/test_responses.py
--- old/responses-0.10.6/test_responses.py 2019-03-15 17:00:18.000000000
+0100
+++ new/responses-0.10.12/test_responses.py 2020-03-03 03:50:19.000000000
+0100
@@ -410,7 +410,11 @@
body = b"test callback"
status = 400
reason = "Bad Request"
- headers = {"foo": "bar"}
+ headers = {
+ "foo": "bar",
+ "Content-Type": "application/json",
+ "Content-Length": "13",
+ }
url = "http://example.com/"
def request_callback(request):
@@ -423,8 +427,9 @@
assert resp.text == "test callback"
assert resp.status_code == status
assert resp.reason == reason
- assert "foo" in resp.headers
- assert resp.headers["foo"] == "bar"
+ assert "bar" == resp.headers.get("foo")
+ assert "application/json" == resp.headers.get("Content-Type")
+ assert "13" == resp.headers.get("Content-Length")
run()
assert_reset()
@@ -494,6 +499,44 @@
assert_reset()
+def test_callback_content_type_dict():
+ def request_callback(request):
+ return (
+ 200,
+ {"Content-Type": "application/json"},
+ b"foo",
+ )
+
+ @responses.activate
+ def run():
+ responses.add_callback("GET", "http://mockhost/.foo",
callback=request_callback)
+ resp = requests.get("http://mockhost/.foo")
+ assert resp.text == "foo"
+ assert resp.headers["content-type"] == "application/json"
+
+ run()
+ assert_reset()
+
+
+def test_callback_content_type_tuple():
+ def request_callback(request):
+ return (
+ 200,
+ [("Content-Type", "application/json")],
+ b"foo",
+ )
+
+ @responses.activate
+ def run():
+ responses.add_callback("GET", "http://mockhost/.foo",
callback=request_callback)
+ resp = requests.get("http://mockhost/.foo")
+ assert resp.text == "foo"
+ assert resp.headers["content-type"] == "application/json"
+
+ run()
+ assert_reset()
+
+
def test_regular_expression_url():
@responses.activate
def run():
@@ -657,8 +700,56 @@
assert resp.status_code == status
assert "session_id" in resp.cookies
assert resp.cookies["session_id"] == "12345"
- assert resp.cookies["a"] == "b"
- assert resp.cookies["c"] == "d"
+ assert set(resp.cookies.keys()) == set(["session_id"])
+
+ run()
+ assert_reset()
+
+
+def test_response_secure_cookies():
+ body = b"test callback"
+ status = 200
+ headers = {"set-cookie": "session_id=12345; a=b; c=d; secure"}
+ url = "http://example.com/"
+
+ def request_callback(request):
+ return (status, headers, body)
+
+ @responses.activate
+ def run():
+ responses.add_callback(responses.GET, url, request_callback)
+ resp = requests.get(url)
+ assert resp.text == "test callback"
+ assert resp.status_code == status
+ assert "session_id" in resp.cookies
+ assert resp.cookies["session_id"] == "12345"
+ assert set(resp.cookies.keys()) == set(["session_id"])
+
+ run()
+ assert_reset()
+
+
+def test_response_cookies_multiple():
+ body = b"test callback"
+ status = 200
+ headers = [
+ ("set-cookie", "1P_JAR=2019-12-31-23; path=/; domain=.example.com;
HttpOnly"),
+ ("set-cookie", "NID=some=value; path=/; domain=.example.com; secure"),
+ ]
+ url = "http://example.com/"
+
+ def request_callback(request):
+ return (status, headers, body)
+
+ @responses.activate
+ def run():
+ responses.add_callback(responses.GET, url, request_callback)
+ resp = requests.get(url)
+ assert resp.text == "test callback"
+ assert resp.status_code == status
+ assert set(resp.cookies.keys()) == set(["1P_JAR", "NID"])
+ assert resp.cookies["1P_JAR"] == "2019-12-31-23"
+ assert resp.cookies["NID"] == "some=value"
run()
assert_reset()
@@ -696,12 +787,15 @@
def test_assert_all_requests_are_fired():
+ def request_callback(request):
+ raise BaseException()
+
def run():
with pytest.raises(AssertionError) as excinfo:
with responses.RequestsMock(assert_all_requests_are_fired=True) as
m:
m.add(responses.GET, "http://example.com", body=b"test")
assert "http://example.com" in str(excinfo.value)
- assert responses.GET in str(excinfo)
+ assert responses.GET in str(excinfo.value)
# check that assert_all_requests_are_fired default to True
with pytest.raises(AssertionError):
@@ -729,6 +823,13 @@
requests.get("http://example.com")
assert len(m._matches) == 1
+ with responses.RequestsMock(assert_all_requests_are_fired=True) as m:
+ m.add_callback(responses.GET, "http://example.com",
request_callback)
+ assert len(m._matches) == 1
+ with pytest.raises(BaseException):
+ requests.get("http://example.com")
+ assert len(m._matches) == 1
+
run()
assert_reset()
@@ -890,6 +991,28 @@
assert_reset()
+def test_passthru_regex(httpserver):
+ httpserver.serve_content("OK", headers={"Content-Type": "text/plain"})
+
+ @responses.activate
+ def run():
+ responses.add_passthru(re.compile("{}/\\w+".format(httpserver.url)))
+ responses.add(responses.GET, "{}/one".format(httpserver.url),
body="one")
+ responses.add(responses.GET, "http://example.com/two", body="two")
+
+ resp = requests.get("http://example.com/two")
+ assert_response(resp, "two")
+ resp = requests.get("{}/one".format(httpserver.url))
+ assert_response(resp, "one")
+ resp = requests.get("{}/two".format(httpserver.url))
+ assert_response(resp, "OK")
+ resp = requests.get("{}/three".format(httpserver.url))
+ assert_response(resp, "OK")
+
+ run()
+ assert_reset()
+
+
def test_method_named_param():
@responses.activate
def run():
@@ -922,3 +1045,40 @@
requests_mock.start()
assert len(patch_mock.call_args_list) == 1
assert patch_mock.call_args[1]["target"] == "something.else"
+
+
+def _quote(s):
+ return responses.quote(responses._ensure_str(s))
+
+
+def test_cookies_from_headers():
+ text = "こんにちは/世界"
+ quoted_text = _quote(text)
+ expected = {"x": "a", "y": quoted_text}
+ headers = {"set-cookie": "; ".join(k + "=" + v for k, v in
expected.items())}
+ cookiejar = responses._cookies_from_headers(headers)
+ for k, v in cookiejar.items():
+ assert isinstance(v, str)
+ assert v == expected[k]
+
+
+def test_request_param():
+ @responses.activate
+ def run():
+ params = {"hello": "world", "example": "params"}
+ responses.add(
+ method=responses.GET,
+ url="http://example.com?hello=world",
+ body="test",
+ match_querystring=False,
+ )
+ resp = requests.get("http://example.com", params=params)
+ assert_response(resp, "test")
+ assert resp.request.params == params
+
+ resp = requests.get("http://example.com")
+ assert_response(resp, "test")
+ assert resp.request.params == {}
+
+ run()
+ assert_reset()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/responses-0.10.6/tox.ini
new/responses-0.10.12/tox.ini
--- old/responses-0.10.6/tox.ini 2019-03-15 17:00:18.000000000 +0100
+++ new/responses-0.10.12/tox.ini 2020-03-03 03:50:19.000000000 +0100
@@ -1,5 +1,5 @@
[tox]
-envlist = py27,py34,py35,py36,py37
+envlist = py27,py34,py35,py36,py37,py38
[testenv]
extras = tests