From 6b39129841626663ac067e0c11af2ff72f9ffeaa Mon Sep 17 00:00:00 2001 From: "reportportal.io" Date: Wed, 16 Oct 2024 17:09:31 +0000 Subject: [PATCH 1/9] Changelog update --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74b8b1d..c874362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] + +## [5.5.9] ### Fixed - Empty parameter Dict conversion, by @HardNorth From f9b77b8c0c923bdc1c0ff3b4e931801e85c3c865 Mon Sep 17 00:00:00 2001 From: "reportportal.io" Date: Wed, 16 Oct 2024 17:09:32 +0000 Subject: [PATCH 2/9] Version update --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index feffe53..e7bda62 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages -__version__ = '5.5.9' +__version__ = '5.5.10' TYPE_STUBS = ['*.pyi'] From 91733b5be864d8a42fafbf7c4056401d61b0acc8 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 10:45:49 +0300 Subject: [PATCH 3/9] A try to fix JSONDecodeError for simplejson --- reportportal_client/core/rp_responses.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/reportportal_client/core/rp_responses.py b/reportportal_client/core/rp_responses.py index b017db8..53063a9 100644 --- a/reportportal_client/core/rp_responses.py +++ b/reportportal_client/core/rp_responses.py @@ -19,7 +19,6 @@ """ import logging -from json import JSONDecodeError from typing import Any, Optional, Generator, Mapping, Tuple, Union from aiohttp import ClientResponse @@ -88,7 +87,7 @@ def json(self) -> Any: if self.__json is NOT_SET: try: self.__json = self._resp.json() - except (JSONDecodeError, TypeError) as exc: + except (ValueError, TypeError) as exc: logger.error(_get_json_decode_error_message(self._resp), exc_info=exc) self.__json = None return self.__json @@ -156,7 +155,7 @@ async def json(self) -> Any: if self.__json is NOT_SET: try: self.__json = await self._resp.json() - except (JSONDecodeError, TypeError) as exc: + except (ValueError, TypeError) as exc: logger.error(_get_json_decode_error_message(self._resp), exc_info=exc) self.__json = None return self.__json From 64e36a99ee6c36dc697f844ffc06d87b8d6c5c47 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 15:48:47 +0300 Subject: [PATCH 4/9] Fixes #244 --- CHANGELOG.md | 2 ++ reportportal_client/core/rp_requests.py | 7 ++++++- reportportal_client/core/rp_responses.py | 9 +++++---- reportportal_client/helpers.py | 7 ++++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c874362..7cc6b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Fixed +- Issue [#244](https://github.com/reportportal/client-Python/issues/244): Client crash on different error responses, by @HardNorth ## [5.5.9] ### Fixed diff --git a/reportportal_client/core/rp_requests.py b/reportportal_client/core/rp_requests.py index 932160e..16d3874 100644 --- a/reportportal_client/core/rp_requests.py +++ b/reportportal_client/core/rp_requests.py @@ -19,7 +19,6 @@ """ import asyncio -import json as json_converter import logging from dataclasses import dataclass from typing import Callable, Optional, Union, List, Tuple, Any, TypeVar @@ -43,6 +42,12 @@ from reportportal_client.core.rp_responses import RPResponse, AsyncRPResponse from reportportal_client.helpers import dict_to_payload, await_if_necessary +try: + # noinspection PyPackageRequirements + import simplejson as json_converter +except ImportError: + import json as json_converter + logger = logging.getLogger(__name__) T = TypeVar("T") diff --git a/reportportal_client/core/rp_responses.py b/reportportal_client/core/rp_responses.py index 53063a9..30703f1 100644 --- a/reportportal_client/core/rp_responses.py +++ b/reportportal_client/core/rp_responses.py @@ -21,7 +21,7 @@ import logging from typing import Any, Optional, Generator, Mapping, Tuple, Union -from aiohttp import ClientResponse +from aiohttp import ClientResponse, ClientError from requests import Response # noinspection PyProtectedMember @@ -41,8 +41,9 @@ def _iter_json_messages(json: Any) -> Generator[str, None, None]: def _get_json_decode_error_message(response: Union[Response, ClientResponse]) -> str: - status = getattr(response, 'status', getattr(response, 'status_code')) - return f'Unable to decode JSON response, got {"passed" if response.ok else "failed"} ' \ + status = getattr(response, 'status', getattr(response, 'status_code', None)) + ok = getattr(response, 'ok', None) + return f'Unable to decode JSON response, got {"passed" if ok else "failed"} ' \ f'response with code "{status}" please check your endpoint configuration or API key' @@ -155,7 +156,7 @@ async def json(self) -> Any: if self.__json is NOT_SET: try: self.__json = await self._resp.json() - except (ValueError, TypeError) as exc: + except (ValueError, TypeError, ClientError) as exc: logger.error(_get_json_decode_error_message(self._resp), exc_info=exc) self.__json = None return self.__json diff --git a/reportportal_client/helpers.py b/reportportal_client/helpers.py index 63debbb..0311890 100644 --- a/reportportal_client/helpers.py +++ b/reportportal_client/helpers.py @@ -15,7 +15,6 @@ import asyncio import inspect -import json import logging import sys import threading @@ -27,6 +26,12 @@ from reportportal_client.core.rp_file import RPFile +try: + # noinspection PyPackageRequirements + import simplejson as json +except ImportError: + import json + logger: logging.Logger = logging.getLogger(__name__) _T = TypeVar('_T') ATTRIBUTE_LENGTH_LIMIT: int = 128 From 6391fc973fe8fcb18a25ee10f4d119638eb161d4 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 16:06:46 +0300 Subject: [PATCH 5/9] Add more tests --- tests/core/test_rp_responses.py | 46 ++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/tests/core/test_rp_responses.py b/tests/core/test_rp_responses.py index 5b8d098..e11d860 100644 --- a/tests/core/test_rp_responses.py +++ b/tests/core/test_rp_responses.py @@ -20,37 +20,59 @@ from reportportal_client.core.rp_responses import RPResponse, AsyncRPResponse +class JSONDecodeError(ValueError): + pass + + def json_error(): raise json.JSONDecodeError('Expecting value: line 1 column 1 (char 0)', '', 0) +def custom_error(): + raise JSONDecodeError('Expecting value: line 1 column 1 (char 0)') + + @mock.patch('reportportal_client.core.rp_responses.logging.Logger.error') -def test_json_decode_error(error_log): +@pytest.mark.parametrize('ok, response_code, error_function, expected_message', [ + (False, 404, json_error, 'Unable to decode JSON response, got failed response with code "404" please check your ' + 'endpoint configuration or API key'), + (True, 200, json_error, 'Unable to decode JSON response, got passed response with code "200" please check your ' + 'endpoint configuration or API key'), + (True, 200, custom_error, 'Unable to decode JSON response, got passed response with code "200" please check your ' + 'endpoint configuration or API key'), +]) +def test_custom_decode_error(error_log, ok, response_code, error_function, expected_message): response = mock.Mock() - response.ok = False + response.ok = ok del response.status - response.status_code = 404 - response.json.side_effect = json_error + response.status_code = response_code + response.json.side_effect = error_function rp_response = RPResponse(response) assert rp_response.json is None error_log.assert_called_once() - assert error_log.call_args_list[0][0][0] == ('Unable to decode JSON response, got failed response with code "404" ' - 'please check your endpoint configuration or API key') + assert error_log.call_args_list[0][0][0] == expected_message @pytest.mark.skipif(sys.version_info < (3, 8), reason='the test requires AsyncMock which was introduced in Python 3.8') @mock.patch('reportportal_client.core.rp_responses.logging.Logger.error') @pytest.mark.asyncio -async def test_json_decode_error_async(error_log): +@pytest.mark.parametrize('ok, response_code, error_function, expected_message', [ + (False, 404, json_error, 'Unable to decode JSON response, got failed response with code "404" please check your ' + 'endpoint configuration or API key'), + (True, 200, json_error, 'Unable to decode JSON response, got passed response with code "200" please check your ' + 'endpoint configuration or API key'), + (True, 200, custom_error, 'Unable to decode JSON response, got passed response with code "200" please check your ' + 'endpoint configuration or API key'), +]) +async def test_json_decode_error_async(error_log, ok, response_code, error_function, expected_message): response = mock.AsyncMock() - response.ok = False - response.status = 403 - response.json.side_effect = json_error + response.ok = ok + response.status = response_code + response.json.side_effect = error_function rp_response = AsyncRPResponse(response) assert await rp_response.json is None error_log.assert_called_once() - assert error_log.call_args_list[0][0][0] == ('Unable to decode JSON response, got failed response with code "403" ' - 'please check your endpoint configuration or API key') + assert error_log.call_args_list[0][0][0] == expected_message From 293c56052751a3dd2e41700169c2dd6a26c63c3d Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 16:29:49 +0300 Subject: [PATCH 6/9] Dependencies update --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6c8a44c..0641c27 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ aenum -requests>=2.28.0 -aiohttp>=3.8.3 -certifi>=2023.7.22 +requests>=2.31.0 +aiohttp>=3.8.6 +certifi>=2024.8.30 From 61a6f0dbfc08e84d51b4244c8692a82d4547643f Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 16:33:53 +0300 Subject: [PATCH 7/9] Add python 3.13 --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 4 ++-- setup.py | 1 + tox.ini | 6 ++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4ef14d7..aa1d825 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: '3.10' - name: Install dependencies run: python -m pip install --upgrade pip setuptools wheel diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3d2e061..121d9d4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ] + python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ] steps: - name: Checkout repository uses: actions/checkout@v4 @@ -54,7 +54,7 @@ jobs: run: tox - name: Upload coverage to Codecov - if: matrix.python-version == 3.8 && success() + if: matrix.python-version == 3.10 && success() uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/setup.py b/setup.py index e7bda62..82bb01c 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ def read_file(fname): 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ], install_requires=read_file('requirements.txt').splitlines(), ) diff --git a/tox.ini b/tox.ini index fbfbada..188cb9a 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,7 @@ envlist = py310 py311 py312 + py313 [testenv] deps = @@ -27,8 +28,9 @@ commands = pre-commit run --all-files --show-diff-on-failure [gh-actions] python = 3.7: py37 - 3.8: pep, py38 + 3.8: py38 3.9: py39 - 3.10: py310 + 3.10: pep, py310 3.11: py311 3.12: py312 + 3.12: py313 From 16a8a78fd2b81c01af4621a0394a4a10b61e63c9 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 16:34:38 +0300 Subject: [PATCH 8/9] Add python 3.13 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc6b2c..993ac1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Added +- Official `Python 3.13` support, by @HardNorth ### Fixed - Issue [#244](https://github.com/reportportal/client-Python/issues/244): Client crash on different error responses, by @HardNorth From e60998e10c85f4de6e794f5398512acad957971c Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 29 Nov 2024 16:36:37 +0300 Subject: [PATCH 9/9] Add python 3.13 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 188cb9a..1bdcd57 100644 --- a/tox.ini +++ b/tox.ini @@ -33,4 +33,4 @@ python = 3.10: pep, py310 3.11: py311 3.12: py312 - 3.12: py313 + 3.13: py313