Skip to content

Commit c5e831e

Browse files
committed
decorators.cache: use Generic type. drop py38
1 parent a9cc009 commit c5e831e

File tree

5 files changed

+12
-11
lines changed

5 files changed

+12
-11
lines changed

fan_tools/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.13.0'
1+
__version__ = '4.0.0'

fan_tools/python/decorators.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import functools
44
import logging
55
from pathlib import Path
6-
from typing import Awaitable, Callable, Protocol, Type, TypeVar, Union
6+
from typing import Awaitable, Callable, Generic, Protocol, Type, TypeVar, Union
77

88

99
try:
@@ -77,34 +77,34 @@ def json(self) -> str:
7777
...
7878

7979

80-
FuncType = Callable[P, Awaitable[PydanticBaseModel]]
80+
ModelType = TypeVar('ModelType', bound=PydanticBaseModel)
8181

8282

83-
class cache_async:
83+
class cache_async(Generic[ModelType]):
8484
"""
8585
file cache for async functions that returns pydantic models
8686
NB: it doesn't use parameters to generate the cache file name
8787
"""
8888

89-
def __init__(self, fname: Path, model: PydanticBaseModel, default: PydanticBaseModel):
89+
def __init__(self, fname: Path, model: ModelType, default: ModelType):
9090
self.fname = fname
9191
self._default = default
9292
self.cache = default
9393
# load from file
9494
if self.fname.exists():
9595
self.cache = model.parse_file(self.fname)
9696

97-
def __call__(self, func: FuncType[P]) -> FuncType[P]:
97+
def __call__(self, func: Callable[P, Awaitable[ModelType]]):
9898
@functools.wraps(func)
99-
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> PydanticBaseModel:
99+
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> ModelType:
100100
if self.cache:
101101
return self.cache
102102
value = await func(*args, **kwargs)
103103
self.cache = value
104104
self.fname.write_text(self.cache.json())
105105
return value
106106

107-
wrapper.reset_cache = self.reset_cache
107+
wrapper.reset_cache = self.reset_cache # type: ignore
108108

109109
return wrapper
110110

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ classifiers = [
2121
'Operating System :: POSIX :: Linux',
2222
'Operating System :: Unix',
2323
'Programming Language :: Python',
24-
'Programming Language :: Python :: 3.8',
2524
'Programming Language :: Python :: 3.9',
25+
'Programming Language :: Python :: 3.10',
26+
'Programming Language :: Python :: 3.11',
2627
'Programming Language :: Python :: Implementation',
2728
'Programming Language :: Python :: Implementation :: CPython',
2829
'Topic :: Software Development',

tests/test_decorators.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ async def test_01_simplest(self, tmp_path):
1010

1111
model.json.return_value = '{"a": "b"}'
1212

13-
@cache_async(fname, model, {})
13+
@cache_async[type(dict)](fname, model, {})
1414
async def func():
1515
return model
1616

tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[tox]
22
min_version = 4.3
33
isolated_build = True
4-
envlist = py{38,39,310}-django{32,40} #,mypy
4+
envlist = py{39,310,311}-django{32,40} #,mypy
55

66
[testenv]
77
extras =

0 commit comments

Comments
 (0)