Repository: getsentry/responses

Issue:
Feature Request: Return requested params in responses.calls[].request
Similar to as discussed in #148 , when using the params parameter in requests, I need to set `match_querystring=False` to ignore the query string:

```
responses.add(
    method=responses.GET,
    url="http://example.com?hello=world,
    json={"response": "response"},
    status=200,
    match_querystring=False,
)
req = requests.get('http://example.com', params={"hello": "world"})
```

This returns a list of calls where I can get the requested URL:
```
print(requests.calls[0].request.url)
> http://example.com
```

However, theres no way to see what the original params passed in the original `request`. It would be nice to be able to also do something like the following so that I can very what the parameters are that were passed in the request:

```
print(requests.calls[0].request.params)
> {"hello": "world"}
```

Discussion:

Patch:
diff --git a/README.rst b/README.rst
index 94c27b3..1ea3d36 100644
--- a/README.rst
+++ b/README.rst
@@ -239,6 +239,25 @@ a callback function to give a slightly different result, you can use ``functools
         )
 
 
+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
 ------------------------------
 
@@ -352,7 +371,7 @@ Passing thru real requests
 --------------------------
 
 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 ``add_passthru' methods:
+and hit a real server. This can be done with the 'passthru' methods:
 
 .. code-block:: python
 
@@ -365,12 +384,6 @@ and hit a real server. This can be done with the ``add_passthru' methods:
 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
 --------------------------------------
diff --git a/responses.py b/responses.py
index df42ef5..0c0f4f2 100644
--- a/responses.py
+++ b/responses.py
@@ -527,18 +527,14 @@ class RequestsMock(object):
 
     def add_passthru(self, prefix):
         """
-        Register a URL prefix or regex to passthru any non-matching mock requests to.
+        Register a URL prefix 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 not isinstance(prefix, Pattern) and _has_unicode(prefix):
+        if _has_unicode(prefix):
             prefix = _clean_unicode(prefix)
         self.passthru_prefixes += (prefix,)
 
@@ -626,16 +622,10 @@ class RequestsMock(object):
     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 any(
-                [
-                    p.match(request.url)
-                    if isinstance(p, Pattern)
-                    else request.url.startswith(p)
-                    for p in self.passthru_prefixes
-                ]
-            ):
+            if request.url.startswith(self.passthru_prefixes):
                 logger.info("request.allowed-passthru", extra={"url": request.url})
                 return _real_send(adapter, request, **kwargs)
 
@@ -652,7 +642,7 @@ class RequestsMock(object):
 
         try:
             response = adapter.build_response(request, match.get_response(request))
-        except BaseException as response:
+        except Exception as response:
             match.call_count += 1
             self._calls.add(request, response)
             response = resp_callback(response) if resp_callback else response


Test patch:
diff --git a/test_responses.py b/test_responses.py
index af41f3a..6f4e534 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -749,9 +749,6 @@ def test_response_filebody():
 
 
 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:
@@ -785,13 +782,6 @@ def test_assert_all_requests_are_fired():
                 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()
 
@@ -953,28 +943,6 @@ def test_passthru(httpserver):
     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():
@@ -1022,3 +990,25 @@ def test_cookies_from_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()