diff --git a/pottery/base.py b/pottery/base.py index 4ce95603..ae046fd5 100644 --- a/pottery/base.py +++ b/pottery/base.py @@ -16,6 +16,10 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + import abc import collections import contextlib @@ -31,8 +35,6 @@ from typing import Generator from typing import Iterable from typing import List -from typing import Mapping -from typing import Optional from typing import Tuple from typing import cast @@ -95,8 +97,8 @@ class _Common: def __init__(self, *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> None: self.redis = cast(Redis, redis) self.key = cast(str, key) @@ -118,7 +120,7 @@ def redis(self) -> Redis: return self.__redis @redis.setter - def redis(self, value: Optional[Redis]) -> None: + def redis(self, value: Redis | None) -> None: self.__redis = _default_redis if value is None else value @property @@ -329,7 +331,7 @@ def key(self, value: str) -> None: self.__key = f'{self.KEY_PREFIX}:{value}' def _check_enough_masters_up(self, - raise_on_redis_errors: Optional[bool], + raise_on_redis_errors: bool | None, redis_errors: List[RedisError], ) -> None: if raise_on_redis_errors is None: diff --git a/pottery/cache.py b/pottery/cache.py index 10a6ac01..7e42f560 100644 --- a/pottery/cache.py +++ b/pottery/cache.py @@ -30,7 +30,6 @@ from typing import Hashable from typing import Iterable from typing import NamedTuple -from typing import Optional from typing import TypeVar from typing import cast @@ -60,7 +59,7 @@ class CacheInfo(NamedTuple): ''' hits: int = 0 misses: int = 0 - maxsize: Optional[int] = None + maxsize: int | None = None currsize: int = 0 @@ -73,9 +72,9 @@ def _arg_hash(*args: Hashable, **kwargs: Hashable) -> int: def redis_cache(*, # NoQA: C901 - redis: Optional[Redis] = None, - key: Optional[str] = None, - timeout: Optional[int] = _DEFAULT_TIMEOUT, + redis: Redis | None = None, + key: str | None = None, + timeout: int | None = _DEFAULT_TIMEOUT, ) -> Callable[[F], F]: '''Redis-backed caching decorator with an API like functools.lru_cache(). @@ -219,11 +218,11 @@ class CachedOrderedDict(collections.OrderedDict): @_set_expiration def __init__(self, *, - redis_client: Optional[Redis] = None, - redis_key: Optional[str] = None, + redis_client: Redis | None = None, + redis_key: str | None = None, dict_keys: Iterable[JSONTypes] = tuple(), num_tries: int = _NUM_TRIES, - timeout: Optional[int] = _DEFAULT_TIMEOUT, + timeout: int | None = _DEFAULT_TIMEOUT, ) -> None: self._num_tries = num_tries self._timeout = timeout diff --git a/pottery/counter.py b/pottery/counter.py index 1d55fad9..70bc6d80 100644 --- a/pottery/counter.py +++ b/pottery/counter.py @@ -29,7 +29,6 @@ from typing import Callable from typing import Iterable from typing import List -from typing import Optional from typing import Tuple from typing import Union from typing import cast @@ -251,7 +250,7 @@ def __iand__(self, other: Counter[JSONTypes]) -> Counter[JSONTypes]: return self.__iset_op(other, method=int.__lt__) def most_common(self, - n: Optional[int] = None, + n: int | None = None, ) -> List[Tuple[JSONTypes, int]]: counter = self.__to_counter() return counter.most_common(n=n) diff --git a/pottery/deque.py b/pottery/deque.py index dc438ecf..3ef147ba 100644 --- a/pottery/deque.py +++ b/pottery/deque.py @@ -23,7 +23,6 @@ import collections import warnings from typing import Iterable -from typing import Optional from typing import Tuple from typing import cast @@ -44,10 +43,10 @@ class RedisDeque(RedisList, collections.deque): # type: ignore def __init__(self, iterable: Iterable[JSONTypes] = tuple(), - maxlen: Optional[int] = None, + maxlen: int | None = None, *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> None: 'Initialize the RedisDeque. O(n)' if maxlen is not None and not isinstance(maxlen, int): @@ -73,7 +72,7 @@ def _populate(self, super()._populate(pipeline, iterable) @property - def maxlen(self) -> Optional[int]: + def maxlen(self) -> int | None: return self._maxlen @maxlen.setter diff --git a/pottery/dict.py b/pottery/dict.py index 20119dbb..1b16d6f5 100644 --- a/pottery/dict.py +++ b/pottery/dict.py @@ -16,6 +16,10 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + import collections.abc import itertools import warnings @@ -24,7 +28,6 @@ from typing import Generator from typing import Iterable from typing import Mapping -from typing import Optional from typing import Tuple from typing import Union from typing import cast @@ -51,8 +54,8 @@ class RedisDict(Base, Iterable_, collections.abc.MutableMapping): def __init__(self, arg: InitArg = tuple(), *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, **kwargs: JSONTypes, ) -> None: 'Initialize the RedisDict. O(n)' diff --git a/pottery/exceptions.py b/pottery/exceptions.py index 83980209..d76c03a8 100644 --- a/pottery/exceptions.py +++ b/pottery/exceptions.py @@ -16,10 +16,13 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + from dataclasses import dataclass from queue import Empty from typing import Iterable -from typing import Optional from redis import Redis from redis import RedisError @@ -30,7 +33,7 @@ class PotteryError(Exception): 'Base exception class for Pottery containers.' redis: Redis - key: Optional[str] = None + key: str | None = None class KeyExistsError(PotteryError): 'Initializing a container on a Redis key that already exists.' diff --git a/pottery/executor.py b/pottery/executor.py index dfe20ddd..bbd23104 100644 --- a/pottery/executor.py +++ b/pottery/executor.py @@ -16,9 +16,12 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + import concurrent.futures from types import TracebackType -from typing import Optional from typing import Type from typing import overload @@ -69,9 +72,9 @@ def __exit__(self, raise NotImplementedError def __exit__(self, - exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - exc_traceback: Optional[TracebackType], + exc_type: Type[BaseException] | None, + exc_value: BaseException | None, + exc_traceback: TracebackType | None, ) -> Literal[False]: self.shutdown(wait=False) return False diff --git a/pottery/hyper.py b/pottery/hyper.py index 22f84821..bac0767c 100644 --- a/pottery/hyper.py +++ b/pottery/hyper.py @@ -27,7 +27,6 @@ from typing import Generator from typing import Iterable from typing import List -from typing import Optional from typing import cast from redis import Redis @@ -107,8 +106,8 @@ class HyperLogLog(Base): def __init__(self, iterable: Iterable[RedisValues] = frozenset(), *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> None: '''Initialize the HyperLogLog. O(n) @@ -149,8 +148,8 @@ def update(self, *objs: HyperLogLog | Iterable[RedisValues]) -> None: def union(self, *objs: Iterable[RedisValues], - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> HyperLogLog: new_hll = self.__class__(redis=redis, key=key) new_hll.update(self, *objs) diff --git a/pottery/list.py b/pottery/list.py index 3c5175f2..72798a71 100644 --- a/pottery/list.py +++ b/pottery/list.py @@ -32,7 +32,6 @@ from typing import Callable from typing import Iterable from typing import List -from typing import Optional from typing import cast from redis import Redis @@ -82,8 +81,8 @@ def __slice_to_indices(self, slice_or_index: slice | int) -> range: def __init__(self, iterable: Iterable[JSONTypes] = tuple(), *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> None: 'Initialize the RedisList. O(n)' super().__init__(redis=redis, key=key) @@ -251,7 +250,7 @@ def _insert(self, # Methods required for Raj's sanity: - def sort(self, *, key: Optional[str] = None, reverse: bool = False) -> None: + def sort(self, *, key: str | None = None, reverse: bool = False) -> None: 'Sort the RedisList in place. O(n)' if key is not None: raise NotImplementedError('sorting by key not implemented') @@ -321,7 +320,7 @@ def extend(self, values: Iterable[JSONTypes]) -> None: __extend = extend # From collections.abc.MutableSequence: - def pop(self, index: Optional[int] = None) -> JSONTypes: + def pop(self, index: int | None = None) -> JSONTypes: with self._watch() as pipeline: len_ = len(self) if index and index >= len_: diff --git a/pottery/nextid.py b/pottery/nextid.py index c0df612a..aeda0df0 100644 --- a/pottery/nextid.py +++ b/pottery/nextid.py @@ -36,7 +36,6 @@ from typing import ClassVar from typing import Iterable from typing import List -from typing import Optional from typing import Tuple from typing import Type from typing import cast @@ -61,7 +60,7 @@ class _Scripts(Primitive): __slots__: Tuple[str, ...] = tuple() - _set_id_script: ClassVar[Optional[Script]] = None + _set_id_script: ClassVar[Script | None] = None def __init__(self, *, diff --git a/pottery/queue.py b/pottery/queue.py index 87b6b0b4..7fc9bc32 100644 --- a/pottery/queue.py +++ b/pottery/queue.py @@ -16,11 +16,14 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + import math import random import time from typing import ClassVar -from typing import Optional from typing import Tuple from typing import cast @@ -61,7 +64,7 @@ def empty(self) -> bool: def put(self, item: JSONTypes, block: bool = True, - timeout: Optional[float] = None, + timeout: float | None = None, ) -> None: '''Put the item on the queue. O(1) @@ -84,7 +87,7 @@ def put_nowait(self, item: JSONTypes) -> None: def get(self, block: bool = True, - timeout: Optional[float] = None, + timeout: float | None = None, ) -> JSONTypes: '''Remove and return an item from the queue. O(1) diff --git a/pottery/redlock.py b/pottery/redlock.py index 6929b652..55d7dd55 100644 --- a/pottery/redlock.py +++ b/pottery/redlock.py @@ -51,7 +51,6 @@ from typing import Callable from typing import ClassVar from typing import Iterable -from typing import Optional from typing import Tuple from typing import Type from typing import cast @@ -88,9 +87,9 @@ class _Scripts(Primitive): __slots__: Tuple[str, ...] = tuple() - _acquired_script: ClassVar[Optional[Script]] = None - _extend_script: ClassVar[Optional[Script]] = None - _release_script: ClassVar[Optional[Script]] = None + _acquired_script: ClassVar[Script | None] = None + _extend_script: ClassVar[Script | None] = None + _release_script: ClassVar[Script | None] = None def __init__(self, *, @@ -330,7 +329,7 @@ def __drift(self) -> float: def __acquire_masters(self, *, - raise_on_redis_errors: Optional[bool] = None, + raise_on_redis_errors: bool | None = None, ) -> bool: self._uuid = str(uuid.uuid4()) self._extension_num = 0 @@ -369,7 +368,7 @@ def acquire(self, *, blocking: bool = True, timeout: float = -1, - raise_on_redis_errors: Optional[bool] = None, + raise_on_redis_errors: bool | None = None, ) -> bool: '''Lock the lock. @@ -454,7 +453,7 @@ def log_time_enqueued(timer: ContextTimer, acquired: bool) -> None: __acquire = acquire - def locked(self, *, raise_on_redis_errors: Optional[bool] = None) -> int: + def locked(self, *, raise_on_redis_errors: bool | None = None) -> int: '''How much longer we'll hold the lock (unless we extend or release it). If we don't currently hold the lock, then this method returns 0. @@ -513,7 +512,7 @@ def locked(self, *, raise_on_redis_errors: Optional[bool] = None) -> int: __locked = locked - def extend(self, *, raise_on_redis_errors: Optional[bool] = None) -> None: + def extend(self, *, raise_on_redis_errors: bool | None = None) -> None: '''Extend our hold on the lock (if we currently hold it). Usage: @@ -565,7 +564,7 @@ def extend(self, *, raise_on_redis_errors: Optional[bool] = None) -> None: redis_errors=redis_errors, ) - def release(self, *, raise_on_redis_errors: Optional[bool] = None) -> None: + def release(self, *, raise_on_redis_errors: bool | None = None) -> None: '''Unlock the lock. Usage: @@ -661,9 +660,9 @@ def __exit__(self, raise NotImplementedError def __exit__(self, - exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - traceback: Optional[TracebackType], + exc_type: Type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, ) -> Literal[False]: '''You can use a Redlock as a context manager. diff --git a/pottery/set.py b/pottery/set.py index b5920542..bbad1c64 100644 --- a/pottery/set.py +++ b/pottery/set.py @@ -16,6 +16,10 @@ # --------------------------------------------------------------------------- # +# TODO: When we drop support for Python 3.9, remove the following import. We +# only need it for X | Y union type annotations as of 2022-01-29. +from __future__ import annotations + import collections.abc import itertools import uuid @@ -24,7 +28,6 @@ from typing import Generator from typing import Iterable from typing import NoReturn -from typing import Optional from typing import Set from typing import cast @@ -45,8 +48,8 @@ class RedisSet(Base, Iterable_, collections.abc.MutableSet): def __init__(self, iterable: Iterable[JSONTypes] = tuple(), *, - redis: Optional[Redis] = None, - key: Optional[str] = None, + redis: Redis | None = None, + key: str | None = None, ) -> None: 'Initialize the RedisSet. O(n)' super().__init__(redis=redis, key=key) diff --git a/pottery/timer.py b/pottery/timer.py index a344da4b..2f2ddbd1 100644 --- a/pottery/timer.py +++ b/pottery/timer.py @@ -26,7 +26,6 @@ import timeit from types import TracebackType -from typing import Optional from typing import Type from typing import overload @@ -91,9 +90,9 @@ def __exit__(self, raise NotImplementedError def __exit__(self, - exc_type: Optional[Type[BaseException]], - exc_value: Optional[BaseException], - exc_traceback: Optional[TracebackType], + exc_type: Type[BaseException] | None, + exc_value: BaseException | None, + exc_traceback: TracebackType | None, ) -> Literal[False]: self.__stop() return False