From 26dc07b633ab293a91b0f68ad17848162cafa5da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20V=2E=20Treider?= Date: Thu, 12 Sep 2024 14:41:01 +0200 Subject: [PATCH] Fix json decode error for users using simplejson instead of built-in json (#1923) --- CHANGELOG.md | 4 ++++ cognite/client/_api_client.py | 5 +++-- cognite/client/_version.py | 2 +- cognite/client/utils/_json.py | 13 +++++++++++-- poetry.lock | 13 ++++++++++++- pyproject.toml | 4 ++-- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d79345f8d..bc6dc69050 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ Changes are grouped as follows - `Fixed` for any bug fixes. - `Security` in case of vulnerabilities. +## [7.59.3] - 2024-09-12 +### Fixed +- JSONDecodeError can no longer be raised in environments where simplejson is used instead of built-in json. + ## [7.59.2] - 2024-09-12 ### Fixed - A bug in `client.sequences.data.retrieve_dataframe(...)` where passing a column to `column_external_ids` caused a TypeError. diff --git a/cognite/client/_api_client.py b/cognite/client/_api_client.py index f58946a6cc..713d9b2f1c 100644 --- a/cognite/client/_api_client.py +++ b/cognite/client/_api_client.py @@ -7,7 +7,6 @@ import re import warnings from collections import UserList -from json.decoder import JSONDecodeError from typing import ( TYPE_CHECKING, Any, @@ -27,6 +26,7 @@ import requests.utils from requests import Response +from requests.exceptions import JSONDecodeError as RequestsJSONDecodeError from requests.structures import CaseInsensitiveDict from cognite.client._http_client import HTTPClient, HTTPClientConfig, get_global_requests_session @@ -63,6 +63,7 @@ IdentifierSequenceCore, SingletonIdentifierSequence, ) +from cognite.client.utils._json import JSONDecodeError from cognite.client.utils._text import convert_all_keys_to_camel_case, shorten, to_camel_case, to_snake_case from cognite.client.utils._validation import assert_type, verify_limit from cognite.client.utils.useful_types import SequenceNotStr @@ -1338,7 +1339,7 @@ def _log_request(self, res: Response, **kwargs: Any) -> None: def _get_response_content_safe(res: Response) -> str: try: return _json.dumps(res.json()) - except JSONDecodeError: + except (JSONDecodeError, RequestsJSONDecodeError): pass try: diff --git a/cognite/client/_version.py b/cognite/client/_version.py index cd9db4b57f..e663079085 100644 --- a/cognite/client/_version.py +++ b/cognite/client/_version.py @@ -1,4 +1,4 @@ from __future__ import annotations -__version__ = "7.59.2" +__version__ = "7.59.3" __api_subversion__ = "20230101" diff --git a/cognite/client/utils/_json.py b/cognite/client/utils/_json.py index e316192c8d..fb6ad343a1 100644 --- a/cognite/client/utils/_json.py +++ b/cognite/client/utils/_json.py @@ -1,13 +1,22 @@ from __future__ import annotations -import json import math import numbers from decimal import Decimal from types import MappingProxyType from typing import Any -__all__ = ["dumps", "loads", "convert_to_float", "convert_nonfinite_float_to_str"] +# Users are seeing JSONDecodeError coming from a block that intercepts JSONDecodeError +# (i.e. shouldn't be possible). It seems Python runtimes like e.g. Databricks patches the +# built-in json library with simplejson and thus simplejson.JSONDecodeError != json.JSONDecodeError +try: + import simplejson as json + from simplejson import JSONDecodeError +except ImportError: + import json # type: ignore [no-redef] + from json import JSONDecodeError # type: ignore [assignment] + +__all__ = ["dumps", "loads", "JSONDecodeError", "convert_to_float", "convert_nonfinite_float_to_str"] def _default_json_encoder(obj: Any) -> Any: diff --git a/poetry.lock b/poetry.lock index 06ff67dd7e..d15ca9ab75 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2664,6 +2664,17 @@ files = [ [package.dependencies] urllib3 = ">=2" +[[package]] +name = "types-simplejson" +version = "3.19.0.20240801" +description = "Typing stubs for simplejson" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-simplejson-3.19.0.20240801.tar.gz", hash = "sha256:ef90cc81dd915f26c452fa2b5e0cbd3a36af81074ae63878fcf8a477e7594e4d"}, + {file = "types_simplejson-3.19.0.20240801-py3-none-any.whl", hash = "sha256:37f1b33c8626d7f072ea87737629310674845d54d187f12387fe33d31c938288"}, +] + [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -2777,4 +2788,4 @@ yaml = ["PyYAML"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "9e456775447549841733cf93df8ec207a099cbffc1e752fccfaa5acdb98d2da9" +content-hash = "f9fa579062a7458a8248db8fae842263cb3eb5a958f1313b1963d71dc40bbbcc" diff --git a/pyproject.toml b/pyproject.toml index db1b000fd8..af9c7e0b79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,7 @@ [tool.poetry] name = "cognite-sdk" - -version = "7.59.2" +version = "7.59.3" description = "Cognite Python SDK" readme = "README.md" documentation = "https://cognite-sdk-python.readthedocs-hosted.com" @@ -88,6 +87,7 @@ packaging = ">=23" IPython = ">=7.0.0" # Used in docstring examples PyYAML = "^6.0" pytest-icdiff = "*" # Used for better diffs in pytest +types-simplejson = "^3.19.0.20240801" [build-system] requires = ["poetry-core"]