diskcache-community 5.8.0__tar.gz → 5.8.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {diskcache_community-5.8.0/diskcache_community.egg-info → diskcache_community-5.8.1}/PKG-INFO +2 -2
  2. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/__init__.py +2 -2
  3. diskcache_community-5.8.1/diskcache_community/__init__.pyi +58 -0
  4. diskcache_community-5.8.1/diskcache_community/_types.pyi +227 -0
  5. diskcache_community-5.8.1/diskcache_community/core.pyi +327 -0
  6. diskcache_community-5.8.1/diskcache_community/djangocache.pyi +101 -0
  7. diskcache_community-5.8.1/diskcache_community/fanout.pyi +70 -0
  8. diskcache_community-5.8.1/diskcache_community/persistent.pyi +161 -0
  9. diskcache_community-5.8.1/diskcache_community/py.typed +0 -0
  10. diskcache_community-5.8.1/diskcache_community/recipes.pyi +102 -0
  11. {diskcache_community-5.8.0 → diskcache_community-5.8.1/diskcache_community.egg-info}/PKG-INFO +2 -2
  12. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community.egg-info/SOURCES.txt +8 -0
  13. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/pyproject.toml +1 -1
  14. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/LICENSE +0 -0
  15. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/NOTICE +0 -0
  16. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/README.md +0 -0
  17. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/cli.py +0 -0
  18. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/core.py +0 -0
  19. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/djangocache.py +0 -0
  20. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/fanout.py +0 -0
  21. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/persistent.py +0 -0
  22. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community/recipes.py +0 -0
  23. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community.egg-info/dependency_links.txt +0 -0
  24. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/diskcache_community.egg-info/top_level.txt +0 -0
  25. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/setup.cfg +0 -0
  26. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_core.py +0 -0
  27. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_default_disk.py +0 -0
  28. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_deque.py +0 -0
  29. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_djangocache.py +0 -0
  30. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_doctest.py +0 -0
  31. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_entry_errors.py +0 -0
  32. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_fanout.py +0 -0
  33. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_golden.py +0 -0
  34. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_index.py +0 -0
  35. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_init.py +0 -0
  36. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_readonly.py +0 -0
  37. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_recipes.py +0 -0
  38. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_safedisk.py +0 -0
  39. {diskcache_community-5.8.0 → diskcache_community-5.8.1}/tests/test_safedisk_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diskcache-community
3
- Version: 5.8.0
3
+ Version: 5.8.1
4
4
  Summary: Disk Cache -- Disk and file backed persistent cache.
5
5
  Author: Grant Jenks
6
6
  Maintainer: diskcache-community contributors
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
23
  Classifier: Programming Language :: Python :: 3.14
24
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
- Requires-Python: >=3.10
25
+ Requires-Python: >=3.9
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  License-File: NOTICE
@@ -70,8 +70,8 @@ except Exception: # pylint: disable=broad-except # pragma: no cover
70
70
 
71
71
 
72
72
  __title__ = 'diskcache-community'
73
- __version__ = '5.8.0'
74
- __build__ = 0x050800
73
+ __version__ = '5.8.1'
74
+ __build__ = 0x050801
75
75
  __author__ = 'Grant Jenks'
76
76
  __license__ = 'Apache 2.0'
77
77
  __copyright__ = 'Copyright 2016-2023 Grant Jenks'
@@ -0,0 +1,58 @@
1
+ from diskcache_community.core import DEFAULT_SETTINGS as DEFAULT_SETTINGS
2
+ from diskcache_community.core import ENOVAL as ENOVAL
3
+ from diskcache_community.core import EVICTION_POLICY as EVICTION_POLICY
4
+ from diskcache_community.core import UNKNOWN as UNKNOWN
5
+ from diskcache_community.core import Cache as Cache
6
+ from diskcache_community.core import Disk as Disk
7
+ from diskcache_community.core import EmptyDirWarning as EmptyDirWarning
8
+ from diskcache_community.core import JSONDisk as JSONDisk
9
+ from diskcache_community.core import ReadOnlyError as ReadOnlyError
10
+ from diskcache_community.core import SafeDisk as SafeDisk
11
+ from diskcache_community.core import Timeout as Timeout
12
+ from diskcache_community.core import UnknownFileWarning as UnknownFileWarning
13
+ from diskcache_community.core import configure as configure
14
+ from diskcache_community.core import default_disk as default_disk
15
+ from diskcache_community.fanout import FanoutCache as FanoutCache
16
+ from diskcache_community.persistent import Deque as Deque
17
+ from diskcache_community.persistent import Index as Index
18
+ from diskcache_community.recipes import Averager as Averager
19
+ from diskcache_community.recipes import BoundedSemaphore as BoundedSemaphore
20
+ from diskcache_community.recipes import Lock as Lock
21
+ from diskcache_community.recipes import RLock as RLock
22
+ from diskcache_community.recipes import barrier as barrier
23
+ from diskcache_community.recipes import memoize_stampede as memoize_stampede
24
+ from diskcache_community.recipes import throttle as throttle
25
+
26
+ __all__ = [
27
+ 'Averager',
28
+ 'BoundedSemaphore',
29
+ 'Cache',
30
+ 'DEFAULT_SETTINGS',
31
+ 'Deque',
32
+ 'Disk',
33
+ 'ENOVAL',
34
+ 'EVICTION_POLICY',
35
+ 'EmptyDirWarning',
36
+ 'FanoutCache',
37
+ 'Index',
38
+ 'JSONDisk',
39
+ 'Lock',
40
+ 'RLock',
41
+ 'ReadOnlyError',
42
+ 'SafeDisk',
43
+ 'Timeout',
44
+ 'UNKNOWN',
45
+ 'UnknownFileWarning',
46
+ 'barrier',
47
+ 'configure',
48
+ 'default_disk',
49
+ 'memoize_stampede',
50
+ 'throttle',
51
+ ]
52
+
53
+ __title__: str
54
+ __version__: str
55
+ __build__: int
56
+ __author__: str
57
+ __license__: str
58
+ __copyright__: str
@@ -0,0 +1,227 @@
1
+ import warnings
2
+ from typing import (
3
+ Any,
4
+ Callable,
5
+ Container,
6
+ ContextManager,
7
+ Iterator,
8
+ Literal,
9
+ Protocol,
10
+ overload,
11
+ )
12
+
13
+ from _typeshed import Incomplete
14
+ from typing_extensions import ParamSpec, Self, TypeAlias, TypedDict, TypeVar
15
+
16
+ from diskcache_community import Disk
17
+
18
+ _T = TypeVar('_T')
19
+ _IntOrStrT = TypeVar('_IntOrStrT', bound=int | str)
20
+ _T_co = TypeVar('_T_co', covariant=True)
21
+ _P = ParamSpec('_P')
22
+
23
+ DbName: TypeAlias = Literal['cache.db']
24
+ ModeNone: TypeAlias = Literal[0]
25
+ ModeRaw: TypeAlias = Literal[1]
26
+ ModeBinary: TypeAlias = Literal[2]
27
+ ModeText: TypeAlias = Literal[3]
28
+ ModePickle: TypeAlias = Literal[4]
29
+ ModeLiteral: TypeAlias = (
30
+ ModeNone | ModeRaw | ModeBinary | ModeText | ModePickle
31
+ )
32
+ EnovalType: TypeAlias = Literal['ENOVAL']
33
+ UnknownType: TypeAlias = Literal['UNKNOWN']
34
+
35
+ ExpireTime: TypeAlias = float | None
36
+ Tag: TypeAlias = str | None
37
+ Ignore: TypeAlias = Container[int | str]
38
+
39
+ ServerSide: TypeAlias = Literal['back', 'front']
40
+ KeyValuePair: TypeAlias = tuple[_IntOrStrT, Any]
41
+ NullPair: TypeAlias = tuple[None, None]
42
+ NullablePair: TypeAlias = KeyValuePair[_IntOrStrT] | NullPair
43
+
44
+ EvictionPolicyKey: TypeAlias = Literal[
45
+ 'none',
46
+ 'least-recently-stored',
47
+ 'least-recently-used',
48
+ 'least-frequently-used',
49
+ ]
50
+ EvictionPolicyItemKey: TypeAlias = Literal['init', 'get', 'cull']
51
+ EvictionPolicyItem: TypeAlias = dict[EvictionPolicyItemKey, str | None]
52
+
53
+ class Memoized(Protocol[_P, _T_co]):
54
+ def __cache_key__(
55
+ self, *args: _P.args, **kwargs: _P.kwargs
56
+ ) -> tuple[Any, ...]: ...
57
+ def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T_co: ...
58
+
59
+ class Settings(TypedDict, total=False):
60
+ statistics: int
61
+ tag_index: int
62
+ eviction_policy: str
63
+ size_limit: int
64
+ cull_limit: int
65
+ sqlite_auto_vacuum: int
66
+ sqlite_cache_size: int
67
+ sqlite_journal_mode: str
68
+ sqlite_mmap_size: int
69
+ sqlite_synchronous: int
70
+ disk_min_file_size: int
71
+ disk_pickle_protocol: int
72
+
73
+ class DefaultSettings(TypedDict, total=True):
74
+ statistics: int
75
+ tag_index: int
76
+ eviction_policy: str
77
+ size_limit: int
78
+ cull_limit: int
79
+ sqlite_auto_vacuum: int
80
+ sqlite_cache_size: int
81
+ sqlite_journal_mode: str
82
+ sqlite_mmap_size: int
83
+ sqlite_synchronous: int
84
+ disk_min_file_size: int
85
+ disk_pickle_protocol: int
86
+
87
+ class Metadata(TypedDict, total=False):
88
+ count: int
89
+ size: int
90
+ hits: int
91
+ misses: int
92
+
93
+ class DefaultMetadata(TypedDict, total=True):
94
+ count: int
95
+ size: int
96
+ hits: int
97
+ misses: int
98
+
99
+ class InitSettings(TypedDict, total=False):
100
+ # settings
101
+ statistics: int
102
+ tag_index: int
103
+ eviction_policy: str
104
+ size_limit: int
105
+ cull_limit: int
106
+ sqlite_auto_vacuum: int
107
+ sqlite_cache_size: int
108
+ sqlite_journal_mode: str
109
+ sqlite_mmap_size: int
110
+ sqlite_synchronous: int
111
+ disk_min_file_size: int
112
+ disk_pickle_protocol: int
113
+ # metadata
114
+ count: int
115
+ size: int
116
+ hits: int
117
+ misses: int
118
+
119
+ class BaseCache(Protocol):
120
+ ### Settings
121
+ @property
122
+ def statistics(self) -> int: ...
123
+ @property
124
+ def tag_index(self) -> int: ...
125
+ @property
126
+ def eviction_policy(self) -> str: ...
127
+ @property
128
+ def size_limit(self) -> int: ...
129
+ @property
130
+ def cull_limit(self) -> int: ...
131
+ @property
132
+ def sqlite_auto_vacuum(self) -> int: ...
133
+ @property
134
+ def sqlite_cache_size(self) -> int: ...
135
+ @property
136
+ def sqlite_journal_mode(self) -> str: ...
137
+ @property
138
+ def sqlite_mmap_size(self) -> int: ...
139
+ @property
140
+ def sqlite_synchronous(self) -> int: ...
141
+ @property
142
+ def disk_min_file_size(self) -> int: ...
143
+ @property
144
+ def disk_pickle_protocol(self) -> int: ...
145
+ ###
146
+ @property
147
+ def directory(self) -> str: ...
148
+ @property
149
+ def timeout(self) -> int: ...
150
+ @property
151
+ def disk(self) -> Disk: ...
152
+ def transact(self, retry: bool = ...) -> ContextManager[None]: ...
153
+ def set( # noqa: PLR0913
154
+ self,
155
+ key: Any,
156
+ value: Any,
157
+ expire: ExpireTime = ...,
158
+ read: bool = ...,
159
+ tag: Tag = ...,
160
+ retry: bool = ...,
161
+ ) -> Literal[True]: ...
162
+ def __setitem__(self, key: Any, value: Any) -> None: ...
163
+ def touch(
164
+ self, key: Any, expire: ExpireTime = ..., retry: bool = ...
165
+ ) -> bool: ...
166
+ def add( # noqa: PLR0913
167
+ self,
168
+ key: Any,
169
+ value: Any,
170
+ expire: ExpireTime = ...,
171
+ read: bool = ...,
172
+ tag: Tag = ...,
173
+ retry: bool = ...,
174
+ ) -> bool: ...
175
+ def incr(
176
+ self, key: Any, delta: int = ..., default: int = ..., retry: bool = ...
177
+ ) -> int: ...
178
+ def decr(
179
+ self, key: Any, delta: int = ..., default: int = ..., retry: bool = ...
180
+ ) -> int: ...
181
+ def get( # noqa: PLR0913
182
+ self,
183
+ key: Any,
184
+ default: Any = ...,
185
+ read: bool = ...,
186
+ expire_time: bool = ...,
187
+ tag: bool = ...,
188
+ retry: bool = ...,
189
+ store_time: bool = ...,
190
+ ) -> Incomplete: ...
191
+ def __getitem__(self, key: Any) -> Any: ...
192
+ def __contains__(self, key: Any) -> bool: ...
193
+ def pop(
194
+ self,
195
+ key: Any,
196
+ default: Any = ...,
197
+ expire_time: bool = ...,
198
+ tag: bool = ...,
199
+ retry: bool = ...,
200
+ ) -> Incomplete: ...
201
+ def delete(self, key: Any, retry: bool = ...) -> bool: ...
202
+ def create_tag_index(self) -> None: ...
203
+ def drop_tag_index(self) -> None: ...
204
+ def check(
205
+ self, fix: bool = ..., retry: bool = ...
206
+ ) -> list[warnings.WarningMessage]: ...
207
+ def evict(self, tag: str, retry: bool = ...) -> int: ...
208
+ def cull(self, retry: bool = ...) -> int: ...
209
+ def clear(self, retry: bool = ...) -> int: ...
210
+ def __iter__(self) -> Iterator[Any]: ...
211
+ def __reversed__(self) -> Iterator[Any]: ...
212
+ def stats(
213
+ self, enable: bool = ..., reset: bool = ...
214
+ ) -> tuple[Any, Any]: ...
215
+ def volume(self) -> int: ...
216
+ def close(self) -> None: ...
217
+ def __enter__(self) -> Self: ...
218
+ def __exit__(self, *exception: object) -> None: ...
219
+ def __len__(self) -> int: ...
220
+ def memoize(
221
+ self,
222
+ name: str | None = ...,
223
+ typed: bool = ...,
224
+ expire: ExpireTime = ...,
225
+ tag: Tag = ...,
226
+ ignore: Ignore = ...,
227
+ ) -> Callable[[Callable[_P, _T]], Memoized[_P, _T]]: ...
@@ -0,0 +1,327 @@
1
+ import pickle
2
+ import sqlite3
3
+ from typing import (
4
+ IO,
5
+ Any,
6
+ BinaryIO,
7
+ Callable,
8
+ Final,
9
+ Generator,
10
+ Generic,
11
+ Literal,
12
+ overload,
13
+ )
14
+
15
+ from _typeshed import StrOrBytesPath
16
+ from typing_extensions import Self, TypeVar, Unpack
17
+
18
+ from ._types import (
19
+ BaseCache,
20
+ DbName,
21
+ DefaultMetadata,
22
+ DefaultSettings,
23
+ EnovalType,
24
+ EvictionPolicyItem,
25
+ EvictionPolicyKey,
26
+ ExpireTime,
27
+ Ignore,
28
+ InitSettings,
29
+ KeyValuePair,
30
+ ModeBinary,
31
+ ModeLiteral,
32
+ ModeNone,
33
+ ModePickle,
34
+ ModeRaw,
35
+ ModeText,
36
+ NullablePair,
37
+ ServerSide,
38
+ Tag,
39
+ UnknownType,
40
+ )
41
+
42
+ _T = TypeVar('_T')
43
+ _BoundStrT = TypeVar('_BoundStrT', bound=str)
44
+ _PutT1 = TypeVar('_PutT1', bound=str | int | float)
45
+ _PutT2 = TypeVar('_PutT2', bound=int | float)
46
+
47
+ def full_name(func: Callable[..., Any]) -> str: ...
48
+ def native_filename(filename: str) -> str: ...
49
+
50
+ class Constant(tuple[_BoundStrT], Generic[_BoundStrT]): # noqa: SLOT001
51
+ def __new__(cls, name: _BoundStrT) -> Self: ...
52
+
53
+ DBNAME: Final[DbName]
54
+ ENOVAL: Final[Constant[EnovalType]]
55
+ UNKNOWN: Final[Constant[UnknownType]]
56
+ MODE_NONE: Final[ModeNone]
57
+ MODE_RAW: Final[ModeRaw]
58
+ MODE_BINARY: Final[ModeBinary]
59
+ MODE_TEXT: Final[ModeText]
60
+ MODE_PICKLE: Final[ModePickle]
61
+ DEFAULT_SETTINGS: Final[DefaultSettings]
62
+ METADATA: Final[DefaultMetadata]
63
+ EVICTION_POLICY: Final[dict[EvictionPolicyKey, EvictionPolicyItem]]
64
+ SETTINGS_TRIGGERS: Final[tuple[tuple[str, str], ...]]
65
+ SAFE_TYPES: Final[frozenset[type]]
66
+ SAFE_PICKLE_NAMES: Final[dict[str, frozenset[str]]]
67
+ UNSAFE_MODULES: Final[tuple[str, ...]]
68
+ ENV_DISK: Final[str]
69
+ ENV_SAFE_TYPES: Final[str]
70
+ ENV_SAFE_MODULES: Final[str]
71
+
72
+ class Disk:
73
+ min_file_size: int
74
+ pickle_protocol: int
75
+ on_error: Literal['raise', 'miss']
76
+ @classmethod
77
+ def with_options(
78
+ cls, *, on_error: Literal['raise', 'miss']
79
+ ) -> type[Self]: ...
80
+ def __init__(
81
+ self,
82
+ directory: StrOrBytesPath,
83
+ min_file_size: int = ...,
84
+ pickle_protocol: int = ...,
85
+ ) -> None: ...
86
+ def hash(self, key: Any) -> int: ...
87
+ @overload
88
+ def put(self, key: bytes) -> tuple[sqlite3.Binary, Literal[True]]: ...
89
+ @overload
90
+ def put(self, key: _PutT1) -> tuple[_PutT1, Literal[True]]: ...
91
+ @overload
92
+ def put(self, key: Any) -> tuple[sqlite3.Binary, Literal[False]]: ...
93
+ @overload
94
+ def get(self, key: sqlite3.Binary, raw: Literal[True]) -> bytes: ...
95
+ @overload
96
+ def get(self, key: _T, raw: Literal[True]) -> bytes | _T: ...
97
+ @overload
98
+ def get(self, key: Any, raw: Literal[False]) -> Any: ...
99
+ @overload
100
+ def get(self, key: Any, raw: bool) -> Any: ...
101
+ @overload
102
+ def store(
103
+ self, value: _PutT2, read: bool, key: Any = ...
104
+ ) -> tuple[Literal[0], ModeRaw, None, _PutT2]: ...
105
+ @overload
106
+ def store(
107
+ self, value: bytes, read: bool, key: Any = ...
108
+ ) -> (
109
+ tuple[Literal[0], ModeRaw, None, sqlite3.Binary]
110
+ | tuple[int, ModeBinary, str, None]
111
+ ): ...
112
+ @overload
113
+ def store(
114
+ self, value: str, read: bool, key: Any = ...
115
+ ) -> tuple[Literal[0], ModeRaw, None, str] | tuple[
116
+ int, ModeText, str, None
117
+ ]: ...
118
+ @overload
119
+ def store(
120
+ self, value: Any, read: Literal[True], key: Any = ...
121
+ ) -> tuple[int, ModeBinary, str, None]: ...
122
+ @overload
123
+ def store(
124
+ self, value: Any, read: bool, key: Any = ...
125
+ ) -> (
126
+ tuple[Literal[0], ModePickle, None, sqlite3.Binary]
127
+ | tuple[int, ModePickle, str, None]
128
+ ): ...
129
+ @overload
130
+ def fetch(
131
+ self, mode: ModeRaw, filename: str, value: sqlite3.Binary, read: bool
132
+ ) -> bytes: ...
133
+ @overload
134
+ def fetch(
135
+ self, mode: ModeRaw, filename: str, value: _T, read: bool
136
+ ) -> _T: ...
137
+ @overload
138
+ def fetch(
139
+ self, mode: ModeBinary, filename: str, value: Any, read: Literal[True]
140
+ ) -> BinaryIO: ...
141
+ @overload
142
+ def fetch(
143
+ self, mode: ModeBinary, filename: str, value: Any, read: Literal[False]
144
+ ) -> BinaryIO: ...
145
+ @overload
146
+ def fetch(
147
+ self, mode: ModeBinary, filename: str, value: Any, read: bool
148
+ ) -> BinaryIO | bytes: ...
149
+ @overload
150
+ def fetch(
151
+ self, mode: ModeText, filename: str, value: Any, read: bool
152
+ ) -> str: ...
153
+ @overload
154
+ def fetch(
155
+ self, mode: ModePickle, filename: str, value: Any, read: bool
156
+ ) -> Any: ...
157
+ @overload
158
+ def fetch(
159
+ self, mode: ModeLiteral, filename: str, value: Any, read: bool
160
+ ) -> Any: ...
161
+ def filename(
162
+ self, key: Any = ..., value: Any = ...
163
+ ) -> tuple[str, str]: ...
164
+ def remove(self, file_path: StrOrBytesPath) -> None: ...
165
+
166
+ class JSONDisk(Disk):
167
+ compress_level: int
168
+ def __init__(
169
+ self,
170
+ directory: StrOrBytesPath,
171
+ compress_level: int = ...,
172
+ *,
173
+ # Disk init args
174
+ min_file_size: int = ...,
175
+ pickle_protocol: int = ...,
176
+ ) -> None: ...
177
+
178
+ class SafeUnpickler(pickle.Unpickler):
179
+ def __init__(
180
+ self,
181
+ file: IO[bytes],
182
+ names: dict[str, frozenset[str]] | None = ...,
183
+ classes: tuple[type, ...] = ...,
184
+ modules: tuple[str, ...] = ...,
185
+ ) -> None: ...
186
+ def find_class(self, module: str, name: str) -> Any: ...
187
+
188
+ class SafeDisk(Disk):
189
+ safe_types: frozenset[type]
190
+ safe_modules: tuple[str, ...]
191
+ @classmethod
192
+ def with_types(
193
+ cls, *types: type, modules: tuple[str, ...] = ...
194
+ ) -> type[Self]: ...
195
+
196
+ def configure(disk: type[Disk] | None) -> None: ...
197
+ def default_disk() -> type[Disk]: ...
198
+
199
+ class Timeout(Exception): ... # noqa: N818
200
+ class ReadOnlyError(sqlite3.OperationalError): ...
201
+ class UnknownFileWarning(UserWarning): ...
202
+ class EmptyDirWarning(UserWarning): ...
203
+
204
+ def args_to_key(
205
+ base: tuple[Any, ...],
206
+ args: tuple[Any, ...],
207
+ kwargs: dict[str, Any],
208
+ typed: bool,
209
+ ignore: Ignore,
210
+ ) -> tuple[Any, ...]: ...
211
+ def resolve_ignore(func: Callable[..., Any], ignore: Ignore) -> Ignore: ...
212
+
213
+ class Cache(BaseCache):
214
+ @overload
215
+ def __init__(
216
+ self,
217
+ directory: StrOrBytesPath | None = ...,
218
+ timeout: int = ...,
219
+ disk: type[Disk] | None = ...,
220
+ *,
221
+ read_only: bool = ...,
222
+ **settings: Unpack[InitSettings],
223
+ ) -> None: ...
224
+ @overload
225
+ def __init__(
226
+ self,
227
+ directory: StrOrBytesPath | None = ...,
228
+ timeout: int = ...,
229
+ disk: type[Disk] | None = ...,
230
+ *,
231
+ read_only: bool = ...,
232
+ # FIXME
233
+ # https://peps.python.org/pep-0728/
234
+ # diskcache allow "disk_*" args
235
+ **settings: Any,
236
+ ) -> None: ...
237
+ @property
238
+ def read_only(self) -> bool: ...
239
+ @property
240
+ def _con(self) -> sqlite3.Connection: ...
241
+ @property
242
+ def _sql(self) -> Callable[..., sqlite3.Cursor]: ...
243
+ def __delitem__(self, key: Any, retry: bool = ...) -> Literal[True]: ...
244
+ @overload
245
+ def reset(self, key: str, value: _T, update: bool = ...) -> _T: ...
246
+ @overload
247
+ def reset(self, key: str, value: Any = ..., update: bool = ...) -> Any: ...
248
+ def read(self, key: Any, retry: bool = ...) -> Any: ...
249
+ @overload
250
+ def push(
251
+ self,
252
+ value: Any,
253
+ prefix: None = ...,
254
+ side: ServerSide = ...,
255
+ expire: ExpireTime = ...,
256
+ read: bool = ...,
257
+ tag: Tag = ...,
258
+ retry: bool = ...,
259
+ ) -> int: ...
260
+ @overload
261
+ def push(
262
+ self,
263
+ value: Any,
264
+ prefix: str = ...,
265
+ side: ServerSide = ...,
266
+ expire: ExpireTime = ...,
267
+ read: bool = ...,
268
+ tag: Tag = ...,
269
+ retry: bool = ...,
270
+ ) -> str: ...
271
+ @overload
272
+ def push(
273
+ self,
274
+ value: Any,
275
+ prefix: str | None = ...,
276
+ side: ServerSide = ...,
277
+ expire: ExpireTime = ...,
278
+ read: bool = ...,
279
+ tag: Tag = ...,
280
+ retry: bool = ...,
281
+ ) -> str | int: ...
282
+ def pull( # noqa: PLR0913
283
+ self,
284
+ prefix: str | None = ...,
285
+ default: Any = ...,
286
+ side: ServerSide = ...,
287
+ expire_time: bool = ...,
288
+ tag: bool = ...,
289
+ retry: bool = ...,
290
+ ) -> (
291
+ NullablePair[Any]
292
+ | tuple[NullablePair[Any], Tag]
293
+ | tuple[NullablePair[Any], ExpireTime]
294
+ | tuple[NullablePair[Any], ExpireTime, Tag]
295
+ ): ...
296
+ def peek( # noqa: PLR0913
297
+ self,
298
+ prefix: str | None = ...,
299
+ default: Any = ...,
300
+ side: ServerSide = ...,
301
+ expire_time: bool = ...,
302
+ tag: bool = ...,
303
+ retry: bool = ...,
304
+ ) -> (
305
+ NullablePair[Any]
306
+ | tuple[NullablePair[Any], Tag]
307
+ | tuple[NullablePair[Any], ExpireTime]
308
+ | tuple[NullablePair[Any], ExpireTime, Tag]
309
+ ): ...
310
+ def peekitem(
311
+ self,
312
+ last: bool = ...,
313
+ expire_time: bool = ...,
314
+ tag: bool = ...,
315
+ retry: bool = ...,
316
+ ) -> (
317
+ KeyValuePair[Any]
318
+ | tuple[KeyValuePair[Any], Tag]
319
+ | tuple[KeyValuePair[Any], ExpireTime]
320
+ | tuple[KeyValuePair[Any], ExpireTime, Tag]
321
+ ): ...
322
+ def expire(self, now: ExpireTime = ..., retry: bool = ...) -> int: ...
323
+ def iterkeys(
324
+ self, reverse: bool = ..., tag: Tag | Constant[EnovalType] = ...
325
+ ) -> Generator[Any, None, None]: ...
326
+ def __getstate__(self) -> tuple[str, int, type[Disk]]: ...
327
+ def __setstate__(self, state: tuple[str, int, type[Disk]]) -> None: ...
@@ -0,0 +1,101 @@
1
+ # pyright: basic
2
+ # ruff: noqa
3
+ # mypy: ignore-errors
4
+ from _typeshed import Incomplete
5
+ from django.core.cache.backends.base import ( # pyright: ignore[reportMissingImports]
6
+ BaseCache,
7
+ )
8
+
9
+ class DjangoCache(BaseCache):
10
+ def __init__(self, directory, params) -> None: ...
11
+ @property
12
+ def directory(self): ...
13
+ def cache(self, name): ...
14
+ def deque(self, name, maxlen: Incomplete | None = None): ...
15
+ def index(self, name): ...
16
+ def add(
17
+ self,
18
+ key,
19
+ value,
20
+ timeout=...,
21
+ version: Incomplete | None = None,
22
+ read: bool = False,
23
+ tag: Incomplete | None = None,
24
+ retry: bool = True,
25
+ ): ...
26
+ def get(
27
+ self,
28
+ key,
29
+ default: Incomplete | None = None,
30
+ version: Incomplete | None = None,
31
+ read: bool = False,
32
+ expire_time: bool = False,
33
+ tag: bool = False,
34
+ retry: bool = False,
35
+ store_time: bool = False,
36
+ ): ...
37
+ def read(self, key, version: Incomplete | None = None): ...
38
+ def set(
39
+ self,
40
+ key,
41
+ value,
42
+ timeout=...,
43
+ version: Incomplete | None = None,
44
+ read: bool = False,
45
+ tag: Incomplete | None = None,
46
+ retry: bool = True,
47
+ ): ...
48
+ def touch(
49
+ self,
50
+ key,
51
+ timeout=...,
52
+ version: Incomplete | None = None,
53
+ retry: bool = True,
54
+ ): ...
55
+ def pop(
56
+ self,
57
+ key,
58
+ default: Incomplete | None = None,
59
+ version: Incomplete | None = None,
60
+ expire_time: bool = False,
61
+ tag: bool = False,
62
+ retry: bool = True,
63
+ ): ...
64
+ def delete(
65
+ self, key, version: Incomplete | None = None, retry: bool = True
66
+ ): ...
67
+ def incr(
68
+ self,
69
+ key,
70
+ delta: int = 1,
71
+ version: Incomplete | None = None,
72
+ default: Incomplete | None = None,
73
+ retry: bool = True,
74
+ ): ...
75
+ def decr(
76
+ self,
77
+ key,
78
+ delta: int = 1,
79
+ version: Incomplete | None = None,
80
+ default: Incomplete | None = None,
81
+ retry: bool = True,
82
+ ): ...
83
+ def has_key(self, key, version: Incomplete | None = None): ...
84
+ def expire(self): ...
85
+ def stats(self, enable: bool = True, reset: bool = False): ...
86
+ def create_tag_index(self) -> None: ...
87
+ def drop_tag_index(self) -> None: ...
88
+ def evict(self, tag): ...
89
+ def cull(self): ...
90
+ def clear(self): ...
91
+ def close(self, **kwargs) -> None: ...
92
+ def get_backend_timeout(self, timeout=...): ...
93
+ def memoize(
94
+ self,
95
+ name: Incomplete | None = None,
96
+ timeout=...,
97
+ version: Incomplete | None = None,
98
+ typed: bool = False,
99
+ tag: Incomplete | None = None,
100
+ ignore=(),
101
+ ): ...
@@ -0,0 +1,70 @@
1
+ from typing import Any, overload
2
+
3
+ from _typeshed import StrOrBytesPath
4
+ from typing_extensions import Unpack
5
+
6
+ from diskcache_community.core import DEFAULT_SETTINGS as DEFAULT_SETTINGS
7
+ from diskcache_community.core import ENOVAL as ENOVAL
8
+ from diskcache_community.core import Cache as Cache
9
+ from diskcache_community.core import Disk as Disk
10
+ from diskcache_community.core import Timeout as Timeout
11
+ from diskcache_community.persistent import Deque as Deque
12
+ from diskcache_community.persistent import Index as Index
13
+
14
+ from ._types import BaseCache, InitSettings
15
+
16
+ class FanoutCache(BaseCache):
17
+ @overload
18
+ def __init__(
19
+ self,
20
+ directory: StrOrBytesPath | None = ...,
21
+ shards: int = ...,
22
+ timeout: float = ...,
23
+ disk: type[Disk] | None = ...,
24
+ **settings: Unpack[InitSettings],
25
+ ) -> None: ...
26
+ @overload
27
+ def __init__(
28
+ self,
29
+ directory: StrOrBytesPath | None = ...,
30
+ shards: int = ...,
31
+ timeout: float = ...,
32
+ disk: type[Disk] | None = ...,
33
+ # FIXME
34
+ # https://peps.python.org/pep-0728/
35
+ # diskcache allow "disk_*" args
36
+ **settings: Any,
37
+ ) -> None: ...
38
+ def __getattr__(self, name: str) -> Any: ...
39
+ def read(self, key: Any) -> Any: ...
40
+ def expire(self, retry: bool = ...) -> int: ...
41
+ @overload
42
+ def cache(
43
+ self,
44
+ name: str,
45
+ timeout: int = ...,
46
+ disk: type[Disk] | None = ...,
47
+ **settings: Unpack[InitSettings],
48
+ ) -> Cache: ...
49
+ @overload
50
+ def cache(
51
+ self,
52
+ name: str,
53
+ timeout: int = ...,
54
+ disk: type[Disk] | None = ...,
55
+ # FIXME
56
+ # https://peps.python.org/pep-0728/
57
+ # diskcache allow "disk_*" args
58
+ **settings: Any,
59
+ ) -> Cache: ...
60
+ def deque(
61
+ self,
62
+ name: str,
63
+ maxlen: int | None = ...,
64
+ disk: type[Disk] | None = ...,
65
+ ) -> Deque[Any]: ...
66
+ def index(
67
+ self, name: str, disk: type[Disk] | None = ...
68
+ ) -> Index[Any, Any]: ...
69
+ def __delitem__(self, key: Any) -> None: ...
70
+ def reset(self, key: str, value: Any = ...) -> Any: ...
@@ -0,0 +1,161 @@
1
+ from collections.abc import MutableMapping, Sequence
2
+ from typing import (
3
+ Any,
4
+ Callable,
5
+ ContextManager,
6
+ Generic,
7
+ ItemsView,
8
+ Iterable,
9
+ Iterator,
10
+ KeysView,
11
+ ValuesView,
12
+ overload,
13
+ )
14
+
15
+ from _typeshed import StrOrBytesPath
16
+ from typing_extensions import ParamSpec, Self, TypeVar
17
+
18
+ from diskcache_community.core import Cache, Disk
19
+
20
+ from ._types import Ignore, KeyValuePair, Memoized, NullablePair, ServerSide
21
+
22
+ _AnyDefault: Iterable[Any] = ()
23
+ _AnyT = TypeVar('_AnyT', bound=Any)
24
+ _KeyT = TypeVar('_KeyT', bound=Any, default=Any)
25
+ _ValueT = TypeVar('_ValueT', bound=Any, default=Any)
26
+ _T = TypeVar('_T')
27
+ _P = ParamSpec('_P')
28
+
29
+ class Deque(Sequence[_ValueT], Generic[_ValueT]):
30
+ __hash__: None # type: ignore[assignment]
31
+ def __init__(
32
+ self,
33
+ iterable: Iterable[_ValueT] = _AnyDefault, # noqa: PYI011
34
+ directory: StrOrBytesPath | None = ...,
35
+ maxlen: int | None = ...,
36
+ disk: type[Disk] | None = ...,
37
+ ) -> None: ...
38
+ @overload
39
+ @classmethod
40
+ def fromcache(
41
+ cls, cache: Cache, iterable: Iterable[_AnyT], maxlen: int | None = ...
42
+ ) -> Deque[_AnyT]: ...
43
+ @overload
44
+ @classmethod
45
+ def fromcache(
46
+ cls,
47
+ cache: Cache,
48
+ iterable: Iterable[Any] = ...,
49
+ maxlen: int | None = ...,
50
+ ) -> Deque[Any]: ...
51
+ @property
52
+ def cache(self) -> Cache: ...
53
+ @property
54
+ def directory(self) -> str: ...
55
+ @property
56
+ def maxlen(self) -> int: ...
57
+ @maxlen.setter
58
+ def maxlen(self, value: int) -> None: ...
59
+ def __getitem__(self, index: int) -> Any: ... # type: ignore[override]
60
+ def __setitem__(self, index: int, value: Any) -> None: ...
61
+ def __delitem__(self, index: int) -> None: ...
62
+ def __eq__(self, value: object) -> bool: ...
63
+ def __ne__(self, value: object) -> bool: ...
64
+ def __lt__(self, value: object) -> bool: ...
65
+ def __gt__(self, value: object) -> bool: ...
66
+ def __le__(self, value: object) -> bool: ...
67
+ def __ge__(self, value: object) -> bool: ...
68
+ def __iadd__(self, iterable: Iterable[_ValueT]) -> Self: ...
69
+ def __iter__(self) -> Iterator[Any]: ...
70
+ def __len__(self) -> int: ...
71
+ def __reversed__(self) -> Iterator[Any]: ...
72
+ def __getstate__(self) -> tuple[str, int]: ...
73
+ def __setstate__(self, state: tuple[str, int]) -> None: ...
74
+ def append(self, value: _ValueT) -> None: ...
75
+ def appendleft(self, value: _ValueT) -> None: ...
76
+ def clear(self) -> None: ...
77
+ def copy(self) -> Self: ...
78
+ def count(self, value: _ValueT) -> int: ...
79
+ def extend(self, iterable: Iterable[_ValueT]) -> None: ...
80
+ def extendleft(self, iterable: Iterable[_ValueT]) -> None: ...
81
+ def peek(self) -> _ValueT: ...
82
+ def peekleft(self) -> _ValueT: ...
83
+ def pop(self) -> _ValueT: ...
84
+ def popleft(self) -> _ValueT: ...
85
+ def remove(self, value: _ValueT) -> _ValueT: ...
86
+ def reverse(self) -> None: ...
87
+ def rotate(self, steps: int = ...) -> None: ...
88
+ def transact(self) -> ContextManager[None]: ...
89
+
90
+ class Index(MutableMapping[_KeyT, _ValueT], Generic[_KeyT, _ValueT]):
91
+ __hash__: None # type: ignore[assignment]
92
+ def __init__(
93
+ self, *args: Any, disk: type[Disk] | None = ..., **kwargs: Any
94
+ ) -> None: ...
95
+ @classmethod
96
+ def fromcache(
97
+ cls, cache: Cache, *args: Any, **kwargs: Any
98
+ ) -> Index[Any, Any]: ...
99
+ @property
100
+ def cache(self) -> Cache: ...
101
+ @property
102
+ def directory(self) -> str: ...
103
+ def __getitem__(self, key: _KeyT) -> _ValueT: ...
104
+ def __setitem__(self, key: _KeyT, value: _ValueT) -> None: ...
105
+ def __delitem__(self, key: _KeyT) -> None: ...
106
+ @overload
107
+ def setdefault(
108
+ self, key: _KeyT, default: _ValueT | None = ...
109
+ ) -> _ValueT: ...
110
+ @overload
111
+ def setdefault(self, key: _KeyT, default: Any = ...) -> Any: ...
112
+ def peekitem(self, last: bool = ...) -> KeyValuePair[Any]: ...
113
+ @overload
114
+ def pop(self, key: _KeyT, default: _ValueT = ...) -> _ValueT: ...
115
+ @overload
116
+ def pop(
117
+ self, key: _KeyT, default: Any = ...
118
+ ) -> Any: ... # pyright: ignore[reportIncompatibleMethodOverride]
119
+ def popitem(self, last: bool = True) -> KeyValuePair[Any]: ...
120
+ @overload
121
+ def push(
122
+ self, value: _ValueT, prefix: None = ..., side: ServerSide = ...
123
+ ) -> int: ...
124
+ @overload
125
+ def push(
126
+ self, value: _ValueT, prefix: str = ..., side: ServerSide = ...
127
+ ) -> str: ...
128
+ @overload
129
+ def push(
130
+ self, value: _ValueT, prefix: str | None = ..., side: ServerSide = ...
131
+ ) -> str | int: ...
132
+ @overload
133
+ def pull(
134
+ self, prefix: None = ..., default: Any = ..., side: ServerSide = ...
135
+ ) -> NullablePair[int]: ...
136
+ @overload
137
+ def pull(
138
+ self, prefix: str = ..., default: Any = ..., side: ServerSide = ...
139
+ ) -> NullablePair[str]: ...
140
+ @overload
141
+ def pull(
142
+ self,
143
+ prefix: str | None = ...,
144
+ default: Any = ...,
145
+ side: ServerSide = ...,
146
+ ) -> NullablePair[Any]: ...
147
+ def clear(self) -> None: ...
148
+ def __iter__(self) -> Iterator[Any]: ...
149
+ def __reversed__(self) -> Iterator[Any]: ...
150
+ def __len__(self) -> int: ...
151
+ def keys(self) -> KeysView[_KeyT]: ...
152
+ def values(self) -> ValuesView[_ValueT]: ...
153
+ def items(self) -> ItemsView[_KeyT, _ValueT]: ...
154
+ def __getstate__(self) -> str: ...
155
+ def __setstate__(self, state: str) -> None: ...
156
+ def __eq__(self, other: object) -> bool: ...
157
+ def __ne__(self, other: object) -> bool: ...
158
+ def memoize(
159
+ self, name: str | None = ..., typed: bool = ..., ignore: Ignore = ...
160
+ ) -> Callable[[Callable[_P, _T]], Memoized[_P, _T]]: ...
161
+ def transact(self) -> ContextManager[None]: ...
File without changes
@@ -0,0 +1,102 @@
1
+ from typing import Any, Callable, Protocol
2
+
3
+ from typing_extensions import ParamSpec, TypeVar, override
4
+
5
+ from ._types import BaseCache, ExpireTime, Ignore, Tag
6
+
7
+ _T = TypeVar('_T')
8
+ _P = ParamSpec('_P')
9
+
10
+ class Averager:
11
+ def __init__(
12
+ self,
13
+ cache: BaseCache,
14
+ key: Any,
15
+ expire: ExpireTime = ...,
16
+ tag: Tag = ...,
17
+ ) -> None: ...
18
+ def add(self, value: float) -> None: ...
19
+ def get(self) -> float | None: ...
20
+ def pop(self) -> float | None: ...
21
+
22
+ class _Lock(Protocol):
23
+ def acquire(self) -> Any: ...
24
+ def release(self) -> Any: ...
25
+ def __enter__(self) -> Any: ...
26
+ def __exit__(self, *exc_info: object) -> Any: ...
27
+
28
+ class Lock(_Lock):
29
+ def __init__(
30
+ self,
31
+ cache: BaseCache,
32
+ key: Any,
33
+ expire: ExpireTime = ...,
34
+ tag: Tag = ...,
35
+ ) -> None: ...
36
+ def locked(self) -> bool: ...
37
+ @override
38
+ def acquire(self) -> None: ...
39
+ @override
40
+ def release(self) -> None: ...
41
+ @override
42
+ def __enter__(self) -> None: ...
43
+ @override
44
+ def __exit__(self, *exc_info: object) -> None: ...
45
+
46
+ class RLock(_Lock):
47
+ def __init__(
48
+ self,
49
+ cache: BaseCache,
50
+ key: Any,
51
+ expire: ExpireTime = ...,
52
+ tag: Tag = ...,
53
+ ) -> None: ...
54
+ @override
55
+ def acquire(self) -> None: ...
56
+ @override
57
+ def release(self) -> None: ...
58
+ @override
59
+ def __enter__(self) -> None: ...
60
+ @override
61
+ def __exit__(self, *exc_info: object) -> None: ...
62
+
63
+ class BoundedSemaphore:
64
+ def __init__(
65
+ self,
66
+ cache: BaseCache,
67
+ key: Any,
68
+ value: int = ...,
69
+ expire: ExpireTime = ...,
70
+ tag: Tag = ...,
71
+ ) -> None: ...
72
+ def acquire(self) -> None: ...
73
+ def release(self) -> None: ...
74
+ def __enter__(self) -> None: ...
75
+ def __exit__(self, *exc_info: object) -> None: ...
76
+
77
+ def throttle( # noqa: PLR0913
78
+ cache: BaseCache,
79
+ count: int,
80
+ seconds: float,
81
+ name: str | None = ...,
82
+ expire: ExpireTime = ...,
83
+ tag: Tag = ...,
84
+ time_func: Callable[[], float] = ...,
85
+ sleep_func: Callable[[float], Any] = ...,
86
+ ) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ...
87
+ def barrier(
88
+ cache: BaseCache,
89
+ lock_factory: Callable[[BaseCache, Any, ExpireTime, Tag], _Lock],
90
+ name: str | None = ...,
91
+ expire: ExpireTime = ...,
92
+ tag: Tag = ...,
93
+ ) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ...
94
+ def memoize_stampede( # noqa: PLR0913
95
+ cache: BaseCache,
96
+ expire: float,
97
+ name: str | None = ...,
98
+ typed: bool = ...,
99
+ tag: Tag = ...,
100
+ beta: float = ...,
101
+ ignore: Ignore = ...,
102
+ ) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diskcache-community
3
- Version: 5.8.0
3
+ Version: 5.8.1
4
4
  Summary: Disk Cache -- Disk and file backed persistent cache.
5
5
  Author: Grant Jenks
6
6
  Maintainer: diskcache-community contributors
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3.13
23
23
  Classifier: Programming Language :: Python :: 3.14
24
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
- Requires-Python: >=3.10
25
+ Requires-Python: >=3.9
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  License-File: NOTICE
@@ -3,12 +3,20 @@ NOTICE
3
3
  README.md
4
4
  pyproject.toml
5
5
  diskcache_community/__init__.py
6
+ diskcache_community/__init__.pyi
7
+ diskcache_community/_types.pyi
6
8
  diskcache_community/cli.py
7
9
  diskcache_community/core.py
10
+ diskcache_community/core.pyi
8
11
  diskcache_community/djangocache.py
12
+ diskcache_community/djangocache.pyi
9
13
  diskcache_community/fanout.py
14
+ diskcache_community/fanout.pyi
10
15
  diskcache_community/persistent.py
16
+ diskcache_community/persistent.pyi
17
+ diskcache_community/py.typed
11
18
  diskcache_community/recipes.py
19
+ diskcache_community/recipes.pyi
12
20
  diskcache_community.egg-info/PKG-INFO
13
21
  diskcache_community.egg-info/SOURCES.txt
14
22
  diskcache_community.egg-info/dependency_links.txt
@@ -7,7 +7,7 @@ name = "diskcache-community"
7
7
  dynamic = ["version"]
8
8
  description = "Disk Cache -- Disk and file backed persistent cache."
9
9
  readme = "README.md"
10
- requires-python = ">=3.10"
10
+ requires-python = ">=3.9"
11
11
  license = "Apache-2.0"
12
12
  license-files = ["LICENSE", "NOTICE"]
13
13
  authors = [{ name = "Grant Jenks" }]