From 14215dcc85b79abe04c8f64960e32e63efb5a452 Mon Sep 17 00:00:00 2001 From: Gianluca Paronitti Date: Tue, 19 Oct 2021 17:58:19 +0200 Subject: [PATCH 1/4] fix bug #1570: manages JSONDecodeError exception test: copes with possible future regressions --- googleapiclient/model.py | 11 ++++++++--- tests/test_json_model.py | 9 ++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/googleapiclient/model.py b/googleapiclient/model.py index b853a4f682e..659ec0b08e2 100644 --- a/googleapiclient/model.py +++ b/googleapiclient/model.py @@ -273,13 +273,18 @@ def serialize(self, body_value): return json.dumps(body_value) def deserialize(self, content): + body = {} try: content = content.decode("utf-8") except AttributeError: pass - body = json.loads(content) - if self._data_wrapper and isinstance(body, dict) and "data" in body: - body = body["data"] + try: + body = json.loads(content) + if self._data_wrapper and isinstance(body, dict) and "data" in body: + body = body["data"] + except json.decoder.JSONDecodeError: + if isinstance(content, str): + body = content return body @property diff --git a/tests/test_json_model.py b/tests/test_json_model.py index 1ddc1c73bd1..4d5bb595ac7 100644 --- a/tests/test_json_model.py +++ b/tests/test_json_model.py @@ -31,7 +31,6 @@ import googleapiclient.model - from googleapiclient.errors import HttpError from googleapiclient.model import JsonModel @@ -290,6 +289,14 @@ def test_no_data_wrapper_deserialize(self): content = model.response(resp, content) self.assertEqual(content, {"data": "is good"}) + def test_no_data_wrapper_deserialize_text_format(self): + model = JsonModel(data_wrapper=False) + resp = httplib2.Response({"status": "200"}) + resp.reason = "OK" + content = 'column1,column2,column3\nstring1,1.2,string2' + content = model.response(resp, content) + self.assertEqual(content, 'column1,column2,column3\nstring1,1.2,string2') + def test_data_wrapper_deserialize(self): model = JsonModel(data_wrapper=True) resp = httplib2.Response({"status": "200"}) From 857c37b54febada11ff9b66f4ae26ca9658ee33c Mon Sep 17 00:00:00 2001 From: Gianluca Paronitti Date: Tue, 19 Oct 2021 19:16:45 +0200 Subject: [PATCH 2/4] fix: bug #1570, manages JSONDecodeError exception test: copes with possible future regressions --- googleapiclient/model.py | 5 +++-- tests/test_json_model.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/googleapiclient/model.py b/googleapiclient/model.py index 659ec0b08e2..0107a74778e 100644 --- a/googleapiclient/model.py +++ b/googleapiclient/model.py @@ -280,11 +280,12 @@ def deserialize(self, content): pass try: body = json.loads(content) - if self._data_wrapper and isinstance(body, dict) and "data" in body: - body = body["data"] except json.decoder.JSONDecodeError: if isinstance(content, str): body = content + else: + if self._data_wrapper and isinstance(body, dict) and "data" in body: + body = body["data"] return body @property diff --git a/tests/test_json_model.py b/tests/test_json_model.py index 4d5bb595ac7..cd3d7db3b6c 100644 --- a/tests/test_json_model.py +++ b/tests/test_json_model.py @@ -35,6 +35,7 @@ from googleapiclient.model import JsonModel _LIBRARY_VERSION = pkg_resources.get_distribution("google-api-python-client").version +CSV_TEXT_MOCK = 'column1,column2,column3\nstring1,1.2,string2' class Model(unittest.TestCase): @@ -293,9 +294,9 @@ def test_no_data_wrapper_deserialize_text_format(self): model = JsonModel(data_wrapper=False) resp = httplib2.Response({"status": "200"}) resp.reason = "OK" - content = 'column1,column2,column3\nstring1,1.2,string2' + content = CSV_TEXT_MOCK content = model.response(resp, content) - self.assertEqual(content, 'column1,column2,column3\nstring1,1.2,string2') + self.assertEqual(content, CSV_TEXT_MOCK) def test_data_wrapper_deserialize(self): model = JsonModel(data_wrapper=True) From 369976c3985148c84ffaa8065c27d01a6e1f63e5 Mon Sep 17 00:00:00 2001 From: Gianluca Paronitti Date: Tue, 19 Oct 2021 20:13:54 +0200 Subject: [PATCH 3/4] fix: address review comments test: User passes a non-str as content --- googleapiclient/model.py | 6 ++---- tests/test_json_model.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/googleapiclient/model.py b/googleapiclient/model.py index 0107a74778e..b023db4dd2d 100644 --- a/googleapiclient/model.py +++ b/googleapiclient/model.py @@ -273,7 +273,6 @@ def serialize(self, body_value): return json.dumps(body_value) def deserialize(self, content): - body = {} try: content = content.decode("utf-8") except AttributeError: @@ -281,10 +280,9 @@ def deserialize(self, content): try: body = json.loads(content) except json.decoder.JSONDecodeError: - if isinstance(content, str): - body = content + body = content else: - if self._data_wrapper and isinstance(body, dict) and "data" in body: + if self._data_wrapper and "data" in body: body = body["data"] return body diff --git a/tests/test_json_model.py b/tests/test_json_model.py index cd3d7db3b6c..cd3f1d4df8e 100644 --- a/tests/test_json_model.py +++ b/tests/test_json_model.py @@ -22,6 +22,7 @@ __author__ = "jcgregorio@google.com (Joe Gregorio)" +import io import httplib2 import json import pkg_resources @@ -298,6 +299,15 @@ def test_no_data_wrapper_deserialize_text_format(self): content = model.response(resp, content) self.assertEqual(content, CSV_TEXT_MOCK) + def test_no_data_wrapper_deserialize_raise_type_error(self): + buffer = io.StringIO() + buffer.write('String buffer') + model = JsonModel(data_wrapper=False) + resp = httplib2.Response({"status": "500"}) + resp.reason = "The JSON object must be str, bytes or bytearray, not StringIO" + content = buffer + self.assertRaises(TypeError, model.response, (resp, content)) + def test_data_wrapper_deserialize(self): model = JsonModel(data_wrapper=True) resp = httplib2.Response({"status": "200"}) From 4e7cdc40bb751a90727d46bbd6cac703dbf72142 Mon Sep 17 00:00:00 2001 From: Gianluca Paronitti Date: Thu, 21 Oct 2021 21:37:30 +0200 Subject: [PATCH 4/4] fix: accepts changes proposed from code reviewer --- tests/test_json_model.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_json_model.py b/tests/test_json_model.py index cd3f1d4df8e..322a7b4848c 100644 --- a/tests/test_json_model.py +++ b/tests/test_json_model.py @@ -306,7 +306,8 @@ def test_no_data_wrapper_deserialize_raise_type_error(self): resp = httplib2.Response({"status": "500"}) resp.reason = "The JSON object must be str, bytes or bytearray, not StringIO" content = buffer - self.assertRaises(TypeError, model.response, (resp, content)) + with self.assertRaises(TypeError): + model.response(resp, content) def test_data_wrapper_deserialize(self): model = JsonModel(data_wrapper=True)