From ecda69130e97629b15d3b09b1e588cb6777ee94d Mon Sep 17 00:00:00 2001 From: kasun Herath Date: Mon, 10 Dec 2018 22:34:49 +0530 Subject: [PATCH] allow to send empty data values and docs changes --- docs/topics/request-response.rst | 6 +++--- scrapy/http/request/json_request.py | 8 +++++--- tests/test_http_request.py | 27 +++++++++++++++++++++------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/docs/topics/request-response.rst b/docs/topics/request-response.rst index d957915e7..02b853fc0 100644 --- a/docs/topics/request-response.rst +++ b/docs/topics/request-response.rst @@ -520,13 +520,13 @@ dealing with JSON requests. remaining arguments are the same as for the :class:`Request` class and are not documented here. - Using the :class:`JSONRequest` will set the `Content-Type` header to `application/json` - and `Accept` header to `application/json, text/javascript, */*; q=0.01` + Using the :class:`JSONRequest` will set the ``Content-Type`` header to ``application/json`` + and ``Accept`` header to ``application/json, text/javascript, */*; q=0.01`` :param data: is any JSON serializable object that needs to be JSON encoded and assigned to body. if :attr:`Request.body` argument is provided this parameter will be ignored. if :attr:`Request.body` argument is not provided and data argument is provided :attr:`Request.method` will be - set to POST automatically. + set to ``'POST'`` automatically. :type data: JSON serializable object JSONRequest usage example diff --git a/scrapy/http/request/json_request.py b/scrapy/http/request/json_request.py index 3b791eda3..593dfdcb0 100644 --- a/scrapy/http/request/json_request.py +++ b/scrapy/http/request/json_request.py @@ -13,12 +13,14 @@ from scrapy.http.request import Request class JSONRequest(Request): def __init__(self, *args, **kwargs): - body_passed = 'body' in kwargs + body_passed = kwargs.get('body', None) is not None data = kwargs.pop('data', None) - if body_passed and data: + data_passed = data is not None + + if body_passed and data_passed: warnings.warn('Both body and data passed. data will be ignored') - elif not body_passed and data: + elif not body_passed and data_passed: kwargs['body'] = json.dumps(data) if 'method' not in kwargs: diff --git a/tests/test_http_request.py b/tests/test_http_request.py index e5a85e6fc..5eb655c12 100644 --- a/tests/test_http_request.py +++ b/tests/test_http_request.py @@ -1175,20 +1175,35 @@ class JSONRequestTest(RequestTest): self.assertEqual(r3.body, to_bytes(json.dumps(data))) self.assertEqual(r3.method, 'POST') + r4 = self.request_class(url="http://www.example.com/", data=[]) + self.assertEqual(r4.body, to_bytes(json.dumps([]))) + self.assertEqual(r4.method, 'POST') + with warnings.catch_warnings(record=True) as _warnings: - r4 = self.request_class(url="http://www.example.com/", body=body, data=data) - self.assertEqual(r4.body, body) - self.assertEqual(r4.method, 'GET') + r5 = self.request_class(url="http://www.example.com/", body=body, data=data) + self.assertEqual(r5.body, body) + self.assertEqual(r5.method, 'GET') self.assertEqual(len(_warnings), 1) self.assertIn('data will be ignored', str(_warnings[0].message)) with warnings.catch_warnings(record=True) as _warnings: - r5 = self.request_class(url="http://www.example.com/", body=b'', data=data) - self.assertEqual(r5.body, b'') - self.assertEqual(r5.method, 'GET') + r6 = self.request_class(url="http://www.example.com/", body=b'', data=data) + self.assertEqual(r6.body, b'') + self.assertEqual(r6.method, 'GET') self.assertEqual(len(_warnings), 1) self.assertIn('data will be ignored', str(_warnings[0].message)) + with warnings.catch_warnings(record=True) as _warnings: + r7 = self.request_class(url="http://www.example.com/", body=None, data=data) + self.assertEqual(r7.body, to_bytes(json.dumps(data))) + self.assertEqual(r7.method, 'POST') + self.assertEqual(len(_warnings), 0) + + with warnings.catch_warnings(record=True) as _warnings: + r8 = self.request_class(url="http://www.example.com/", body=None, data=None) + self.assertEqual(r8.method, 'GET') + self.assertEqual(len(_warnings), 0) + def tearDown(self): warnings.resetwarnings() super(JSONRequestTest, self).tearDown()