Skip to content

Commit 3555733

Browse files
committed
style: apply ruff auto-fixes for py310 target version
Ruff UP rules now flag old-style typing (Optional[X] -> X | None, Union -> |, typing.List -> list, typing.Tuple -> tuple, etc.) since target-version is py310. Also fix import sorting and zip() strict parameter warnings. Migrate tests/pyproject.toml ruff config to [tool.ruff.lint] section.
1 parent 4b65327 commit 3555733

15 files changed

Lines changed: 92 additions & 105 deletions

File tree

examples/in_memory/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pyright: reportGeneralTypeIssues=false
2+
from collections.abc import AsyncIterator
23
from contextlib import asynccontextmanager
3-
from typing import AsyncIterator, Dict, Optional
44

55
import pendulum
66
import uvicorn
@@ -94,9 +94,9 @@ async def handler_method(self):
9494
# cache a Pydantic model instance; the return type annotation is required in this case
9595
class Item(BaseModel):
9696
name: str
97-
description: Optional[str] = None
97+
description: str | None = None
9898
price: float
99-
tax: Optional[float] = None
99+
tax: float | None = None
100100

101101

102102
@app.get("/pydantic_instance")
@@ -129,7 +129,7 @@ async def cached_put():
129129
@cache(namespace="test", expire=5, injected_dependency_namespace="monty_python") # pyright: ignore[reportArgumentType]
130130
def namespaced_injection(
131131
__fastapi_cache_request: int = 42, __fastapi_cache_response: int = 17
132-
) -> Dict[str, int]:
132+
) -> dict[str, int]:
133133
return {
134134
"__fastapi_cache_request": __fastapi_cache_request,
135135
"__fastapi_cache_response": __fastapi_cache_response,

examples/redis/main.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# pyright: reportGeneralTypeIssues=false
22
import time
3+
from collections.abc import AsyncIterator
34
from contextlib import asynccontextmanager
4-
from typing import AsyncIterator
55

66
import pendulum
7+
import redis.asyncio as redis
78
import uvicorn
89
from fastapi import FastAPI
910
from fastapi.responses import HTMLResponse
@@ -13,12 +14,10 @@
1314
from fastapi_cache.backends.redis import RedisBackend
1415
from fastapi_cache.coder import PickleCoder
1516
from fastapi_cache.decorator import cache
17+
from redis.asyncio.connection import ConnectionPool
1618
from starlette.requests import Request
1719
from starlette.responses import JSONResponse, Response
1820

19-
import redis.asyncio as redis
20-
from redis.asyncio.connection import ConnectionPool
21-
2221

2322
@asynccontextmanager
2423
async def lifespan(_: FastAPI) -> AsyncIterator[None]:

fastapi_cache/__init__.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from importlib.metadata import version
2-
from typing import ClassVar, Optional, Type
2+
from typing import ClassVar
33

44
from fastapi_cache.coder import Coder, JsonCoder
55
from fastapi_cache.key_builder import default_key_builder
@@ -17,22 +17,22 @@
1717

1818

1919
class FastAPICache:
20-
_backend: ClassVar[Optional[Backend]] = None
21-
_prefix: ClassVar[Optional[str]] = None
22-
_expire: ClassVar[Optional[int]] = None
20+
_backend: ClassVar[Backend | None] = None
21+
_prefix: ClassVar[str | None] = None
22+
_expire: ClassVar[int | None] = None
2323
_init: ClassVar[bool] = False
24-
_coder: ClassVar[Optional[Type[Coder]]] = None
25-
_key_builder: ClassVar[Optional[KeyBuilder]] = None
26-
_cache_status_header: ClassVar[Optional[str]] = None
24+
_coder: ClassVar[type[Coder] | None] = None
25+
_key_builder: ClassVar[KeyBuilder | None] = None
26+
_cache_status_header: ClassVar[str | None] = None
2727
_enable: ClassVar[bool] = True
2828

2929
@classmethod
3030
def init(
3131
cls,
3232
backend: Backend,
3333
prefix: str = "",
34-
expire: Optional[int] = None,
35-
coder: Type[Coder] = JsonCoder,
34+
expire: int | None = None,
35+
coder: type[Coder] = JsonCoder,
3636
key_builder: KeyBuilder = default_key_builder,
3737
cache_status_header: str = "X-FastAPI-Cache",
3838
enable: bool = True,
@@ -70,11 +70,11 @@ def get_prefix(cls) -> str:
7070
return cls._prefix
7171

7272
@classmethod
73-
def get_expire(cls) -> Optional[int]:
73+
def get_expire(cls) -> int | None:
7474
return cls._expire
7575

7676
@classmethod
77-
def get_coder(cls) -> Type[Coder]:
77+
def get_coder(cls) -> type[Coder]:
7878
assert cls._coder, "You must call init first!" # noqa: S101
7979
return cls._coder
8080

@@ -94,7 +94,7 @@ def get_enable(cls) -> bool:
9494

9595
@classmethod
9696
async def clear(
97-
cls, namespace: Optional[str] = None, key: Optional[str] = None
97+
cls, namespace: str | None = None, key: str | None = None
9898
) -> int:
9999
assert ( # noqa: S101
100100
cls._backend and cls._prefix is not None

fastapi_cache/backends/dynamodb.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import datetime
2-
from typing import TYPE_CHECKING, Optional, Tuple
2+
from typing import TYPE_CHECKING
33

44
from aiobotocore.client import AioBaseClient
55
from aiobotocore.session import AioSession, get_session
@@ -33,9 +33,9 @@ class DynamoBackend(Backend):
3333
client: DynamoDBClient
3434
session: AioSession
3535
table_name: str
36-
region: Optional[str]
36+
region: str | None
3737

38-
def __init__(self, table_name: str, region: Optional[str] = None) -> None:
38+
def __init__(self, table_name: str, region: str | None = None) -> None:
3939
self.session: AioSession = get_session()
4040
self.table_name = table_name
4141
self.region = region
@@ -48,7 +48,7 @@ async def init(self) -> None:
4848
async def close(self) -> None:
4949
self.client = await self.client.__aexit__(None, None, None)
5050

51-
async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
51+
async def get_with_ttl(self, key: str) -> tuple[int, bytes | None]:
5252
response = await self.client.get_item(TableName=self.table_name, Key={"key": {"S": key}})
5353

5454
if "Item" in response:
@@ -65,13 +65,13 @@ async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
6565

6666
return 0, None
6767

68-
async def get(self, key: str) -> Optional[bytes]:
68+
async def get(self, key: str) -> bytes | None:
6969
response = await self.client.get_item(TableName=self.table_name, Key={"key": {"S": key}})
7070
if "Item" in response:
7171
return response["Item"].get("value", {}).get("B")
7272
return None
7373

74-
async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None:
74+
async def set(self, key: str, value: bytes, expire: int | None = None) -> None:
7575
ttl = (
7676
{
7777
"ttl": {
@@ -99,5 +99,5 @@ async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> Non
9999
},
100100
)
101101

102-
async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int:
102+
async def clear(self, namespace: str | None = None, key: str | None = None) -> int:
103103
raise NotImplementedError

fastapi_cache/backends/inmemory.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import time
22
from asyncio import Lock
33
from dataclasses import dataclass
4-
from typing import Dict, Optional, Tuple
54

65
from fastapi_cache.types import Backend
76

@@ -13,14 +12,14 @@ class Value:
1312

1413

1514
class InMemoryBackend(Backend):
16-
_store: Dict[str, Value] = {}
15+
_store: dict[str, Value] = {}
1716
_lock = Lock()
1817

1918
@property
2019
def _now(self) -> int:
2120
return int(time.time())
2221

23-
def _get(self, key: str) -> Optional[Value]:
22+
def _get(self, key: str) -> Value | None:
2423
v = self._store.get(key)
2524
if v:
2625
if v.ttl_ts < self._now:
@@ -29,25 +28,25 @@ def _get(self, key: str) -> Optional[Value]:
2928
return v
3029
return None
3130

32-
async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
31+
async def get_with_ttl(self, key: str) -> tuple[int, bytes | None]:
3332
async with self._lock:
3433
v = self._get(key)
3534
if v:
3635
return v.ttl_ts - self._now, v.data
3736
return 0, None
3837

39-
async def get(self, key: str) -> Optional[bytes]:
38+
async def get(self, key: str) -> bytes | None:
4039
async with self._lock:
4140
v = self._get(key)
4241
if v:
4342
return v.data
4443
return None
4544

46-
async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None:
45+
async def set(self, key: str, value: bytes, expire: int | None = None) -> None:
4746
async with self._lock:
4847
self._store[key] = Value(value, self._now + (expire or 0))
4948

50-
async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int:
49+
async def clear(self, namespace: str | None = None, key: str | None = None) -> int:
5150
count = 0
5251
if namespace:
5352
keys = list(self._store.keys())
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from typing import Optional, Tuple
21

32
from aiomcache import Client
43

@@ -9,14 +8,14 @@ class MemcachedBackend(Backend):
98
def __init__(self, mcache: Client):
109
self.mcache = mcache
1110

12-
async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
11+
async def get_with_ttl(self, key: str) -> tuple[int, bytes | None]:
1312
return 3600, await self.get(key)
1413

15-
async def get(self, key: str) -> Optional[bytes]:
14+
async def get(self, key: str) -> bytes | None:
1615
return await self.mcache.get(key.encode())
1716

18-
async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None:
17+
async def set(self, key: str, value: bytes, expire: int | None = None) -> None:
1918
await self.mcache.set(key.encode(), value, exptime=expire or 0)
2019

21-
async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int:
20+
async def clear(self, namespace: str | None = None, key: str | None = None) -> int:
2221
raise NotImplementedError

fastapi_cache/backends/redis.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional, Tuple, Union
1+
from typing import Union
22

33
from redis.asyncio.client import Redis
44
from redis.asyncio.cluster import RedisCluster
@@ -11,17 +11,17 @@ def __init__(self, redis: Union["Redis[bytes]", "RedisCluster[bytes]"]):
1111
self.redis = redis
1212
self.is_cluster: bool = isinstance(redis, RedisCluster)
1313

14-
async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
14+
async def get_with_ttl(self, key: str) -> tuple[int, bytes | None]:
1515
async with self.redis.pipeline(transaction=not self.is_cluster) as pipe:
1616
return await pipe.ttl(key).get(key).execute() # type: ignore[union-attr,no-any-return]
1717

18-
async def get(self, key: str) -> Optional[bytes]:
18+
async def get(self, key: str) -> bytes | None:
1919
return await self.redis.get(key) # type: ignore[union-attr]
2020

21-
async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None:
21+
async def set(self, key: str, value: bytes, expire: int | None = None) -> None:
2222
await self.redis.set(key, value, ex=expire) # type: ignore[union-attr]
2323

24-
async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int:
24+
async def clear(self, namespace: str | None = None, key: str | None = None) -> int:
2525
if namespace:
2626
lua = f"for i, name in ipairs(redis.call('KEYS', '{namespace}:*')) do redis.call('DEL', name); end"
2727
return await self.redis.eval(lua, numkeys=0) # type: ignore[union-attr,no-any-return]

fastapi_cache/coder.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import datetime
22
import json
33
import pickle # nosec:B403
4+
from collections.abc import Callable
45
from decimal import Decimal
56
from typing import (
67
Any,
7-
Callable,
88
ClassVar,
9-
Dict,
10-
Optional,
119
TypeVar,
12-
Union,
1310
overload,
1411
)
1512

@@ -27,7 +24,7 @@ class ModelField:
2724
_T = TypeVar("_T", bound=type)
2825

2926

30-
CONVERTERS: Dict[str, Callable[[str], Any]] = {
27+
CONVERTERS: dict[str, Callable[[str], Any]] = {
3128
# Pendulum 3.0.0 adds parse to __all__, at which point these ignores can be removed
3229
"date": lambda x: pendulum.parse(x, exact=True),
3330
"datetime": lambda x: pendulum.parse(x, exact=True),
@@ -72,7 +69,7 @@ def decode(cls, value: bytes) -> Any:
7269
# decode_as_type method and then stores a different kind of field for a
7370
# given type, do make sure that the subclass provides its own class
7471
# attribute for this cache.
75-
_type_field_cache: ClassVar[Dict[Any, ModelField]] = {}
72+
_type_field_cache: ClassVar[dict[Any, ModelField]] = {}
7673

7774
@overload
7875
@classmethod
@@ -85,7 +82,7 @@ def decode_as_type(cls, value: bytes, *, type_: None) -> Any:
8582
...
8683

8784
@classmethod
88-
def decode_as_type(cls, value: bytes, *, type_: Optional[_T]) -> Union[_T, Any]:
85+
def decode_as_type(cls, value: bytes, *, type_: _T | None) -> _T | Any:
8986
"""Decode value to the specific given type
9087
9188
The default implementation uses the Pydantic model system to convert the value.
@@ -122,7 +119,7 @@ def decode(cls, value: bytes) -> Any:
122119
return pickle.loads(value) # noqa: S301
123120

124121
@classmethod
125-
def decode_as_type(cls, value: bytes, *, type_: Optional[_T]) -> Any:
122+
def decode_as_type(cls, value: bytes, *, type_: _T | None) -> Any:
126123
# Pickle already produces the correct type on decoding, no point
127124
# in paying an extra performance penalty for pydantic to discover
128125
# the same.

0 commit comments

Comments
 (0)