Skip to content

Commit 233e2ee

Browse files
ramastjamielennox
authored andcommitted
Allow raw parameter to accept callable like body elements
1 parent b3f7080 commit 233e2ee

File tree

6 files changed

+44
-11
lines changed

6 files changed

+44
-11
lines changed

doc/source/response.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ Dynamic Response
7070
================
7171

7272
A callback can be provided in place of any of the body elements.
73+
raw attribute also accepts callable that returns HTTPResponse.
74+
The HTTPResponse should have `preload_content=False` or it may not work properly.
75+
7376
Callbacks must be a function in the form of
7477

7578
.. code:: python
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
When using dynamic responses, you can now use a callback function for the
5+
raw HTTPResponse object. This aligns it with all the other parameters that
6+
can be mocked.

requests_mock/adapter.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class Adapter(BaseAdapter, _RequestHistoryTracker):
6666
text: Union[str, Callback[str]] = ...,
6767
content: Union[bytes, Callback[bytes]] = ...,
6868
body: Union[IOBase, Callback[IOBase]] = ...,
69-
raw: HTTPResponse = ...,
69+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
7070
exc: Union[Exception, Type[Exception]] = ...,
7171
additional_matcher: AdditionalMatcher = ...,
7272
**kwargs: Any

requests_mock/mocker.pyi

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class MockerCore:
5454
text: Union[str, Callback[str]] = ...,
5555
content: Union[bytes, Callback[bytes]] = ...,
5656
body: Union[IOBase, Callback[IOBase]] = ...,
57-
raw: HTTPResponse = ...,
57+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
5858
exc: Union[Exception, Type[Exception]] = ...,
5959
additional_matcher: AdditionalMatcher = ...,
6060
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -77,7 +77,7 @@ class MockerCore:
7777
text: Union[str, Callback[str]] = ...,
7878
content: Union[bytes, Callback[bytes]] = ...,
7979
body: Union[IOBase, Callback[IOBase]] = ...,
80-
raw: HTTPResponse = ...,
80+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
8181
exc: Union[Exception, Type[Exception]] = ...,
8282
additional_matcher: AdditionalMatcher = ...,
8383
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -99,7 +99,7 @@ class MockerCore:
9999
text: Union[str, Callback[str]] = ...,
100100
content: Union[bytes, Callback[bytes]] = ...,
101101
body: Union[IOBase, Callback[IOBase]] = ...,
102-
raw: HTTPResponse = ...,
102+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
103103
exc: Union[Exception, Type[Exception]] = ...,
104104
additional_matcher: AdditionalMatcher = ...,
105105
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -121,7 +121,7 @@ class MockerCore:
121121
text: Union[str, Callback[str]] = ...,
122122
content: Union[bytes, Callback[bytes]] = ...,
123123
body: Union[IOBase, Callback[IOBase]] = ...,
124-
raw: HTTPResponse = ...,
124+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
125125
exc: Union[Exception, Type[Exception]] = ...,
126126
additional_matcher: AdditionalMatcher = ...,
127127
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -143,7 +143,7 @@ class MockerCore:
143143
text: Union[str, Callback[str]] = ...,
144144
content: Union[bytes, Callback[bytes]] = ...,
145145
body: Union[IOBase, Callback[IOBase]] = ...,
146-
raw: HTTPResponse = ...,
146+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
147147
exc: Union[Exception, Type[Exception]] = ...,
148148
additional_matcher: AdditionalMatcher = ...,
149149
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -165,7 +165,7 @@ class MockerCore:
165165
text: Union[str, Callback[str]] = ...,
166166
content: Union[bytes, Callback[bytes]] = ...,
167167
body: Union[IOBase, Callback[IOBase]] = ...,
168-
raw: HTTPResponse = ...,
168+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
169169
exc: Union[Exception, Type[Exception]] = ...,
170170
additional_matcher: AdditionalMatcher = ...,
171171
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -187,7 +187,7 @@ class MockerCore:
187187
text: Union[str, Callback[str]] = ...,
188188
content: Union[bytes, Callback[bytes]] = ...,
189189
body: Union[IOBase, Callback[IOBase]] = ...,
190-
raw: HTTPResponse = ...,
190+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
191191
exc: Union[Exception, Type[Exception]] = ...,
192192
additional_matcher: AdditionalMatcher = ...,
193193
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -209,7 +209,7 @@ class MockerCore:
209209
text: Union[str, Callback[str]] = ...,
210210
content: Union[bytes, Callback[bytes]] = ...,
211211
body: Union[IOBase, Callback[IOBase]] = ...,
212-
raw: HTTPResponse = ...,
212+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
213213
exc: Union[Exception, Type[Exception]] = ...,
214214
additional_matcher: AdditionalMatcher = ...,
215215
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -231,7 +231,7 @@ class MockerCore:
231231
text: Union[str, Callback[str]] = ...,
232232
content: Union[bytes, Callback[bytes]] = ...,
233233
body: Union[IOBase, Callback[IOBase]] = ...,
234-
raw: HTTPResponse = ...,
234+
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
235235
exc: Union[Exception, Type[Exception]] = ...,
236236
additional_matcher: AdditionalMatcher = ...,
237237
json_encoder: Optional[Type[JSONEncoder]] = ...,

requests_mock/response.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def _call(f, *args, **kwargs):
270270
text=_call(self._params.get('text')),
271271
content=_call(self._params.get('content')),
272272
body=_call(self._params.get('body')),
273-
raw=self._params.get('raw'),
273+
raw=_call(self._params.get('raw')),
274274
json_encoder=self._params.get('json_encoder'),
275275
status_code=context.status_code,
276276
reason=context.reason,

tests/test_adapter.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13+
import http.client
14+
import io
1315
import json
1416
import re
1517
import urllib.parse
1618

1719
import purl
1820
import requests
21+
from urllib3 import HTTPResponse
1922

2023
import requests_mock
2124
from . import base
@@ -119,6 +122,27 @@ def _text_cb(request, context):
119122
self.assertHeaders(resp)
120123
self.assertLastRequest()
121124

125+
def test_raw_callback(self):
126+
status_code = 401
127+
data = 'testdata'
128+
129+
def _raw_cb(request, context):
130+
return HTTPResponse(
131+
status=status_code,
132+
headers=self.headers,
133+
body=io.BytesIO(data.encode('utf-8')),
134+
preload_content=False,
135+
reason=http.client.responses.get(status_code),
136+
)
137+
138+
self.adapter.register_uri('GET', self.url, raw=_raw_cb)
139+
resp = self.session.get(self.url)
140+
self.assertEqual(status_code, resp.status_code)
141+
self.assertEqual(data, resp.text)
142+
self.assertEqual(data.encode('utf-8'), resp.content)
143+
self.assertHeaders(resp)
144+
self.assertLastRequest()
145+
122146
def test_json(self):
123147
json_data = {'hello': 'world'}
124148
self.adapter.register_uri('GET',

0 commit comments

Comments
 (0)