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 2022-02-17 23:40:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-responses (Old)
 and      /work/SRC/openSUSE:Factory/.python-responses.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-responses"

Thu Feb 17 23:40:01 2022 rev:18 rq:955500 version:0.17.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-responses/python-responses.changes        
2021-12-09 19:45:04.281117718 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-responses.new.1958/python-responses.changes  
    2022-02-17 23:40:56.091700712 +0100
@@ -1,0 +2,18 @@
+Wed Feb 16 23:14:16 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.17.0:
+  * This release is the last to support Python 2.7.
+  * Fixed issue when `response.iter_content` when `chunk_size=None` entered 
infinite loop
+  * Fixed issue when `passthru_prefixes` persisted across tests.
+    Now `add_passthru` is valid only within a context manager or for a single 
function and
+    cleared on exit
+  * Deprecate `match_querystring` argument in `Response` and 
`CallbackResponse`.
+    Use `responses.matchers.query_param_matcher` or 
`responses.matchers.query_string_matcher`
+  * Added support for non-UTF-8 bytes in `responses.matchers.multipart_matcher`
+  * Added `responses.registries`. Now user can create custom registries to
+    manipulate the order of responses in the match algorithm
+    `responses.activate(registry=CustomRegistry)`
+  * Fixed issue with response match when requests were performed between 
adding responses with
+    same URL. See Issue #212
+
+-------------------------------------------------------------------

Old:
----
  responses-0.16.0.tar.gz

New:
----
  responses-0.17.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-responses.spec ++++++
--- /var/tmp/diff_new_pack.iRqrSR/_old  2022-02-17 23:40:56.623700707 +0100
+++ /var/tmp/diff_new_pack.iRqrSR/_new  2022-02-17 23:40:56.627700707 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-responses
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 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.16.0
+Version:        0.17.0
 Release:        0
 Summary:        A utility library for mocking out the `requests` Python library
 License:        Apache-2.0

++++++ responses-0.16.0.tar.gz -> responses-0.17.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/CHANGES new/responses-0.17.0/CHANGES
--- old/responses-0.16.0/CHANGES        2021-11-11 19:03:18.000000000 +0100
+++ new/responses-0.17.0/CHANGES        2022-01-07 17:18:13.000000000 +0100
@@ -1,3 +1,20 @@
+0.17.0
+------
+
+* This release is the last to support Python 2.7.
+* Fixed issue when `response.iter_content` when `chunk_size=None` entered 
infinite loop
+* Fixed issue when `passthru_prefixes` persisted across tests.
+  Now `add_passthru` is valid only within a context manager or for a single 
function and
+  cleared on exit
+* Deprecate `match_querystring` argument in `Response`` and `CallbackResponse`.
+  Use `responses.matchers.query_param_matcher` or 
`responses.matchers.query_string_matcher`
+* Added support for non-UTF-8 bytes in `responses.matchers.multipart_matcher`
+* Added `responses.registries`. Now user can create custom registries to
+  manipulate the order of responses in the match algorithm
+  `responses.activate(registry=CustomRegistry)`
+* Fixed issue with response match when requests were performed between adding 
responses with
+  same URL. See Issue #212
+
 0.16.0
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/MANIFEST.in 
new/responses-0.17.0/MANIFEST.in
--- old/responses-0.16.0/MANIFEST.in    2021-11-11 19:03:18.000000000 +0100
+++ new/responses-0.17.0/MANIFEST.in    2022-01-07 17:18:13.000000000 +0100
@@ -1,4 +1,5 @@
 include README.rst CHANGES LICENSE
-include test_responses.py tox.ini
+include test_responses.py test_matchers.py
 include **/*.pyi
+include tox.ini
 global-exclude *~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/PKG-INFO 
new/responses-0.17.0/PKG-INFO
--- old/responses-0.16.0/PKG-INFO       2021-11-11 19:03:24.265085000 +0100
+++ new/responses-0.17.0/PKG-INFO       2022-01-07 17:18:17.088163000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.16.0
+Version: 0.17.0
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer
@@ -129,6 +129,9 @@
     The full resource URL.
 
 match_querystring (``bool``)
+    DEPRECATED: Use `responses.matchers.query_param_matcher` or
+    `responses.matchers.query_string_matcher`
+
     Include the query string when matching requests.
     Enabled by default if the response URL contains a query string,
     disabled if it doesn't or the URL is a regular expression.
@@ -294,7 +297,7 @@
         req_files = {"file_name": b"Old World!"}
         responses.add(
             responses.POST, url="http://httpbin.org/post";,
-            match=[multipart_matcher(req_data, req_files)]
+            match=[multipart_matcher(req_files, data=req_data)]
         )
         resp = requests.post("http://httpbin.org/post";, files={"file_name": 
b"New World!"})
 
@@ -411,6 +414,49 @@
         resp = session.send(prepped)
         assert resp.text == "hello world"
 
+Response Registry
+---------------------------
+
+By default, ``responses`` will search all registered``Response`` objects and
+return a match. If only one ``Response`` is registered, the registry is kept 
unchanged.
+However, if multiple matches are found for the same request, then first match 
is returned and
+removed from registry.
+
+Such behavior is suitable for most of use cases, but to handle special 
conditions, you can
+implement custom registry which must follow interface of 
``registries.FirstMatchRegistry``.
+Redefining the ``find`` method will allow you to create custom search logic 
and return
+appropriate ``Response``
+
+Example that shows how to set custom registry
+
+.. code-block:: python
+
+    import responses
+    from responses import registries
+
+
+    class CustomRegistry(registries.FirstMatchRegistry):
+        pass
+
+
+    """ Before tests: <responses.registries.FirstMatchRegistry object> """
+
+    # using function decorator
+    @responses.activate(registry=CustomRegistry)
+    def run():
+        """ Within test: <__main__.CustomRegistry object> """
+
+    run()
+    """ After test: <responses.registries.FirstMatchRegistry object> """
+
+    # using context manager
+    with responses.RequestsMock(registry=CustomRegistry) as rsps:
+        """ In context manager: <__main__.CustomRegistry object> """
+
+    """
+    After exit from context manager: <responses.registries.FirstMatchRegistry 
object>
+    """
+
 Dynamic Responses
 -----------------
 
@@ -590,22 +636,26 @@
 
 .. code-block:: python
 
-    def setUp():
-        self.responses = responses.RequestsMock()
-        self.responses.start()
-
-        # self.responses.add(...)
-
-        self.addCleanup(self.responses.stop)
-        self.addCleanup(self.responses.reset)
+    class TestMyApi(unittest.TestCase):
+        def setUp(self):
+            responses.add(responses.GET, 'https://example.com', body="within 
setup")
+            # here go other self.responses.add(...)
+
+        @responses.activate
+        def test_my_func(self):
+            responses.add(
+                responses.GET,
+                "https://httpbin.org/get";,
+                match=[matchers.query_param_matcher({"test": "1", "didi": 
"pro"})],
+                body="within test"
+            )
+            resp = requests.get("https://example.com";)
+            resp2 = requests.get("https://httpbin.org/get";, params={"test": 
"1", "didi": "pro"})
+            print(resp.text)
+            # >>> within setup
+            print(resp2.text)
+            # >>> within test
 
-    def test_api(self):
-        self.responses.add(
-            responses.GET, 'http://twitter.com/api/1/foobar',
-            body='{}', status=200,
-            content_type='application/json')
-        resp = requests.get('http://twitter.com/api/1/foobar')
-        assert resp.status_code == 200
 
 Assertions on declared responses
 --------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/README.rst 
new/responses-0.17.0/README.rst
--- old/responses-0.16.0/README.rst     2021-11-11 19:03:18.000000000 +0100
+++ new/responses-0.17.0/README.rst     2022-01-07 17:18:13.000000000 +0100
@@ -102,6 +102,9 @@
     The full resource URL.
 
 match_querystring (``bool``)
+    DEPRECATED: Use `responses.matchers.query_param_matcher` or
+    `responses.matchers.query_string_matcher`
+
     Include the query string when matching requests.
     Enabled by default if the response URL contains a query string,
     disabled if it doesn't or the URL is a regular expression.
@@ -267,7 +270,7 @@
         req_files = {"file_name": b"Old World!"}
         responses.add(
             responses.POST, url="http://httpbin.org/post";,
-            match=[multipart_matcher(req_data, req_files)]
+            match=[multipart_matcher(req_files, data=req_data)]
         )
         resp = requests.post("http://httpbin.org/post";, files={"file_name": 
b"New World!"})
 
@@ -384,6 +387,49 @@
         resp = session.send(prepped)
         assert resp.text == "hello world"
 
+Response Registry
+---------------------------
+
+By default, ``responses`` will search all registered``Response`` objects and
+return a match. If only one ``Response`` is registered, the registry is kept 
unchanged.
+However, if multiple matches are found for the same request, then first match 
is returned and
+removed from registry.
+
+Such behavior is suitable for most of use cases, but to handle special 
conditions, you can
+implement custom registry which must follow interface of 
``registries.FirstMatchRegistry``.
+Redefining the ``find`` method will allow you to create custom search logic 
and return
+appropriate ``Response``
+
+Example that shows how to set custom registry
+
+.. code-block:: python
+
+    import responses
+    from responses import registries
+
+
+    class CustomRegistry(registries.FirstMatchRegistry):
+        pass
+
+
+    """ Before tests: <responses.registries.FirstMatchRegistry object> """
+
+    # using function decorator
+    @responses.activate(registry=CustomRegistry)
+    def run():
+        """ Within test: <__main__.CustomRegistry object> """
+
+    run()
+    """ After test: <responses.registries.FirstMatchRegistry object> """
+
+    # using context manager
+    with responses.RequestsMock(registry=CustomRegistry) as rsps:
+        """ In context manager: <__main__.CustomRegistry object> """
+
+    """
+    After exit from context manager: <responses.registries.FirstMatchRegistry 
object>
+    """
+
 Dynamic Responses
 -----------------
 
@@ -563,22 +609,26 @@
 
 .. code-block:: python
 
-    def setUp():
-        self.responses = responses.RequestsMock()
-        self.responses.start()
-
-        # self.responses.add(...)
-
-        self.addCleanup(self.responses.stop)
-        self.addCleanup(self.responses.reset)
+    class TestMyApi(unittest.TestCase):
+        def setUp(self):
+            responses.add(responses.GET, 'https://example.com', body="within 
setup")
+            # here go other self.responses.add(...)
+
+        @responses.activate
+        def test_my_func(self):
+            responses.add(
+                responses.GET,
+                "https://httpbin.org/get";,
+                match=[matchers.query_param_matcher({"test": "1", "didi": 
"pro"})],
+                body="within test"
+            )
+            resp = requests.get("https://example.com";)
+            resp2 = requests.get("https://httpbin.org/get";, params={"test": 
"1", "didi": "pro"})
+            print(resp.text)
+            # >>> within setup
+            print(resp2.text)
+            # >>> within test
 
-    def test_api(self):
-        self.responses.add(
-            responses.GET, 'http://twitter.com/api/1/foobar',
-            body='{}', status=200,
-            content_type='application/json')
-        resp = requests.get('http://twitter.com/api/1/foobar')
-        assert resp.status_code == 200
 
 Assertions on declared responses
 --------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/__init__.py 
new/responses-0.17.0/responses/__init__.py
--- old/responses-0.16.0/responses/__init__.py  2021-11-11 19:03:18.000000000 
+0100
+++ new/responses-0.17.0/responses/__init__.py  2022-01-07 17:18:13.000000000 
+0100
@@ -16,6 +16,8 @@
 from requests.utils import cookiejar_from_dict
 from responses.matchers import json_params_matcher as _json_params_matcher
 from responses.matchers import urlencoded_params_matcher as 
_urlencoded_params_matcher
+from responses.registries import FirstMatchRegistry
+from responses.matchers import query_string_matcher as _query_string_matcher
 from warnings import warn
 
 try:
@@ -76,6 +78,13 @@
 
 logger = logging.getLogger("responses")
 
+if six.PY2:
+    warn(
+        "Support for Python 2.7 is being removed from the next release of 
responses. "
+        "Pin your dependency to responses==0.17 or lower.",
+        DeprecationWarning,
+    )
+
 
 def urlencoded_params_matcher(params):
     warn(
@@ -156,7 +165,7 @@
 """
 
 
-def get_wrapped(func, responses):
+def get_wrapped(func, responses, registry=None):
     if six.PY2:
         args, a, kw, defaults = inspect.getargspec(func)
         wrapper_args = inspect.formatargspec(args, a, kw, defaults)
@@ -193,6 +202,9 @@
         signature = signature.replace(parameters=params_without_defaults)
         func_args = str(signature)
 
+    if registry is not None:
+        responses._set_registry(registry)
+
     evaldict = {"func": func, "responses": responses}
     six.exec_(
         _wrapper_template % {"wrapper_args": wrapper_args, "func_args": 
func_args},
@@ -246,10 +258,35 @@
     if isinstance(body, _io.BufferedReader):
         return body
 
-    return BufferIO(body)
+    data = BufferIO(body)
+
+    def is_closed():
+        """
+        Real Response uses HTTPResponse as body object.
+        Thus, when method is_closed is called first to check if there is any 
more
+        content to consume and the file-like object is still opened
+
+        This method ensures stability to work for both:
+        https://github.com/getsentry/responses/issues/438
+        https://github.com/getsentry/responses/issues/394
+
+        where file should be intentionally be left opened to continue 
consumption
+        """
+        if not data.closed and data.read(1):
+            # if there is more bytes to read then keep open, but return pointer
+            data.seek(-1, 1)
+            return False
+        else:
+            if not data.closed:
+                # close but return False to mock like is still opened
+                data.close()
+                return False
 
+            # only if file really closed (by us) return True
+            return True
 
-_unspecified = object()
+    data.isclosed = is_closed
+    return data
 
 
 class BaseResponse(object):
@@ -259,11 +296,14 @@
 
     stream = False
 
-    def __init__(self, method, url, match_querystring=_unspecified, match=()):
+    def __init__(self, method, url, match_querystring=None, match=()):
         self.method = method
         # ensure the url has a default path set if the url is a string
         self.url = _ensure_url_default_path(url)
-        self.match_querystring = 
self._should_match_querystring(match_querystring)
+
+        if self._should_match_querystring(match_querystring):
+            match = tuple(match) + 
(_query_string_matcher(urlparse(self.url).query),)
+
         self.match = match
         self.call_count = 0
 
@@ -285,40 +325,32 @@
     def __ne__(self, other):
         return not self.__eq__(other)
 
-    def _url_matches_strict(self, url, other):
-        url_parsed = urlparse(url)
-        other_parsed = urlparse(other)
-
-        if url_parsed[:3] != other_parsed[:3]:
-            return False
-
-        url_qsl = sorted(parse_qsl(url_parsed.query))
-        other_qsl = sorted(parse_qsl(other_parsed.query))
-
-        return url_qsl == other_qsl
-
     def _should_match_querystring(self, match_querystring_argument):
-        if match_querystring_argument is not _unspecified:
-            return match_querystring_argument
-
         if isinstance(self.url, Pattern):
             # the old default from <= 0.9.0
             return False
 
+        if match_querystring_argument is not None:
+            warn(
+                (
+                    "Argument 'match_querystring' is deprecated. "
+                    "Use 'responses.matchers.query_param_matcher' or "
+                    "'responses.matchers.query_string_matcher'"
+                ),
+                DeprecationWarning,
+            )
+            return match_querystring_argument
+
         return bool(urlparse(self.url).query)
 
-    def _url_matches(self, url, other, match_querystring=False):
+    def _url_matches(self, url, other):
         if _is_string(url):
             if _has_unicode(url):
                 url = _clean_unicode(url)
                 if not isinstance(other, six.text_type):
                     other = other.encode("ascii").decode("utf8")
 
-            if match_querystring:
-                normalize_url = parse_url(url).url
-                return self._url_matches_strict(normalize_url, other)
-            else:
-                return _get_url_and_path(url) == _get_url_and_path(other)
+            return _get_url_and_path(url) == _get_url_and_path(other)
 
         elif isinstance(url, Pattern) and url.match(other):
             return True
@@ -350,7 +382,7 @@
         if request.method != self.method:
             return False, "Method does not match"
 
-        if not self._url_matches(self.url, request.url, 
self.match_querystring):
+        if not self._url_matches(self.url, request.url):
             return False, "URL does not match"
 
         valid, reason = self._req_attr_matches(self.match, request)
@@ -535,17 +567,35 @@
         response_callback=None,
         passthru_prefixes=(),
         target="requests.adapters.HTTPAdapter.send",
+        registry=FirstMatchRegistry,
     ):
         self._calls = CallList()
         self.reset()
+        self._registry = registry()  # call only after reset
         self.assert_all_requests_are_fired = assert_all_requests_are_fired
         self.response_callback = response_callback
         self.passthru_prefixes = tuple(passthru_prefixes)
         self.target = target
+        self._patcher = None
+        self._matches = []
+
+    def _get_registry(self):
+        return self._registry
+
+    def _set_registry(self, new_registry):
+        if self.registered():
+            err_msg = (
+                "Cannot replace Registry, current registry has responses.\n"
+                "Run 'responses.registry.reset()' first"
+            )
+            raise AttributeError(err_msg)
+
+        self._registry = new_registry()
 
     def reset(self):
-        self._matches = []
+        self._registry = FirstMatchRegistry()
         self._calls.reset()
+        self.passthru_prefixes = ()
 
     def add(
         self,
@@ -557,8 +607,9 @@
         **kwargs
     ):
         """
-        A basic request:
+        >>> import responses
 
+        A basic request:
         >>> responses.add(responses.GET, 'http://example.com')
 
         You can also directly pass an object which implements the
@@ -582,23 +633,15 @@
         >>>     headers={'X-Header': 'foo'},
         >>> )
 
-
-        Strict query string matching:
-
-        >>> responses.add(
-        >>>     method='GET',
-        >>>     url='http://example.com?foo=bar',
-        >>>     match_querystring=True
-        >>> )
         """
         if isinstance(method, BaseResponse):
-            self._matches.append(method)
+            self._registry.add(method)
             return
 
         if adding_headers is not None:
             kwargs.setdefault("headers", adding_headers)
 
-        self._matches.append(Response(method=method, url=url, body=body, 
**kwargs))
+        self._registry.add(Response(method=method, url=url, body=body, 
**kwargs))
 
     def add_passthru(self, prefix):
         """
@@ -607,6 +650,7 @@
         For example, to allow any request to 'https://example.com', but require
         mocks for the remainder, you would add the prefix as so:
 
+        >>> import responses
         >>> responses.add_passthru('https://example.com')
 
         Regex can be used like:
@@ -623,16 +667,16 @@
         either by a response object inheriting ``BaseResponse`` or
         ``method`` and ``url``. Removes all matching responses.
 
-        >>> response.add(responses.GET, 'http://example.org')
-        >>> response.remove(responses.GET, 'http://example.org')
+        >>> import responses
+        >>> responses.add(responses.GET, 'http://example.org')
+        >>> responses.remove(responses.GET, 'http://example.org')
         """
         if isinstance(method_or_response, BaseResponse):
             response = method_or_response
         else:
             response = BaseResponse(method=method_or_response, url=url)
 
-        while response in self._matches:
-            self._matches.remove(response)
+        self._registry.remove(response)
 
     def replace(self, method_or_response=None, url=None, body="", *args, 
**kwargs):
         """
@@ -640,6 +684,7 @@
         is identical to ``add()``. The response is identified using ``method``
         and ``url``, and the first matching response is replaced.
 
+        >>> import responses
         >>> responses.add(responses.GET, 'http://example.org', json={'data': 
1})
         >>> responses.replace(responses.GET, 'http://example.org', 
json={'data': 2})
         """
@@ -649,11 +694,7 @@
         else:
             response = Response(method=method_or_response, url=url, body=body, 
**kwargs)
 
-        try:
-            index = self._matches.index(response)
-        except ValueError:
-            raise ValueError("Response is not registered for URL %s" % url)
-        self._matches[index] = response
+        self._registry.replace(response)
 
     def upsert(self, method_or_response=None, url=None, body="", *args, 
**kwargs):
         """
@@ -661,6 +702,7 @@
         if no response exists.  Responses are matched using ``method``and 
``url``.
         The first matching response is replaced.
 
+        >>> import responses
         >>> responses.add(responses.GET, 'http://example.org', json={'data': 
1})
         >>> responses.upsert(responses.GET, 'http://example.org', 
json={'data': 2})
         """
@@ -681,7 +723,7 @@
         # ensure the url has a default path set if the url is a string
         # url = _ensure_url_default_path(url, match_querystring)
 
-        self._matches.append(
+        self._registry.add(
             CallbackResponse(
                 url=url,
                 method=method,
@@ -693,7 +735,7 @@
         )
 
     def registered(self):
-        return self._matches
+        return self._registry.registered
 
     @property
     def calls(self):
@@ -709,8 +751,14 @@
         self.reset()
         return success
 
-    def activate(self, func):
-        return get_wrapped(func, self)
+    def activate(self, func=None, registry=None):
+        if func is not None:
+            return get_wrapped(func, self)
+
+        def deco_activate(func):
+            return get_wrapped(func, self, registry)
+
+        return deco_activate
 
     def _find_match(self, request):
         """
@@ -721,21 +769,7 @@
             (Response) found match. If multiple found, then remove & return 
the first match.
             (list) list with reasons why other matches don't match
         """
-        found = None
-        found_match = None
-        match_failed_reasons = []
-        for i, match in enumerate(self._matches):
-            match_result, reason = match.matches(request)
-            if match_result:
-                if found is None:
-                    found = i
-                    found_match = match
-                else:
-                    # Multiple matches found.  Remove & return the first match.
-                    return self._matches.pop(found), match_failed_reasons
-            else:
-                match_failed_reasons.append(reason)
-        return found_match, match_failed_reasons
+        return self._registry.find(request)
 
     def _parse_request_params(self, url):
         params = {}
@@ -774,7 +808,7 @@
                 "- %s %s\n\n"
                 "Available matches:\n" % (request.method, request.url)
             )
-            for i, m in enumerate(self._matches):
+            for i, m in enumerate(self.registered()):
                 error_msg += "- {} {} {}\n".format(
                     m.method, m.url, match_failed_reasons[i]
                 )
@@ -798,11 +832,6 @@
                 response = resp_callback(response) if resp_callback else 
response
                 raise
 
-        stream = kwargs.get("stream")
-        if not stream:
-            response.content  # NOQA required to ensure that response body is 
read.
-            response.close()
-
         response = resp_callback(response) if resp_callback else response
         match.call_count += 1
         self._calls.add(request, response)
@@ -823,7 +852,7 @@
         if not allow_assert:
             return
 
-        not_called = [m for m in self._matches if m.call_count == 0]
+        not_called = [m for m in self.registered() if m.call_count == 0]
         if not_called:
             raise AssertionError(
                 "Not all requests have been executed {0!r}".format(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/__init__.pyi 
new/responses-0.17.0/responses/__init__.pyi
--- old/responses-0.16.0/responses/__init__.pyi 2021-11-11 19:03:18.000000000 
+0100
+++ new/responses-0.17.0/responses/__init__.pyi 2022-01-07 17:18:13.000000000 
+0100
@@ -23,6 +23,7 @@
 from urllib.parse import quote as quote
 from urllib3.response import HTTPHeaderDict
 from .matchers import urlencoded_params_matcher, json_params_matcher
+from .registries import FirstMatchRegistry
 
 
 def _clean_unicode(url: str) -> str: ...
@@ -38,7 +39,7 @@
 def _has_unicode(s: str) -> bool: ...
 def _is_string(s: Union[Pattern[str], str]) -> bool: ...
 def get_wrapped(
-    func: Callable[..., Any], responses: RequestsMock
+    func: Callable[..., Any], responses: RequestsMock, registry: Optional[Any]
 ) -> Callable[..., Any]: ...
 
 
@@ -51,7 +52,9 @@
 MatcherIterable = Iterable[Callable[[Any], Callable[..., Any]]]
 
 class CallList(Sequence[Call], Sized):
-    def __init__(self) -> None: ...
+    def __init__(self) -> None:
+        self._calls = List[Call]
+        ...
     def __iter__(self) -> Iterator[Call]: ...
     def __len__(self) -> int: ...
     def __getitem__(self, idx: int) -> Call: ...  # type: ignore [override]
@@ -78,7 +81,7 @@
     def __eq__(self, other: Any) -> bool: ...
     def __ne__(self, other: Any) -> bool: ...
     def _req_attr_matches(
-        self, match: MatcherIterable, request: Optional[Union[bytes, str]]
+        self, match: MatcherIterable, request: PreparedRequest
     ) -> Tuple[bool, str]: ...
     def _should_match_querystring(
         self, match_querystring_argument: Union[bool, object]
@@ -144,6 +147,8 @@
     ) -> None: ...
     def isclosed(self) -> bool: ...
 
+_F = TypeVar("_F", bound=Callable[..., Any])
+
 class RequestsMock:
     DELETE: Literal["DELETE"]
     GET: Literal["GET"]
@@ -154,7 +159,7 @@
     PUT: Literal["PUT"]
     response_callback: Optional[Callable[[Any], Any]] = ...
     assert_all_requests_are_fired: Any = ...
-    passthru_prefixes: Tuple[str, ...] = ...
+    passthru_prefixes: Tuple[Union[str, Pattern[str]], ...] = ...
     target: Any = ...
     _matches: List[Any]
     def __init__(
@@ -163,7 +168,11 @@
         response_callback: Optional[Callable[[Any], Any]] = ...,
         passthru_prefixes: Tuple[str, ...] = ...,
         target: str = ...,
-    ) -> None: ...
+        registry: Any = ...,
+    ) -> None:
+        self._patcher = Callable[[Any], Any]
+        self._calls = CallList
+        ...
     def reset(self) -> None: ...
     add: _Add
     add_passthru: _AddPassthru
@@ -173,24 +182,23 @@
         url: Optional[Union[Pattern[str], str]] = ...,
     ) -> None: ...
     replace: _Replace
+    upsert: _Upsert
     add_callback: _AddCallback
     @property
     def calls(self) -> CallList: ...
     def __enter__(self) -> RequestsMock: ...
     def __exit__(self, type: Any, value: Any, traceback: Any) -> bool: ...
-    activate: _Activate
+    def activate(self, func: Optional[_F], registry: Optional[Any]) -> _F: ...
     def start(self) -> None: ...
     def stop(self, allow_assert: bool = ...) -> None: ...
     def assert_call_count(self, url: str, count: int) -> bool: ...
     def registered(self) -> List[Any]: ...
+    def _set_registry(self, registry: Any) -> None: ...
+    def _get_registry(self) -> Any: ...
 
-_F = TypeVar("_F", bound=Callable[..., Any])
 
 HeaderSet = Optional[Union[Mapping[str, str], List[Tuple[str, str]]]]
 
-class _Activate(Protocol):
-    def __call__(self, func: _F) -> _F: ...
-
 class _Add(Protocol):
     def __call__(
         self,
@@ -267,7 +275,7 @@
     def __call__(self) -> List[Response]: ...
 
 
-activate: _Activate
+activate: Any
 add: _Add
 add_callback: _AddCallback
 add_passthru: _AddPassthru
@@ -322,5 +330,5 @@
     "start",
     "stop",
     "target",
-    "upsert"
+    "upsert",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/matchers.py 
new/responses-0.17.0/responses/matchers.py
--- old/responses-0.16.0/responses/matchers.py  2021-11-11 19:03:18.000000000 
+0100
+++ new/responses-0.17.0/responses/matchers.py  2022-01-07 17:18:13.000000000 
+0100
@@ -175,14 +175,16 @@
     :param query: (str), same as constructed by request
     :return: (func) matcher
     """
+    if six.PY2 and isinstance(query, unicode):  # noqa: F821
+        query = query.encode("utf8")
 
     def match(request):
         reason = ""
         data = parse_url(request.url)
         request_query = data.query
 
-        request_qsl = sorted(parse_qsl(request_query))
-        matcher_qsl = sorted(parse_qsl(query))
+        request_qsl = sorted(parse_qsl(request_query)) if request_query else {}
+        matcher_qsl = sorted(parse_qsl(query)) if query else {}
 
         valid = not query if request_query is None else request_qsl == 
matcher_qsl
 
@@ -275,12 +277,12 @@
         )
 
         request_body = request.body
-        if isinstance(request_body, bytes):
-            request_body = request_body.decode("utf-8")
-
         prepared_body = prepared.body
+
         if isinstance(prepared_body, bytes):
-            prepared_body = prepared_body.decode("utf-8")
+            # since headers always come as str, need to convert to bytes
+            prepared_boundary = prepared_boundary.encode("utf-8")
+            request_boundary = request_boundary.encode("utf-8")
 
         prepared_body = prepared_body.replace(prepared_boundary, 
request_boundary)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/registries.py 
new/responses-0.17.0/responses/registries.py
--- old/responses-0.16.0/responses/registries.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/responses-0.17.0/responses/registries.py        2022-01-07 
17:18:13.000000000 +0100
@@ -0,0 +1,48 @@
+class FirstMatchRegistry(object):
+    def __init__(self):
+        self._responses = []
+
+    @property
+    def registered(self):
+        return self._responses
+
+    def reset(self):
+        self._responses = []
+
+    def find(self, request):
+        found = None
+        found_match = None
+        match_failed_reasons = []
+        for i, response in enumerate(self.registered):
+            match_result, reason = response.matches(request)
+            if match_result:
+                if found is None:
+                    found = i
+                    found_match = response
+                else:
+                    if self.registered[found].call_count > 0:
+                        # that assumes that some responses were added between 
calls
+                        self.registered.pop(found)
+                        found_match = response
+                        break
+                    # Multiple matches found.  Remove & return the first 
response.
+                    return self.registered.pop(found), match_failed_reasons
+            else:
+                match_failed_reasons.append(reason)
+        return found_match, match_failed_reasons
+
+    def add(self, response):
+        self.registered.append(response)
+
+    def remove(self, response):
+        while response in self.registered:
+            self.registered.remove(response)
+
+    def replace(self, response):
+        try:
+            index = self.registered.index(response)
+        except ValueError:
+            raise ValueError(
+                "Response is not registered for URL {}".format(response.url)
+            )
+        self.registered[index] = response
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/registries.pyi 
new/responses-0.17.0/responses/registries.pyi
--- old/responses-0.16.0/responses/registries.pyi       1970-01-01 
01:00:00.000000000 +0100
+++ new/responses-0.17.0/responses/registries.pyi       2022-01-07 
17:18:13.000000000 +0100
@@ -0,0 +1,17 @@
+from typing import (
+    List,
+    Tuple,
+)
+from requests.adapters import PreparedRequest
+from responses import BaseResponse
+
+class FirstMatchRegistry:
+    _responses = List[BaseResponse]
+    def __init__(self) -> None: ...
+    @property
+    def registered(self) -> List[BaseResponse]: ...
+    def reset(self) -> None: ...
+    def find(self, request: PreparedRequest) -> Tuple[BaseResponse, 
List[str]]: ...
+    def add(self, response: BaseResponse) -> None: ...
+    def remove(self, response: BaseResponse) -> None: ...
+    def replace(self, response: BaseResponse) -> None: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/test_matchers.py 
new/responses-0.17.0/responses/test_matchers.py
--- old/responses-0.16.0/responses/test_matchers.py     2021-11-11 
19:03:18.000000000 +0100
+++ new/responses-0.17.0/responses/test_matchers.py     2022-01-07 
17:18:13.000000000 +0100
@@ -18,7 +18,7 @@
 
 
 def assert_reset():
-    assert len(responses._default_mock._matches) == 0
+    assert len(responses._default_mock.registered()) == 0
     assert len(responses.calls) == 0
 
 
@@ -283,17 +283,32 @@
     assert_reset()
 
 
-def test_multipart_matcher():
+@pytest.mark.parametrize(
+    "req_file,match_file",
+    [
+        (b"Old World!", "Old World!"),
+        ("Old World!", b"Old World!"),
+        (b"Old World!", b"Old World!"),
+        ("Old World!", "Old World!"),
+        (b"\xacHello World!", b"\xacHello World!"),
+    ],
+)
+def test_multipart_matcher(req_file, match_file):
     @responses.activate
     def run():
         req_data = {"some": "other", "data": "fields"}
-        req_files = {"file_name": b"Old World!"}
         responses.add(
             responses.POST,
             url="http://httpbin.org/post";,
-            match=[matchers.multipart_matcher(req_files, data=req_data)],
+            match=[
+                matchers.multipart_matcher(
+                    files={"file_name": match_file}, data=req_data
+                )
+            ],
+        )
+        resp = requests.post(
+            "http://httpbin.org/post";, data=req_data, files={"file_name": 
req_file}
         )
-        resp = requests.post("http://httpbin.org/post";, data=req_data, 
files=req_files)
         assert resp.status_code == 200
 
         with pytest.raises(TypeError):
@@ -334,14 +349,24 @@
 
             msg = str(excinfo.value)
             assert "multipart/form-data doesn't match. Request body differs." 
in msg
-            assert (
-                '\r\nContent-Disposition: form-data; name="file_name"; '
-                'filename="file_name"\r\n\r\nOld World!\r\n'
-            ) in msg
-            assert (
-                '\r\nContent-Disposition: form-data; name="file_name"; '
-                'filename="file_name"\r\n\r\nNew World!\r\n'
-            ) in msg
+            if six.PY2:
+                assert (
+                    '\r\nContent-Disposition: form-data; name="file_name"; '
+                    'filename="file_name"\r\n\r\nOld World!\r\n'
+                ) in msg
+                assert (
+                    '\r\nContent-Disposition: form-data; name="file_name"; '
+                    'filename="file_name"\r\n\r\nNew World!\r\n'
+                ) in msg
+            else:
+                assert (
+                    r'\r\nContent-Disposition: form-data; name="file_name"; '
+                    r'filename="file_name"\r\n\r\nOld World!\r\n'
+                ) in msg
+                assert (
+                    r'\r\nContent-Disposition: form-data; name="file_name"; '
+                    r'filename="file_name"\r\n\r\nNew World!\r\n'
+                ) in msg
 
         # x-www-form-urlencoded request
         with responses.RequestsMock(assert_all_requests_are_fired=False) as 
rsps:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses/test_responses.py 
new/responses-0.17.0/responses/test_responses.py
--- old/responses-0.16.0/responses/test_responses.py    2021-11-11 
19:03:18.000000000 +0100
+++ new/responses-0.17.0/responses/test_responses.py    2022-01-07 
17:18:13.000000000 +0100
@@ -18,6 +18,7 @@
     PassthroughResponse,
     matchers,
     CallbackResponse,
+    registries,
 )
 
 
@@ -28,7 +29,7 @@
 
 
 def assert_reset():
-    assert len(responses._default_mock._matches) == 0
+    assert len(responses._default_mock.registered()) == 0
     assert len(responses.calls) == 0
 
 
@@ -1070,24 +1071,24 @@
         # check that assert_all_requests_are_fired=True doesn't remove urls
         with responses.RequestsMock(assert_all_requests_are_fired=True) as m:
             m.add(responses.GET, "http://example.com";, body=b"test")
-            assert len(m._matches) == 1
+            assert len(m.registered()) == 1
             requests.get("http://example.com";)
-            assert len(m._matches) == 1
+            assert len(m.registered()) == 1
 
         # check that assert_all_requests_are_fired=True counts mocked errors
         with responses.RequestsMock(assert_all_requests_are_fired=True) as m:
             m.add(responses.GET, "http://example.com";, body=Exception())
-            assert len(m._matches) == 1
+            assert len(m.registered()) == 1
             with pytest.raises(Exception):
                 requests.get("http://example.com";)
-            assert len(m._matches) == 1
+            assert len(m.registered()) == 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
+            assert len(m.registered()) == 1
             with pytest.raises(BaseException):
                 requests.get("http://example.com";)
-            assert len(m._matches) == 1
+            assert len(m.registered()) == 1
 
     run()
     assert_reset()
@@ -1219,6 +1220,9 @@
     https://github.com/psf/requests/pull/3563
 
     Now user can manually patch URL3 lib to achieve the same
+
+    See discussion in
+    https://github.com/getsentry/responses/issues/394
     """
 
     @responses.activate
@@ -1248,6 +1252,30 @@
     assert_reset()
 
 
+def test_stream_with_none_chunk_size():
+    """
+    See discussion in
+    https://github.com/getsentry/responses/issues/438
+    """
+
+    @responses.activate
+    def run():
+        responses.add(
+            responses.GET,
+            "https://example.com";,
+            status=200,
+            content_type="application/octet-stream",
+            body=b"This is test",
+            auto_calculate_content_length=True,
+        )
+        res = requests.get("https://example.com";, stream=True)
+        for chunk in res.iter_content(chunk_size=None):
+            assert chunk == b"This is test"
+
+    run()
+    assert_reset()
+
+
 def test_legacy_adding_headers():
     @responses.activate
     def run():
@@ -1377,15 +1405,48 @@
     def run():
         responses.add(responses.GET, "http://example.com";, body="test")
         responses.add(responses.GET, "http://example.com";, body="rest")
+        responses.add(responses.GET, "http://example.com";, body="fest")
+        responses.add(responses.GET, "http://example.com";, body="best")
 
         resp = requests.get("http://example.com";)
         assert_response(resp, "test")
+
         resp = requests.get("http://example.com";)
         assert_response(resp, "rest")
+
+        resp = requests.get("http://example.com";)
+        assert_response(resp, "fest")
+
+        resp = requests.get("http://example.com";)
+        assert_response(resp, "best")
+
         # After all responses are used, last response should be repeated
         resp = requests.get("http://example.com";)
+        assert_response(resp, "best")
+
+    run()
+    assert_reset()
+
+
+def test_multiple_responses_intermixed():
+    @responses.activate
+    def run():
+        responses.add(responses.GET, "http://example.com";, body="test")
+        resp = requests.get("http://example.com";)
+        assert_response(resp, "test")
+
+        responses.add(responses.GET, "http://example.com";, body="rest")
+        resp = requests.get("http://example.com";)
         assert_response(resp, "rest")
 
+        responses.add(responses.GET, "http://example.com";, body="best")
+        resp = requests.get("http://example.com";)
+        assert_response(resp, "best")
+
+        # After all responses are used, last response should be repeated
+        resp = requests.get("http://example.com";)
+        assert_response(resp, "best")
+
     run()
     assert_reset()
 
@@ -1546,6 +1607,37 @@
     assert_reset()
 
 
+def test_passthru_does_not_persist_across_tests(httpserver):
+    """
+    passthru should be erased on exit from context manager
+    see:
+    https://github.com/getsentry/responses/issues/322
+    """
+    httpserver.serve_content("OK", headers={"Content-Type": "text/plain"})
+
+    @responses.activate
+    def with_a_passthru():
+        assert not responses._default_mock.passthru_prefixes
+        responses.add_passthru(re.compile(".*"))
+        try:
+            response = requests.get("https://example.com";)
+        except ConnectionError as err:
+            if "Failed to establish" in str(err):
+                pytest.skip("Cannot resolve DNS for example.com")
+            raise err
+
+        assert response.status_code == 200
+
+    @responses.activate
+    def without_a_passthru():
+        assert not responses._default_mock.passthru_prefixes
+        with pytest.raises(requests.exceptions.ConnectionError):
+            requests.get("https://example.com";)
+
+    with_a_passthru()
+    without_a_passthru()
+
+
 def test_method_named_param():
     @responses.activate
     def run():
@@ -1767,7 +1859,7 @@
 
         mocks_list = responses.registered()
 
-        assert mocks_list == responses.mock._matches
+        assert mocks_list == responses.mock.registered()
         assert mocks_list == [first_response, second_response, third_response]
 
     run()
@@ -1792,3 +1884,86 @@
 
     run()
     assert_reset()
+
+
+def test_set_registry_not_empty():
+    class CustomRegistry(registries.FirstMatchRegistry):
+        pass
+
+    @responses.activate
+    def run():
+        url = "http://fizzbuzz/foo";
+        responses.add(method=responses.GET, url=url)
+        with pytest.raises(AttributeError) as excinfo:
+            responses.mock._set_registry(CustomRegistry)
+        msg = str(excinfo.value)
+        assert "Cannot replace Registry, current registry has responses" in msg
+
+    run()
+    assert_reset()
+
+
+def test_set_registry():
+    class CustomRegistry(registries.FirstMatchRegistry):
+        pass
+
+    @responses.activate(registry=CustomRegistry)
+    def run_with_registry():
+        assert type(responses.mock._get_registry()) == CustomRegistry
+
+    @responses.activate
+    def run():
+        # test that registry does not leak to another test
+        assert type(responses.mock._get_registry()) == 
registries.FirstMatchRegistry
+
+    run_with_registry()
+    run()
+    assert_reset()
+
+
+def test_set_registry_context_manager():
+    def run():
+        class CustomRegistry(registries.FirstMatchRegistry):
+            pass
+
+        with responses.RequestsMock(
+            assert_all_requests_are_fired=False, registry=CustomRegistry
+        ) as rsps:
+            assert type(rsps._get_registry()) == CustomRegistry
+            assert type(responses.mock._get_registry()) == 
registries.FirstMatchRegistry
+
+    run()
+    assert_reset()
+
+
+def test_registry_reset():
+    def run():
+        class CustomRegistry(registries.FirstMatchRegistry):
+            pass
+
+        with responses.RequestsMock(
+            assert_all_requests_are_fired=False, registry=CustomRegistry
+        ) as rsps:
+            rsps._get_registry().reset()
+            assert not rsps.registered()
+
+    run()
+    assert_reset()
+
+
+def test_requests_between_add():
+    @responses.activate
+    def run():
+        responses.add(responses.GET, "https://example.com/";, json={"response": 
"old"})
+        assert requests.get("https://example.com/";).content == b'{"response": 
"old"}'
+        assert requests.get("https://example.com/";).content == b'{"response": 
"old"}'
+        assert requests.get("https://example.com/";).content == b'{"response": 
"old"}'
+
+        responses.add(responses.GET, "https://example.com/";, json={"response": 
"new"})
+
+        assert requests.get("https://example.com/";).content == b'{"response": 
"new"}'
+        assert requests.get("https://example.com/";).content == b'{"response": 
"new"}'
+        assert requests.get("https://example.com/";).content == b'{"response": 
"new"}'
+
+    run()
+    assert_reset()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses.egg-info/PKG-INFO 
new/responses-0.17.0/responses.egg-info/PKG-INFO
--- old/responses-0.16.0/responses.egg-info/PKG-INFO    2021-11-11 
19:03:24.000000000 +0100
+++ new/responses-0.17.0/responses.egg-info/PKG-INFO    2022-01-07 
17:18:16.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.16.0
+Version: 0.17.0
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer
@@ -129,6 +129,9 @@
     The full resource URL.
 
 match_querystring (``bool``)
+    DEPRECATED: Use `responses.matchers.query_param_matcher` or
+    `responses.matchers.query_string_matcher`
+
     Include the query string when matching requests.
     Enabled by default if the response URL contains a query string,
     disabled if it doesn't or the URL is a regular expression.
@@ -294,7 +297,7 @@
         req_files = {"file_name": b"Old World!"}
         responses.add(
             responses.POST, url="http://httpbin.org/post";,
-            match=[multipart_matcher(req_data, req_files)]
+            match=[multipart_matcher(req_files, data=req_data)]
         )
         resp = requests.post("http://httpbin.org/post";, files={"file_name": 
b"New World!"})
 
@@ -411,6 +414,49 @@
         resp = session.send(prepped)
         assert resp.text == "hello world"
 
+Response Registry
+---------------------------
+
+By default, ``responses`` will search all registered``Response`` objects and
+return a match. If only one ``Response`` is registered, the registry is kept 
unchanged.
+However, if multiple matches are found for the same request, then first match 
is returned and
+removed from registry.
+
+Such behavior is suitable for most of use cases, but to handle special 
conditions, you can
+implement custom registry which must follow interface of 
``registries.FirstMatchRegistry``.
+Redefining the ``find`` method will allow you to create custom search logic 
and return
+appropriate ``Response``
+
+Example that shows how to set custom registry
+
+.. code-block:: python
+
+    import responses
+    from responses import registries
+
+
+    class CustomRegistry(registries.FirstMatchRegistry):
+        pass
+
+
+    """ Before tests: <responses.registries.FirstMatchRegistry object> """
+
+    # using function decorator
+    @responses.activate(registry=CustomRegistry)
+    def run():
+        """ Within test: <__main__.CustomRegistry object> """
+
+    run()
+    """ After test: <responses.registries.FirstMatchRegistry object> """
+
+    # using context manager
+    with responses.RequestsMock(registry=CustomRegistry) as rsps:
+        """ In context manager: <__main__.CustomRegistry object> """
+
+    """
+    After exit from context manager: <responses.registries.FirstMatchRegistry 
object>
+    """
+
 Dynamic Responses
 -----------------
 
@@ -590,22 +636,26 @@
 
 .. code-block:: python
 
-    def setUp():
-        self.responses = responses.RequestsMock()
-        self.responses.start()
-
-        # self.responses.add(...)
-
-        self.addCleanup(self.responses.stop)
-        self.addCleanup(self.responses.reset)
+    class TestMyApi(unittest.TestCase):
+        def setUp(self):
+            responses.add(responses.GET, 'https://example.com', body="within 
setup")
+            # here go other self.responses.add(...)
+
+        @responses.activate
+        def test_my_func(self):
+            responses.add(
+                responses.GET,
+                "https://httpbin.org/get";,
+                match=[matchers.query_param_matcher({"test": "1", "didi": 
"pro"})],
+                body="within test"
+            )
+            resp = requests.get("https://example.com";)
+            resp2 = requests.get("https://httpbin.org/get";, params={"test": 
"1", "didi": "pro"})
+            print(resp.text)
+            # >>> within setup
+            print(resp2.text)
+            # >>> within test
 
-    def test_api(self):
-        self.responses.add(
-            responses.GET, 'http://twitter.com/api/1/foobar',
-            body='{}', status=200,
-            content_type='application/json')
-        resp = requests.get('http://twitter.com/api/1/foobar')
-        assert resp.status_code == 200
 
 Assertions on declared responses
 --------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/responses.egg-info/SOURCES.txt 
new/responses-0.17.0/responses.egg-info/SOURCES.txt
--- old/responses-0.16.0/responses.egg-info/SOURCES.txt 2021-11-11 
19:03:24.000000000 +0100
+++ new/responses-0.17.0/responses.egg-info/SOURCES.txt 2022-01-07 
17:18:16.000000000 +0100
@@ -9,6 +9,8 @@
 responses/__init__.pyi
 responses/matchers.py
 responses/matchers.pyi
+responses/registries.py
+responses/registries.pyi
 responses/test_matchers.py
 responses/test_responses.py
 responses.egg-info/PKG-INFO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/setup.py 
new/responses-0.17.0/setup.py
--- old/responses-0.16.0/setup.py       2021-11-11 19:03:18.000000000 +0100
+++ new/responses-0.17.0/setup.py       2022-01-07 17:18:13.000000000 +0100
@@ -59,7 +59,7 @@
 
 setup(
     name="responses",
-    version="0.16.0",
+    version="0.17.0",
     author="David Cramer",
     description=("A utility library for mocking out the `requests` Python 
library."),
     url="https://github.com/getsentry/responses";,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.16.0/tox.ini new/responses-0.17.0/tox.ini
--- old/responses-0.16.0/tox.ini        2021-11-11 19:03:18.000000000 +0100
+++ new/responses-0.17.0/tox.ini        2022-01-07 17:18:13.000000000 +0100
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27,py35,py36,py37,py38,py39,py310,mypy
+envlist = py27,py35,py36,py37,py38,py39,py310,mypy,precom
 
 [testenv]
 extras = tests
@@ -12,3 +12,10 @@
 basepython = python3.7
 commands =
     python -m mypy --config-file=mypy.ini -p responses
+
+[testenv:precom]
+description = Run pre-commit hooks (black, flake, etc)
+basepython = python3.7
+deps = pre-commit
+commands =
+    pre-commit run --all-files

Reply via email to