diff --git a/dataclasses_json/core.py b/dataclasses_json/core.py index 684a1e55..1602fef5 100644 --- a/dataclasses_json/core.py +++ b/dataclasses_json/core.py @@ -11,11 +11,9 @@ from datetime import datetime, timezone from decimal import Decimal from enum import Enum -from typing import Any, Collection, Dict, Mapping, Union, get_type_hints +from typing import Any, Collection, Mapping, Union, get_type_hints from uuid import UUID -from cachetools import cached -from cachetools.lru import LRUCache from typing_inspect import is_union_type # type: ignore from dataclasses_json import cfg @@ -26,10 +24,6 @@ _issubclass_safe) Json = Union[dict, list, str, int, float, bool, None] -_MAX_CACHE_SIZE = 128 -_get_type_hints_cache = LRUCache(maxsize=_MAX_CACHE_SIZE) -_is_supported_generic_cache = LRUCache(maxsize=_MAX_CACHE_SIZE) -_user_overrides_cache = LRUCache(maxsize=_MAX_CACHE_SIZE) class _ExtendedEncoder(json.JSONEncoder): @@ -53,14 +47,10 @@ def default(self, o) -> Json: return result -confs = ['encoder', 'decoder', 'mm_field', 'letter_case'] -FieldOverride = namedtuple('FieldOverride', confs) +def _user_overrides_or_exts(cls): + confs = ['encoder', 'decoder', 'mm_field', 'letter_case'] + FieldOverride = namedtuple('FieldOverride', confs) - -@cached(cache=_user_overrides_cache, key=id) -def _user_overrides_or_exts(cls) -> Dict[str, FieldOverride]: - overrides = {} - # overrides at the class-level global_metadata = defaultdict(dict) encoders = cfg.global_config.encoders decoders = cfg.global_config.decoders @@ -99,7 +89,7 @@ def _encode_json_type(value, default=_ExtendedEncoder().default): return default(value) -def _encode_overrides(kvs: Dict[str, Any], overrides, encode_json=False): +def _encode_overrides(kvs, overrides, encode_json=False): override_kvs = {} for k, v in kvs.items(): if k in overrides: @@ -128,11 +118,6 @@ def _decode_letter_case_overrides(field_names, overrides): return names -@cached(cache=_get_type_hints_cache, key=id) -def _get_type_hints_cached(cls): - return get_type_hints(cls) - - def _decode_dataclass(cls, kvs, infer_missing): if isinstance(kvs, cls): return kvs @@ -155,7 +140,7 @@ def _decode_dataclass(cls, kvs, infer_missing): kvs = _handle_undefined_parameters_safe(cls, kvs, usage="from") init_kwargs = {} - types = _get_type_hints_cached(cls) + types = get_type_hints(cls) for field in fields(cls): # The field should be skipped from being added # to init_kwargs as it's not intended as a constructor argument. @@ -237,7 +222,6 @@ def _support_extended_types(field_type, field_value): return res -@cached(cache=_is_supported_generic_cache, key=id) def _is_supported_generic(type_): not_str = not _issubclass_safe(type_, str) is_enum = _issubclass_safe(type_, Enum) diff --git a/setup.py b/setup.py index 1ccc9cde..dedb1f91 100644 --- a/setup.py +++ b/setup.py @@ -21,8 +21,7 @@ 'marshmallow>=3.3.0,<4.0.0', 'marshmallow-enum>=1.5.1,<2.0.0', 'typing-inspect>=0.4.0', - 'stringcase==1.2.0,<2.0.0', - 'cachetools==4.0.0,<5.0.0' + 'stringcase==1.2.0,<2.0.0' ], python_requires='>=3.6', extras_require={ diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 28c8b9ad..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,3 +0,0 @@ -pytest_plugins = [ - 'tests.fixtures' -] diff --git a/tests/fixtures.py b/tests/fixtures.py deleted file mode 100644 index 9743d83f..00000000 --- a/tests/fixtures.py +++ /dev/null @@ -1,10 +0,0 @@ -import pytest -# noinspection PyProtectedMember -from dataclasses_json.core import _get_type_hints_cache, _is_supported_generic_cache, _user_overrides_cache - - -@pytest.fixture(autouse=True) -def clear_caches(): - _is_supported_generic_cache.clear() - _user_overrides_cache.clear() - _get_type_hints_cache.clear() diff --git a/tests/test_cache.py b/tests/test_cache.py deleted file mode 100644 index 447fae72..00000000 --- a/tests/test_cache.py +++ /dev/null @@ -1,80 +0,0 @@ -from tests.entities import (DataClassWithDataClass, - DataClassWithList, - DataClassX, - DataClassXs) -# noinspection PyProtectedMember -from dataclasses_json.core import _get_type_hints_cache, _is_supported_generic_cache, _user_overrides_cache - - -class TestCache: - - def test_dataclass_with_xs_caches_class(self): - json_dataclass_with_xs = '{"xs": [{"x": 1}]}' - _ = DataClassXs.from_json(json_dataclass_with_xs) - - # type hints for class and DataClassX cached - assert _get_type_hints_cache._Cache__currsize == 2 - # supported generic called for List[DataClassX] and int - assert _is_supported_generic_cache._Cache__currsize == 2 - # for the dataclasses - assert _user_overrides_cache._Cache__currsize == 2 - - # force cache hits - _ = DataClassXs.from_json(json_dataclass_with_xs) - - assert _get_type_hints_cache._Cache__currsize == 2 - assert _is_supported_generic_cache._Cache__currsize == 2 - assert _user_overrides_cache._Cache__currsize == 2 - - def test_dataclass_with_x_caches_class(self): - json_dataclass_with_x = '{"x": 1}' - _ = DataClassX.from_json(json_dataclass_with_x) - - # type hints for class cached - assert _get_type_hints_cache._Cache__currsize == 1 - # supported generic called for int - assert _is_supported_generic_cache._Cache__currsize == 1 - # for the dataclass - assert _user_overrides_cache._Cache__currsize == 1 - - # force cache hits - _ = DataClassX.from_json(json_dataclass_with_x) - - assert _get_type_hints_cache._Cache__currsize == 1 - assert _is_supported_generic_cache._Cache__currsize == 1 - assert _user_overrides_cache._Cache__currsize == 1 - - def test_dataclass_with_list_caches_class(self): - json_dataclass_with_list = '{"xs": [1]}' - _ = DataClassWithList.from_json(json_dataclass_with_list) - - # type hints for class cached - assert _get_type_hints_cache._Cache__currsize == 1 - # supported generic called for List[int] and int itself - assert _is_supported_generic_cache._Cache__currsize == 2 - # for the dataclass - assert _user_overrides_cache._Cache__currsize == 1 - - # force cache hits - _ = DataClassWithList.from_json(json_dataclass_with_list) - - assert _get_type_hints_cache._Cache__currsize == 1 - assert _is_supported_generic_cache._Cache__currsize == 2 - assert _user_overrides_cache._Cache__currsize == 1 - - def test_nested_dataclass_caches_both_classes(self): - json_dataclass_with_dataclass = '{"dc_with_list": {"xs": [1]}}' - _ = DataClassWithDataClass.from_json(json_dataclass_with_dataclass) - - assert _get_type_hints_cache._Cache__currsize == 2 - # supported generic called for List[int] and int - assert _is_supported_generic_cache._Cache__currsize == 2 - # for the dataclasses - assert _user_overrides_cache._Cache__currsize == 2 - - # force cache_hit - _ = DataClassWithDataClass.from_json(json_dataclass_with_dataclass) - - assert _get_type_hints_cache._Cache__currsize == 2 - assert _is_supported_generic_cache._Cache__currsize == 2 - assert _user_overrides_cache._Cache__currsize == 2