diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a7fb01e..1294c63 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -22,12 +22,10 @@ jobs: fail-fast: false matrix: python-version: - - '3.8' - '3.9' - '3.10' - '3.11' - '3.12' - - 'pypy-3.10' services: redis: diff --git a/Makefile b/Makefile index 067dad6..853c5d4 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ clean: .PHONY: install install: - poetry install --all-extras --with=dev --with=docs + poetry install --sync --all-extras --with=dev --with=docs .PHONY: lint lint: lint/ruff lint/mypy diff --git a/cachetory/backends/async_/django.py b/cachetory/backends/async_/django.py index 868488b..08fff64 100644 --- a/cachetory/backends/async_/django.py +++ b/cachetory/backends/async_/django.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import AsyncIterable, Iterable from datetime import datetime, timedelta -from typing import AsyncIterable, Generic, Iterable +from typing import Generic from urllib.parse import urlparse from django.core.cache import BaseCache, cache, caches # type: ignore[import-untyped] diff --git a/cachetory/backends/async_/dummy.py b/cachetory/backends/async_/dummy.py index 87b17cd..6fcd6d5 100644 --- a/cachetory/backends/async_/dummy.py +++ b/cachetory/backends/async_/dummy.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import AsyncIterable, Iterable from datetime import datetime, timedelta -from typing import AsyncIterable, Generic, Iterable +from typing import Generic from cachetory.interfaces.backends.async_ import AsyncBackend from cachetory.interfaces.backends.private import WireT diff --git a/cachetory/backends/async_/memory.py b/cachetory/backends/async_/memory.py index f5272d0..4d96463 100644 --- a/cachetory/backends/async_/memory.py +++ b/cachetory/backends/async_/memory.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import Coroutine from datetime import datetime, timedelta -from typing import Any, Coroutine, Generic +from typing import Any, Generic from cachetory.backends.sync.memory import MemoryBackend as SyncMemoryBackend from cachetory.interfaces.backends.async_ import AsyncBackend diff --git a/cachetory/backends/async_/redis.py b/cachetory/backends/async_/redis.py index 512508a..78d251d 100644 --- a/cachetory/backends/async_/redis.py +++ b/cachetory/backends/async_/redis.py @@ -1,9 +1,9 @@ from __future__ import annotations import itertools +from collections.abc import AsyncIterable, Iterable from datetime import datetime, timedelta from types import TracebackType -from typing import AsyncIterable, Iterable from redis.asyncio import Redis diff --git a/cachetory/backends/sync/django.py b/cachetory/backends/sync/django.py index d5f674a..3029d1e 100644 --- a/cachetory/backends/sync/django.py +++ b/cachetory/backends/sync/django.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import Iterable from datetime import datetime, timedelta -from typing import Generic, Iterable +from typing import Generic from urllib.parse import urlparse from django.core.cache import BaseCache, cache, caches # type: ignore[import-untyped] diff --git a/cachetory/backends/sync/dummy.py b/cachetory/backends/sync/dummy.py index 2302781..ad9a040 100644 --- a/cachetory/backends/sync/dummy.py +++ b/cachetory/backends/sync/dummy.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import Iterable from datetime import datetime, timedelta -from typing import Generic, Iterable +from typing import Generic from cachetory.interfaces.backends.private import WireT from cachetory.interfaces.backends.sync import SyncBackend diff --git a/cachetory/backends/sync/redis.py b/cachetory/backends/sync/redis.py index f11f849..d7d4e30 100644 --- a/cachetory/backends/sync/redis.py +++ b/cachetory/backends/sync/redis.py @@ -1,9 +1,9 @@ from __future__ import annotations import itertools +from collections.abc import Iterable from datetime import datetime, timedelta from types import TracebackType -from typing import Iterable from redis import Redis diff --git a/cachetory/caches/async_.py b/cachetory/caches/async_.py index cef42d1..2d24eb8 100644 --- a/cachetory/caches/async_.py +++ b/cachetory/caches/async_.py @@ -1,11 +1,12 @@ from __future__ import annotations from asyncio import get_running_loop +from collections.abc import Iterable, Mapping from concurrent.futures import Executor from contextlib import AbstractAsyncContextManager from datetime import timedelta from types import TracebackType -from typing import Generic, Iterable, Mapping +from typing import Generic from cachetory.caches.private import DefaultT from cachetory.interfaces.backends.async_ import AsyncBackend diff --git a/cachetory/caches/sync.py b/cachetory/caches/sync.py index 14e93a6..188476b 100644 --- a/cachetory/caches/sync.py +++ b/cachetory/caches/sync.py @@ -1,7 +1,8 @@ +from collections.abc import Iterable, Mapping from contextlib import AbstractContextManager from datetime import timedelta from types import TracebackType -from typing import Dict, Generic, Iterable, Mapping, Optional, Tuple, Type, Union +from typing import Generic, Optional, Union from cachetory.caches.private import DefaultT from cachetory.interfaces.backends.private import WireT @@ -66,7 +67,7 @@ def get(self, key: str, default: DefaultT = None) -> Union[ValueT, DefaultT]: # except KeyError: return default - def get_many(self, *keys: str) -> Dict[str, ValueT]: + def get_many(self, *keys: str) -> dict[str, ValueT]: """ Retrieve many values from the cache. @@ -118,7 +119,7 @@ def set( # noqa: A003 if_not_exists=if_not_exists, ) - def set_many(self, items: Union[Iterable[Tuple[str, ValueT]], Mapping[str, ValueT]]) -> None: + def set_many(self, items: Union[Iterable[tuple[str, ValueT]], Mapping[str, ValueT]]) -> None: """ Set many cache items at once. @@ -154,7 +155,7 @@ def __delitem__(self, key: str) -> None: def __exit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: diff --git a/cachetory/decorators/async_.py b/cachetory/decorators/async_.py index 90df99a..c481cc4 100644 --- a/cachetory/decorators/async_.py +++ b/cachetory/decorators/async_.py @@ -1,8 +1,9 @@ from __future__ import annotations +from collections.abc import Awaitable from datetime import timedelta from functools import wraps -from typing import Awaitable, Callable, Protocol +from typing import Callable, Protocol from typing_extensions import ParamSpec diff --git a/cachetory/interfaces/backends/async_.py b/cachetory/interfaces/backends/async_.py index ae4b806..b620e77 100644 --- a/cachetory/interfaces/backends/async_.py +++ b/cachetory/interfaces/backends/async_.py @@ -8,10 +8,11 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod +from collections.abc import AsyncIterable, Iterable from contextlib import AbstractAsyncContextManager, AbstractContextManager from datetime import datetime, timedelta, timezone from types import TracebackType -from typing import Any, AsyncIterable, Generic, Iterable +from typing import Any, Generic from typing_extensions import Never, Protocol diff --git a/cachetory/interfaces/backends/sync.py b/cachetory/interfaces/backends/sync.py index 993b8df..09fca39 100644 --- a/cachetory/interfaces/backends/sync.py +++ b/cachetory/interfaces/backends/sync.py @@ -8,10 +8,11 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod +from collections.abc import Iterable from contextlib import AbstractContextManager from datetime import datetime, timedelta from types import TracebackType -from typing import Generic, Iterable +from typing import Generic from typing_extensions import Protocol diff --git a/cachetory/private/functools.py b/cachetory/private/functools.py index a28120b..2ed3c02 100644 --- a/cachetory/private/functools.py +++ b/cachetory/private/functools.py @@ -1,8 +1,9 @@ from __future__ import annotations +from collections.abc import Awaitable from functools import wraps from inspect import iscoroutinefunction -from typing import Any, Awaitable, Callable, TypeVar, cast +from typing import Any, Callable, TypeVar, cast T = TypeVar("T") diff --git a/cachetory/serializers/chained.py b/cachetory/serializers/chained.py index e1ca722..a379c13 100644 --- a/cachetory/serializers/chained.py +++ b/cachetory/serializers/chained.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import Any, Generic, Iterable, cast +from collections.abc import Iterable +from typing import Any, Generic, cast from urllib.parse import urlparse from cachetory.interfaces.backends.private import WireT diff --git a/cachetory/serializers/compressors/zlib.py b/cachetory/serializers/compressors/zlib.py index ec67d51..e728921 100644 --- a/cachetory/serializers/compressors/zlib.py +++ b/cachetory/serializers/compressors/zlib.py @@ -1,10 +1,10 @@ from __future__ import annotations import zlib +from typing import Annotated from urllib.parse import parse_qsl, urlparse from pydantic import BaseModel, Field -from typing_extensions import Annotated from cachetory.interfaces.serializers import Serializer diff --git a/cachetory/serializers/compressors/zstd.py b/cachetory/serializers/compressors/zstd.py index fb159be..8ae8948 100644 --- a/cachetory/serializers/compressors/zstd.py +++ b/cachetory/serializers/compressors/zstd.py @@ -1,10 +1,10 @@ from __future__ import annotations +from typing import Annotated from urllib.parse import parse_qsl, urlparse import zstd # type: ignore from pydantic import BaseModel, Field -from typing_extensions import Annotated from cachetory.interfaces.serializers import Serializer diff --git a/cachetory/serializers/pickle.py b/cachetory/serializers/pickle.py index 714d56e..7e0f2b7 100644 --- a/cachetory/serializers/pickle.py +++ b/cachetory/serializers/pickle.py @@ -1,11 +1,10 @@ from __future__ import annotations import pickle -from typing import Generic +from typing import Annotated, Generic from urllib.parse import parse_qsl, urlparse from pydantic import BaseModel, Field -from typing_extensions import Annotated from cachetory.interfaces.serializers import Serializer, ValueT diff --git a/poetry.lock b/poetry.lock index dc42c53..be41b0c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,9 +11,6 @@ files = [ {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - [[package]] name = "asgiref" version = "3.7.2" @@ -54,40 +51,11 @@ files = [ ] [package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} setuptools = {version = "*", markers = "python_version >= \"3.12\""} [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -optional = true -python-versions = ">=3.6" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "black" version = "24.8.0" @@ -538,7 +506,6 @@ files = [ [package.dependencies] asgiref = ">=3.6.0,<4" -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} sqlparse = ">=0.3.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} @@ -2038,5 +2005,5 @@ zstd = ["zstd"] [metadata] lock-version = "2.0" -python-versions = "^3.8.0" -content-hash = "9df07a71175d9859f10e7f8ea473019eb4b2f5c2bfc11adbb5106155a63e3942" +python-versions = "^3.9.0" +content-hash = "7a63309ea0501904d37a931e583f73e1cbcf3d2c5982cf1885288fc7989b9cd9" diff --git a/pyproject.toml b/pyproject.toml index ece3233..e9672bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [project] -requires-python = ">=3.8" +requires-python = ">=3.9" [tool.poetry] authors = [ @@ -20,7 +20,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -37,7 +36,7 @@ build-backend = "poetry_dynamic_versioning.backend" django = {version = "^4.0.0 || ^5.0.0", optional = true} ormsgpack = {version = "^1.4.0", optional = true, markers = "platform_python_implementation == 'CPython'"} pydantic = ">2.0.0.0, <3.0.0.0" -python = "^3.8.0" +python = "^3.9.0" redis = {version = "^4.4.2 || ^5.0.0", optional = true} typing-extensions = "^4.4.0" zstd = {version = "^1.5.2.6", optional = true} @@ -75,11 +74,11 @@ pillow = "10.4.0" [tool.black] line-length = 120 -target_version = ["py38", "py39", "py310", "py311"] +target_version = ["py39", "py310", "py311", "py312"] [tool.ruff] line-length = 120 -target-version = "py38" +target-version = "py39" [tool.ruff.lint] select = [ diff --git a/tests/backends/async_/test_django.py b/tests/backends/async_/test_django.py index e7a551b..39543c5 100644 --- a/tests/backends/async_/test_django.py +++ b/tests/backends/async_/test_django.py @@ -1,4 +1,4 @@ -from typing import AsyncIterable +from collections.abc import AsyncIterable import pytest diff --git a/tests/backends/async_/test_memory.py b/tests/backends/async_/test_memory.py index d4954a5..51a0652 100644 --- a/tests/backends/async_/test_memory.py +++ b/tests/backends/async_/test_memory.py @@ -1,5 +1,5 @@ +from collections.abc import AsyncIterable from datetime import datetime, timedelta, timezone -from typing import AsyncIterable from freezegun import freeze_time from pytest import fixture, mark, raises diff --git a/tests/backends/async_/test_redis.py b/tests/backends/async_/test_redis.py index 61360d2..f7636b0 100644 --- a/tests/backends/async_/test_redis.py +++ b/tests/backends/async_/test_redis.py @@ -1,6 +1,6 @@ from asyncio import sleep +from collections.abc import AsyncIterable from datetime import timedelta -from typing import AsyncIterable from pytest import fixture, mark, raises diff --git a/tests/backends/sync/test_django.py b/tests/backends/sync/test_django.py index 898519b..a4a0869 100644 --- a/tests/backends/sync/test_django.py +++ b/tests/backends/sync/test_django.py @@ -1,4 +1,4 @@ -from typing import Iterable +from collections.abc import Iterable import pytest diff --git a/tests/backends/sync/test_memory.py b/tests/backends/sync/test_memory.py index dd1f2c5..064e385 100644 --- a/tests/backends/sync/test_memory.py +++ b/tests/backends/sync/test_memory.py @@ -1,5 +1,5 @@ +from collections.abc import Iterable from datetime import datetime, timedelta, timezone -from typing import Iterable from freezegun import freeze_time from pytest import fixture, raises diff --git a/tests/backends/sync/test_redis.py b/tests/backends/sync/test_redis.py index ef18704..8474de3 100644 --- a/tests/backends/sync/test_redis.py +++ b/tests/backends/sync/test_redis.py @@ -1,6 +1,6 @@ +from collections.abc import Iterable from datetime import timedelta from time import sleep -from typing import Iterable from pytest import fixture, raises diff --git a/tests/decorators/test_shared.py b/tests/decorators/test_shared.py index 7cc7e5c..d7aa30b 100644 --- a/tests/decorators/test_shared.py +++ b/tests/decorators/test_shared.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Dict, Tuple +from typing import Any, Callable from pytest import mark @@ -32,8 +32,8 @@ def _callable() -> None: ) def test_make_default_key( callable_: Callable[..., Any], - args: Tuple[Any, ...], - kwargs: Dict[str, Any], + args: tuple[Any, ...], + kwargs: dict[str, Any], expected_key: str, ) -> None: assert make_default_key(callable_, *args, **kwargs) == expected_key diff --git a/tests/private/test_functools.py b/tests/private/test_functools.py index b4a741f..e070065 100644 --- a/tests/private/test_functools.py +++ b/tests/private/test_functools.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import Awaitable, Callable +from collections.abc import Awaitable +from typing import Callable import pytest diff --git a/tests/serializers/test_chained.py b/tests/serializers/test_chained.py index 38d53ed..d98599e 100644 --- a/tests/serializers/test_chained.py +++ b/tests/serializers/test_chained.py @@ -1,4 +1,5 @@ -from typing import Any, Iterable, List, Type, cast +from collections.abc import Iterable +from typing import Any, cast import pytest from pytest import mark, raises @@ -23,7 +24,7 @@ ("pickle+zstd://", [PickleSerializer, ZstdCompressor]), ], ) -def test_layers(url: str, expected_layers: List[Type[Serializer[Any, Any]]]) -> None: +def test_layers(url: str, expected_layers: list[type[Serializer[Any, Any]]]) -> None: assert [ type(layer) for layer in cast(Iterable[Serializer[Any, Any]], ChainedSerializer.from_url(url)._layers) ] == expected_layers