Upgrading limits 2 to 3
Breaking2.8.0 → 3.14.1Breaking2Platform3Deprecated1New4Changed12Fixed10Other18
BreakingUpgrade verdict
2 breaking changes and 3 platform requirement changes.
In plain terms
- The package no longer falls back to the redis-py-cluster library for Redis cluster support.
- The old Google App Engine Memcached storage option is gone, so anyone using it must switch to another storage backend.
- The package can now be installed and used on Python 3.13.
- Python 3.8 is no longer supported, so users on 3.8 must upgrade their Python version.
Must act Top 5 of 6 that need code or config changes
Python requirement changed in 3.14.0: >=3.7 → >=3.9.
Drops setuptools.
Installs 4 packages in all (was 5).
What you must change
Breaking2
Removes fallback support for redis-py-cluster.
redis-py-clusterRemoves the deprecated GAE Memcached storage.
Platform3
Adds support for Python 3.13.
Drops support for Python 3.8.
Adds support for Python 3.12.
Deprecations to plan for
Deprecated1
Removes deprecated use of pkg_resources and switches to importlib_resource.
pkg_resourcesimportlib_resourceAPI changes
Generated by DepDelta from published Python source. Not mixed with prose notes.
- added:
export WindowStats
- added:
export EtcdStorage
- changed:
constructor Storage(uri: Optional[str]=…, **options: Union[float, str, bool]) -> None → constructor Storage(uri: Optional[str]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
property Storage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- added:
async method EtcdStorage.check() -> bool - added:
async method EtcdStorage.clear(key: str) -> None - added:
async method EtcdStorage.get(key: str) -> int - added:
async method EtcdStorage.get_expiry(key: str) -> int - added:
async method EtcdStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int - added:
async method EtcdStorage.reset() -> Optional[int] - added:
class EtcdStorage(Storage) - added:
constructor EtcdStorage(uri: str, max_retries: int=…, **options: str) -> None - added:
field EtcdStorage.DEPENDENCIES - added:
field EtcdStorage.MAX_RETRIES - added:
field EtcdStorage.PREFIX - added:
field EtcdStorage.STORAGE_SCHEME - added:
method EtcdStorage.prefixed_key(key: str) -> bytes - added:
property EtcdStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
constructor MemcachedStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor MemcachedStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
property MemcachedStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
constructor MemoryStorage(uri: Optional[str]=…, **_: str) -> None → constructor MemoryStorage(uri: Optional[str]=…, wrap_exceptions: bool=…, **_: str) -> None - added:
property MemoryStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- removed:
field MongoDBStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]] - changed:
constructor MongoDBStorage(uri: str, database_name: str=…, **options: Union[float, str, bool]) -> None → constructor MongoDBStorage(uri: str, database_name: str=…, counter_collection_name: str=…, window_collection_name: str=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
property MongoDBStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- removed:
field RedisSentinelStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]] - changed:
constructor RedisClusterStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor RedisClusterStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - changed:
constructor RedisStorage(uri: str, connection_pool: Optional[coredis.ConnectionPool]=…, **options: Union[float, str, bool]) -> None → constructor RedisStorage(uri: str, connection_pool: Optional[coredis.ConnectionPool]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
field RedisInteractor.PREFIX - added:
method RedisInteractor.prefixed_key(key: str) -> str - added:
property RedisStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
async method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
async method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool - changed:
async method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
async method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool - changed:
async method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
async method RateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method RateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
- added:
class ConcurrentUpdateError(Exception) - added:
class StorageError(Exception) - added:
constructor ConcurrentUpdateError(key: str, attempts: int) -> None - added:
constructor StorageError(storage_error: Exception) -> None
- removed:
export GAEMemcachedStorage - added:
export EtcdStorage - added:
export MongoDBStorageBase
- changed:
constructor Storage(uri: Optional[str]=…, **options: Union[float, str, bool]) → constructor Storage(uri: Optional[str]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) - added:
property Storage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- added:
class EtcdStorage(Storage) - added:
constructor EtcdStorage(uri: str, max_retries: int=…, **options: str) -> None - added:
field EtcdStorage.DEPENDENCIES - added:
field EtcdStorage.MAX_RETRIES - added:
field EtcdStorage.PREFIX - added:
field EtcdStorage.STORAGE_SCHEME - added:
method EtcdStorage.check() -> bool - added:
method EtcdStorage.clear(key: str) -> None - added:
method EtcdStorage.get(key: str) -> int - added:
method EtcdStorage.get_expiry(key: str) -> int - added:
method EtcdStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int - added:
method EtcdStorage.prefixed_key(key: str) -> bytes - added:
method EtcdStorage.reset() -> Optional[int] - added:
property EtcdStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- removed:
class GAEMemcachedStorage(MemcachedStorage) - removed:
constructor GAEMemcachedStorage(uri: str, **options) - removed:
field GAEMemcachedStorage.MAX_CAS_RETRIES - removed:
field GAEMemcachedStorage.STORAGE_SCHEME - removed:
method GAEMemcachedStorage.check() -> bool - removed:
method GAEMemcachedStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…)
- changed:
constructor MemcachedStorage(uri: str, **options: Union[str, Callable[[], MemcachedClientP]]) -> None → constructor MemcachedStorage(uri: str, wrap_exceptions: bool=…, **options: Union[str, Callable[[], MemcachedClientP]]) -> None - added:
field MemcachedStorage.DEPENDENCIES - added:
property MemcachedStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
constructor MemoryStorage(uri: Optional[str]=…, **_: str) → constructor MemoryStorage(uri: Optional[str]=…, wrap_exceptions: bool=…, **_: str) - added:
property MemoryStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- removed:
constructor MongoDBStorage(uri: str, database_name: str=…, **options: Union[int, str, bool]) -> None - removed:
field MongoDBStorage.DEFAULT_OPTIONS: Dict[str, Union[int, str, bool]] - removed:
field MongoDBStorage.DEPENDENCIES - removed:
method MongoDBStorage.acquire_entry(key: str, limit: int, expiry: int, amount: int=…) -> bool - removed:
method MongoDBStorage.check() -> bool - removed:
method MongoDBStorage.clear(key: str) -> None - removed:
method MongoDBStorage.get(key: str) -> int - removed:
method MongoDBStorage.get_expiry(key: str) -> int - removed:
method MongoDBStorage.get_moving_window(key: str, limit: int, expiry: int) -> Tuple[int, int] - removed:
method MongoDBStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int - removed:
method MongoDBStorage.reset() -> Optional[int] - changed:
class MongoDBStorage(Storage, MovingWindowSupport) → class MongoDBStorage(MongoDBStorageBase) - added:
class MongoDBStorageBase(Storage, MovingWindowSupport, ABC) - added:
constructor MongoDBStorageBase(uri: str, database_name: str=…, counter_collection_name: str=…, window_collection_name: str=…, wrap_exceptions: bool=…, **options: Union[int, str, bool]) -> None - added:
field MongoDBStorageBase.DEPENDENCIES - added:
method MongoDBStorageBase.acquire_entry(key: str, limit: int, expiry: int, amount: int=…) -> bool - added:
method MongoDBStorageBase.check() -> bool - added:
method MongoDBStorageBase.clear(key: str) -> None - added:
method MongoDBStorageBase.get(key: str) -> int - added:
method MongoDBStorageBase.get_expiry(key: str) -> int - added:
method MongoDBStorageBase.get_moving_window(key: str, limit: int, expiry: int) -> Tuple[int, int] - added:
method MongoDBStorageBase.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int - added:
method MongoDBStorageBase.reset() -> Optional[int] - added:
property MongoDBStorageBase.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]] - added:
property MongoDBStorageBase.counters -> MongoCollection - added:
property MongoDBStorageBase.storage -> MongoClient - added:
property MongoDBStorageBase.windows -> MongoCollection
- changed:
constructor RedisStorage(uri: str, connection_pool: Optional[redis.connection.ConnectionPool]=…, **options: Union[float, str, bool]) -> None → constructor RedisStorage(uri: str, connection_pool: Optional[redis.connection.ConnectionPool]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
field RedisInteractor.PREFIX - added:
method RedisInteractor.prefixed_key(key: str) -> str - added:
property RedisStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
constructor RedisClusterStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor RedisClusterStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
- removed:
field RedisSentinelStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]] - changed:
constructor RedisSentinelStorage(uri: str, service_name: Optional[str]=…, use_replicas: bool=…, sentinel_kwargs: Optional[Dict[str, Union[float, str, bool]]]=…, **options: Union[float, str, bool]) -> None → constructor RedisSentinelStorage(uri: str, service_name: Optional[str]=…, use_replicas: bool=…, sentinel_kwargs: Optional[Dict[str, Union[float, str, bool]]]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None - added:
property RedisSentinelStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
- changed:
method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool - changed:
method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool - changed:
method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats - changed:
method RateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method RateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
- added:
export Awaitable - added:
export NamedTuple - added:
variable MongoClient: TypeAlias - added:
variable MongoCollection: TypeAlias - added:
variable MongoDatabase: TypeAlias
- added:
class WindowStats(NamedTuple) - added:
field WindowStats.remaining: int - added:
field WindowStats.reset_time: int