cachetools 7.1.2__tar.gz → 7.1.3__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.
- cachetools-7.1.3/.github/FUNDING.yml +2 -0
- cachetools-7.1.3/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- cachetools-7.1.3/.github/ISSUE_TEMPLATE/config.yml +1 -0
- cachetools-7.1.3/.github/ISSUE_TEMPLATE/feature_request.md +10 -0
- cachetools-7.1.3/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- cachetools-7.1.3/.github/SECURITY.md +13 -0
- cachetools-7.1.3/.github/copilot-instructions.md +83 -0
- cachetools-7.1.3/.github/copilot-review.md +54 -0
- cachetools-7.1.3/.github/dependabot.yml +6 -0
- cachetools-7.1.3/.github/workflows/ci.yml +27 -0
- cachetools-7.1.3/.gitignore +12 -0
- cachetools-7.1.3/.readthedocs.yaml +11 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/CHANGELOG.rst +8 -0
- {cachetools-7.1.2/src/cachetools.egg-info → cachetools-7.1.3}/PKG-INFO +1 -1
- {cachetools-7.1.2 → cachetools-7.1.3}/pyproject.toml +1 -1
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/__init__.py +1 -4
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/func.pyi +20 -19
- {cachetools-7.1.2 → cachetools-7.1.3/src/cachetools.egg-info}/PKG-INFO +1 -1
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools.egg-info/SOURCES.txt +12 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tox.ini +5 -5
- {cachetools-7.1.2 → cachetools-7.1.3}/LICENSE +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/README.rst +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/docs/conf.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/docs/index.rst +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/setup.cfg +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/__init__.pyi +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/_cached.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/_cachedmethod.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/func.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/keys.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/keys.pyi +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools/py.typed +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools.egg-info/dependency_links.txt +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/src/cachetools.egg-info/top_level.txt +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/__init__.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_cache.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_cached.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_cachedmethod.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_classmethod.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_fifo.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_func.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_keys.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_lfu.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_lru.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_rr.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_threading.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_tlru.py +0 -0
- {cachetools-7.1.2 → cachetools-7.1.3}/tests/test_ttl.py +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: tkem
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Before reporting a bug, please make sure you have the latest `cachetools` version installed:
|
|
11
|
+
```
|
|
12
|
+
pip install --upgrade cachetools
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Describe the bug**
|
|
16
|
+
A clear and concise description of what the bug is.
|
|
17
|
+
|
|
18
|
+
**Expected result**
|
|
19
|
+
A clear and concise description of what you expected to happen.
|
|
20
|
+
|
|
21
|
+
**Actual result**
|
|
22
|
+
A clear and concise description of what happened instead.
|
|
23
|
+
|
|
24
|
+
**Reproduction steps**
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import cachetools
|
|
28
|
+
|
|
29
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Description
|
|
2
|
+
|
|
3
|
+
A clear and concise description of your changes.
|
|
4
|
+
|
|
5
|
+
## Motivation and Context
|
|
6
|
+
|
|
7
|
+
Why is this change required? What problem does it solve?
|
|
8
|
+
|
|
9
|
+
## Related Issue
|
|
10
|
+
|
|
11
|
+
Except for trivial changes like correcting typos, this project only
|
|
12
|
+
accepts pull requests related to open issues. If suggesting a new
|
|
13
|
+
feature or change, please discuss it in an issue first. If fixing a
|
|
14
|
+
bug, there should be an issue describing the bug, with steps to
|
|
15
|
+
reproduce.
|
|
16
|
+
|
|
17
|
+
Please link to the issue here: https://github.com/tkem/cachetools/issues/###
|
|
18
|
+
|
|
19
|
+
## Has this been tested and documented?
|
|
20
|
+
|
|
21
|
+
This project uses [tox](https://tox.wiki) for test automization.
|
|
22
|
+
Before submitting a pull request, run `tox` in the project's root and
|
|
23
|
+
make sure all tests are passing.
|
|
24
|
+
|
|
25
|
+
When adding new features or code not already covered by existing unit
|
|
26
|
+
tests, please also add some tests covering your changes under the
|
|
27
|
+
`tests` directory. For new features, please consider adding to the
|
|
28
|
+
existing documentation under the `docs` directory.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Security updates are applied only to the latest release.
|
|
6
|
+
|
|
7
|
+
## Reporting a Vulnerability
|
|
8
|
+
|
|
9
|
+
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
|
|
10
|
+
|
|
11
|
+
Please disclose it at [security advisory](https://github.com/tkem/cachetools/security/advisories/new).
|
|
12
|
+
|
|
13
|
+
This project is maintained by a single person on a best effort basis. As such, vulnerability reports will be investigated and fixed or disclosed as soon as possible, but there may be delays in response time due to the maintainer's other commitments.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Copilot Instructions for cachetools
|
|
2
|
+
|
|
3
|
+
## Architecture Overview
|
|
4
|
+
**cachetools** provides extensible memoizing collections and decorators, including variants of Python's `@lru_cache`. Pure Python 3.10+, no external runtime dependencies.
|
|
5
|
+
|
|
6
|
+
### Core Design Pattern
|
|
7
|
+
- All caches inherit from `Cache` (a `MutableMapping` with `maxsize`, `currsize`, and `getsizeof`)
|
|
8
|
+
- Subclasses override `__setitem__`, `__getitem__`, `__delitem__`, and `popitem()` to implement eviction policies
|
|
9
|
+
- **Critical:** Subclasses use default parameter trick (e.g., `cache_setitem=Cache.__setitem__`) to call parent methods efficiently while avoiding recursion
|
|
10
|
+
|
|
11
|
+
### Cache Types
|
|
12
|
+
- `FIFOCache`: Evicts oldest inserted (`OrderedDict`)
|
|
13
|
+
- `LRUCache`: Evicts least recently used (`OrderedDict.move_to_end()`)
|
|
14
|
+
- `LFUCache`: Evicts least frequently used (doubly-linked list of frequency buckets)
|
|
15
|
+
- `RRCache`: Random eviction (`__keys` list with `__index` dict for O(1) removal)
|
|
16
|
+
- `TTLCache`/`TLRUCache`: Time-based eviction via `_TimedCache` base; `_Timer` context manager freezes time during operations to prevent TOCTOU bugs; `expire()` returns `list[tuple[key, value]]`
|
|
17
|
+
|
|
18
|
+
### Decorators
|
|
19
|
+
- `@cached` (`_cached.py`): Function memoization; separate wrappers for each lock/condition/info combination; supports `cache=None` via `_uncached`/`_uncached_info` wrappers (pass-through without caching)
|
|
20
|
+
- `@cachedmethod` (`_cachedmethod.py`): Method memoization via descriptor protocol (`__set_name__`/`__get__`); class hierarchy: `_WrapperBase` (per-instance callable) → `_DescriptorBase` (descriptor with `__set_name__`/`__get__`, replaces self in instance `__dict__` via `setdefault` for thread safety) → `_DeprecatedDescriptorBase` (backward-compatible `@classmethod` support with warnings); the backward-compatible `_condition` variant uses `weakref.WeakKeyDictionary` for per-instance pending sets
|
|
21
|
+
- Both support `key`, `lock`, `condition`, and `info` parameters; when `condition` is given without `lock`, `condition` serves as both lock and condition
|
|
22
|
+
- `info=True` adds `cache_info()`/`cache_clear()`; `info=False` (default) only provides `cache_clear()`
|
|
23
|
+
- `func.py`: `functools.lru_cache`-compatible wrappers; all use `threading.Condition()` by default for thread safety + stampede prevention; `_UnboundTTLCache` extends `TTLCache` with `math.inf` maxsize for `maxsize=None`
|
|
24
|
+
|
|
25
|
+
### Thread Safety
|
|
26
|
+
3-tier locking: **Unlocked** | **Locked** (release during compute) | **Condition** (lock + pending set + `wait_for`/`notify_all` to prevent thundering herd)
|
|
27
|
+
|
|
28
|
+
`_AbstractCondition` protocol in `__init__.pyi`: extends `AbstractContextManager[Any]` + `Protocol` with `wait()`, `wait_for()`, `notify()`, `notify_all()`. Only `wait_for()` and `notify_all()` are used at runtime.
|
|
29
|
+
|
|
30
|
+
### Key Generation (`keys.py`)
|
|
31
|
+
- `hashkey`: Default key function; `_HashedTuple` caches hash values
|
|
32
|
+
- `methodkey`: Drops `self` from key; `typedkey`/`typedmethodkey`: Adds `type()` info
|
|
33
|
+
|
|
34
|
+
## Developer Workflows
|
|
35
|
+
|
|
36
|
+
### Testing
|
|
37
|
+
```bash
|
|
38
|
+
pytest # Run all tests
|
|
39
|
+
pytest --cov=cachetools --cov-report term-missing # With coverage
|
|
40
|
+
tox -e py # Just tests
|
|
41
|
+
tox -e ruff # Linting (ruff check)
|
|
42
|
+
tox -e ruff-format # Format check (ruff format --diff)
|
|
43
|
+
tox -e pyright # Type checking
|
|
44
|
+
tox -e docs # Build docs
|
|
45
|
+
tox -e doctest # Run doctests
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- `tests/__init__.py`: `CacheTestMixin` (16 standard tests), `_TestCaseProtocol`, `CountedLock`, `CountedCondition` (implements full `_AbstractCondition` protocol)
|
|
49
|
+
- Each cache test inherits `unittest.TestCase` + `CacheTestMixin`
|
|
50
|
+
- `test_cached.py` / `test_cachedmethod.py` use `DecoratorTestMixin` / `MethodDecoratorTestMixin` for all lock/condition/info combos
|
|
51
|
+
- Threading stampede tests gated by `THREADING_TESTS` env var (enabled in `tox.ini` via `setenv`)
|
|
52
|
+
|
|
53
|
+
### Code Style
|
|
54
|
+
- **ruff** formatter and linter (`tox -e ruff-format`, `tox -e ruff`)
|
|
55
|
+
|
|
56
|
+
## Conventions
|
|
57
|
+
|
|
58
|
+
### Adding New Cache Types
|
|
59
|
+
1. Inherit from `Cache` or `_TimedCache`
|
|
60
|
+
2. Override `__setitem__`, `__delitem__`, `popitem()` (optionally `__getitem__`)
|
|
61
|
+
3. Use default parameters to call parent: `def __setitem__(self, key, value, cache_setitem=Cache.__setitem__)`
|
|
62
|
+
4. Handle `__missing__` edge case: check `if key in self` after parent call
|
|
63
|
+
5. Add test class inheriting `CacheTestMixin`
|
|
64
|
+
|
|
65
|
+
### Type Stubs
|
|
66
|
+
Inline stubs ship with the package (`py.typed` marker):
|
|
67
|
+
- `@overload` distinguishes `info=True` vs `info=False`; `Literal[False]` overload listed last
|
|
68
|
+
- `_TimedCache` uses `Generic[_KT, _VT, _TT]` with `_TT` defaulting to `float`
|
|
69
|
+
- `_AbstractCondition` is `@type_check_only` `Protocol` for `condition` params and `cache_condition` attributes
|
|
70
|
+
- `_cached_wrapper` / `_cachedmethod_wrapper` use `ParamSpec(_P)` to preserve decorated function signatures; `__call__` uses `_P.args`/`_P.kwargs`
|
|
71
|
+
- `_cachedmethod_wrapper` models the descriptor protocol: `__set_name__`, `__get__`, `__call__`; uses `Concatenate[Any, _P]` so `_P` excludes `self`
|
|
72
|
+
- `_cachedmethod.py` uses `# type: ignore` for `functools.update_wrapper()` (typeshed #9846)
|
|
73
|
+
- Validate stubs with `tox -e pyright`
|
|
74
|
+
|
|
75
|
+
## Key Files
|
|
76
|
+
- `src/cachetools/__init__.py` — All cache implementations
|
|
77
|
+
- `src/cachetools/__init__.pyi` — Type stubs for caches and decorators
|
|
78
|
+
- `src/cachetools/_cached.py` — `@cached` decorator variants
|
|
79
|
+
- `src/cachetools/_cachedmethod.py` — `@cachedmethod` descriptor variants
|
|
80
|
+
- `src/cachetools/keys.py` / `keys.pyi` — Key functions
|
|
81
|
+
- `src/cachetools/func.py` / `func.pyi` — Functools-compatible wrappers (`lru_cache`, `ttl_cache`, etc.)
|
|
82
|
+
- `tests/__init__.py` — Test mixin and helpers
|
|
83
|
+
- `pyproject.toml` — Build config, version: `{attr = "cachetools.__version__"}`
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Code Review — cachetools 7.1.3
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-18
|
|
4
|
+
**CI status:** All green (tox: py, ruff, ruff-format, pyright, docs, doctest)
|
|
5
|
+
|
|
6
|
+
## Type Stubs (`__init__.pyi`, `keys.pyi`, `func.pyi`)
|
|
7
|
+
|
|
8
|
+
No issues. `cached` and `cachedmethod` stubs use `ParamSpec(_P)` to
|
|
9
|
+
preserve decorated function signatures (`__call__` uses `_P.args`/`_P.kwargs`).
|
|
10
|
+
`cachedmethod` stubs use `Concatenate[Any, _P]` to strip `self` from
|
|
11
|
+
`ParamSpec`, and `_cachedmethod_wrapper` models the descriptor protocol
|
|
12
|
+
(`__set_name__`, `__get__`, `__call__`). Overload ordering is correct
|
|
13
|
+
(`Literal[True]` before `Literal[False]` default).
|
|
14
|
+
|
|
15
|
+
`func.pyi` deliberately uses `Callable[..., _R]` instead of `ParamSpec`
|
|
16
|
+
for `_cachetools_cache_wrapper` since the `func.*_cache` decorators
|
|
17
|
+
rewrite signatures (adding `cache_info`, `cache_clear`, `cache_parameters`).
|
|
18
|
+
|
|
19
|
+
## Code — Potential Issues
|
|
20
|
+
|
|
21
|
+
| # | Severity | Location | Finding |
|
|
22
|
+
|---|----------|----------|---------|
|
|
23
|
+
| 1 | Low | `Cache.__init__` | `maxsize` is not validated. Negative values cause confusing `popitem` errors at insertion time rather than a clear early `ValueError`. Docs note `maxsize` must be positive, but code does not enforce it. |
|
|
24
|
+
| 2 | Low | `Cache.__setitem__`/`__delitem__` | Size accounting assumes value size is stable after insert. In-place mutation of cached values can desync `currsize`. By design (documented), but a known footgun. |
|
|
25
|
+
| 3 | Low | `_cachedmethod.py` condition variants | Stampede prevention uses per-instance pending sets. Two instances sharing one cache+condition won't coordinate pending keys across instances. |
|
|
26
|
+
| 4 | Info | `_cachedmethod.py` / `_cached.py` condition variants | Same-thread recursive re-entry on the same key will deadlock (`wait_for` on own pending marker). |
|
|
27
|
+
|
|
28
|
+
No implementation bugs found.
|
|
29
|
+
|
|
30
|
+
## Tests — Gaps
|
|
31
|
+
|
|
32
|
+
| # | Priority | Finding |
|
|
33
|
+
|---|----------|---------|
|
|
34
|
+
| 1 | Medium | Threading tests join workers without timeout (`test_threading.py`), so a deadlock regression hangs CI instead of failing. |
|
|
35
|
+
| 2 | Medium | Lock-only race resolution (`cache.setdefault` in locked wrappers) is not stress-tested under real concurrency — only condition-based wrappers have threading tests. |
|
|
36
|
+
| 3 | Low | `@cached` condition wrappers lack an error-path test (pending cleanup on exception). Equivalent coverage exists for `@cachedmethod` (`test_decorator_cond_error`) but not for `@cached`. |
|
|
37
|
+
| 4 | Low | `CacheTestMixin` assertions are intentionally weak on eviction-order correctness (checks key existence, not specific eviction victim), relying on per-cache test files for policy validation. |
|
|
38
|
+
| 5 | Low | `test_cached.py`: zero-size + condition + `info=True` combination is not tested (zero-size only tested for no-lock and lock variants). |
|
|
39
|
+
| 6 | Low | `test_lfu.py`: no tie-breaking test for equal-frequency eviction (current code picks an arbitrary element via `next(iter(curr.keys))`). |
|
|
40
|
+
| 7 | Low | `test_classmethod.py`: limited coverage — only deprecation warnings + basic functionality. No `info=True`, error-path, or shared-cache tests. |
|
|
41
|
+
|
|
42
|
+
## Docs
|
|
43
|
+
|
|
44
|
+
| # | Priority | Finding |
|
|
45
|
+
|---|----------|---------|
|
|
46
|
+
| 1 | Low | `condition` docs say it must provide `wait()`, `wait_for()`, `notify()` and `notify_all()`, but only `wait_for()` and `notify_all()` are used at runtime. The `_AbstractCondition` protocol in stubs includes all four for compatibility with `threading.Condition`. |
|
|
47
|
+
| 2 | Info | PEP URLs in examples use legacy `http://www.python.org/dev/peps/` (moved to `peps.python.org`), but these are mocked in doctests so functionally irrelevant. |
|
|
48
|
+
|
|
49
|
+
## Keys & Func Modules
|
|
50
|
+
|
|
51
|
+
No issues found. `func.py` correctly uses `threading.Condition()` for
|
|
52
|
+
all decorators, providing stampede prevention by default. `_UnboundTTLCache`
|
|
53
|
+
cleanly extends `TTLCache` with `math.inf` maxsize for the
|
|
54
|
+
`maxsize=None` case.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request, workflow_dispatch]
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
main:
|
|
10
|
+
name: Python ${{ matrix.python }}
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python: ["3.10", "3.11", "3.12", "3.13", "3.13t", "3.14", "3.14t", "pypy3.10", "pypy3.11"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
18
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python }}
|
|
21
|
+
allow-prereleases: true
|
|
22
|
+
- run: pip install coverage tox
|
|
23
|
+
- run: tox
|
|
24
|
+
- uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
|
25
|
+
with:
|
|
26
|
+
name: ${{ matrix.python }}
|
|
27
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -12,7 +12,7 @@ __all__ = (
|
|
|
12
12
|
"cachedmethod",
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
-
__version__ = "7.1.
|
|
15
|
+
__version__ = "7.1.3"
|
|
16
16
|
|
|
17
17
|
import collections
|
|
18
18
|
import collections.abc
|
|
@@ -23,9 +23,6 @@ import time
|
|
|
23
23
|
|
|
24
24
|
from . import keys
|
|
25
25
|
|
|
26
|
-
# Typing stubs for this package are provided by typeshed:
|
|
27
|
-
# https://github.com/python/typeshed/tree/main/stubs/cachetools
|
|
28
|
-
|
|
29
26
|
|
|
30
27
|
class _DefaultSize:
|
|
31
28
|
"""A minimal "fake" dict that returns a constant size 1 for any key."""
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
from collections.abc import Callable, Sequence
|
|
2
|
-
from typing import Any, Final, Generic, TypeVar, overload, type_check_only
|
|
2
|
+
from typing import Any, Final, Generic, ParamSpec, TypeVar, overload, type_check_only
|
|
3
3
|
|
|
4
4
|
from . import _CacheInfo
|
|
5
5
|
|
|
6
6
|
__all__: Final = ("fifo_cache", "lfu_cache", "lru_cache", "rr_cache", "ttl_cache")
|
|
7
7
|
|
|
8
|
+
_P = ParamSpec("_P")
|
|
8
9
|
_T = TypeVar("_T")
|
|
9
10
|
_R = TypeVar("_R")
|
|
10
11
|
|
|
11
12
|
@type_check_only
|
|
12
|
-
class _cachetools_cache_wrapper(Generic[_R]):
|
|
13
|
-
__wrapped__: Callable[
|
|
13
|
+
class _cachetools_cache_wrapper(Generic[_P, _R]):
|
|
14
|
+
__wrapped__: Callable[_P, _R]
|
|
14
15
|
__name__: str
|
|
15
16
|
__doc__: str | None
|
|
16
|
-
def __call__(self, /, *args:
|
|
17
|
+
def __call__(self, /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
|
|
17
18
|
def cache_info(self) -> _CacheInfo: ...
|
|
18
19
|
def cache_clear(self) -> None: ...
|
|
19
20
|
def cache_parameters(self) -> dict[str, Any]: ...
|
|
@@ -21,50 +22,50 @@ class _cachetools_cache_wrapper(Generic[_R]):
|
|
|
21
22
|
@overload
|
|
22
23
|
def fifo_cache(
|
|
23
24
|
maxsize: int | None = 128, typed: bool = False
|
|
24
|
-
) -> Callable[[Callable[
|
|
25
|
+
) -> Callable[[Callable[_P, _R]], _cachetools_cache_wrapper[_P, _R]]: ...
|
|
25
26
|
@overload
|
|
26
27
|
def fifo_cache(
|
|
27
|
-
maxsize: Callable[
|
|
28
|
-
) -> _cachetools_cache_wrapper[_R]: ...
|
|
28
|
+
maxsize: Callable[_P, _R], typed: bool = False
|
|
29
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
29
30
|
@overload
|
|
30
31
|
def lfu_cache(
|
|
31
32
|
maxsize: int | None = 128, typed: bool = False
|
|
32
|
-
) -> Callable[[Callable[
|
|
33
|
+
) -> Callable[[Callable[_P, _R]], _cachetools_cache_wrapper[_P, _R]]: ...
|
|
33
34
|
@overload
|
|
34
35
|
def lfu_cache(
|
|
35
|
-
maxsize: Callable[
|
|
36
|
-
) -> _cachetools_cache_wrapper[_R]: ...
|
|
36
|
+
maxsize: Callable[_P, _R], typed: bool = False
|
|
37
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
37
38
|
@overload
|
|
38
39
|
def lru_cache(
|
|
39
40
|
maxsize: int | None = 128, typed: bool = False
|
|
40
|
-
) -> Callable[[Callable[
|
|
41
|
+
) -> Callable[[Callable[_P, _R]], _cachetools_cache_wrapper[_P, _R]]: ...
|
|
41
42
|
@overload
|
|
42
43
|
def lru_cache(
|
|
43
|
-
maxsize: Callable[
|
|
44
|
-
) -> _cachetools_cache_wrapper[_R]: ...
|
|
44
|
+
maxsize: Callable[_P, _R], typed: bool = False
|
|
45
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
45
46
|
@overload
|
|
46
47
|
def rr_cache(
|
|
47
48
|
maxsize: int | None = 128,
|
|
48
49
|
choice: Callable[[Sequence[_T]], _T] = ...,
|
|
49
50
|
typed: bool = False,
|
|
50
|
-
) -> Callable[[Callable[
|
|
51
|
+
) -> Callable[[Callable[_P, _R]], _cachetools_cache_wrapper[_P, _R]]: ...
|
|
51
52
|
@overload
|
|
52
53
|
def rr_cache(
|
|
53
|
-
maxsize: Callable[
|
|
54
|
+
maxsize: Callable[_P, _R],
|
|
54
55
|
choice: Callable[[Sequence[_T]], _T] = ...,
|
|
55
56
|
typed: bool = False,
|
|
56
|
-
) -> _cachetools_cache_wrapper[_R]: ...
|
|
57
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
57
58
|
@overload
|
|
58
59
|
def ttl_cache(
|
|
59
60
|
maxsize: int | None = 128,
|
|
60
61
|
ttl: Any = 600,
|
|
61
62
|
timer: Callable[[], _T] = ...,
|
|
62
63
|
typed: bool = False,
|
|
63
|
-
) -> Callable[[Callable[
|
|
64
|
+
) -> Callable[[Callable[_P, _R]], _cachetools_cache_wrapper[_P, _R]]: ...
|
|
64
65
|
@overload
|
|
65
66
|
def ttl_cache(
|
|
66
|
-
maxsize: Callable[
|
|
67
|
+
maxsize: Callable[_P, _R],
|
|
67
68
|
ttl: Any = 600,
|
|
68
69
|
timer: Callable[[], _T] = ...,
|
|
69
70
|
typed: bool = False,
|
|
70
|
-
) -> _cachetools_cache_wrapper[_R]: ...
|
|
71
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
.readthedocs.yaml
|
|
1
3
|
CHANGELOG.rst
|
|
2
4
|
LICENSE
|
|
3
5
|
README.rst
|
|
4
6
|
pyproject.toml
|
|
5
7
|
tox.ini
|
|
8
|
+
.github/FUNDING.yml
|
|
9
|
+
.github/PULL_REQUEST_TEMPLATE.md
|
|
10
|
+
.github/SECURITY.md
|
|
11
|
+
.github/copilot-instructions.md
|
|
12
|
+
.github/copilot-review.md
|
|
13
|
+
.github/dependabot.yml
|
|
14
|
+
.github/ISSUE_TEMPLATE/bug_report.md
|
|
15
|
+
.github/ISSUE_TEMPLATE/config.yml
|
|
16
|
+
.github/ISSUE_TEMPLATE/feature_request.md
|
|
17
|
+
.github/workflows/ci.yml
|
|
6
18
|
docs/conf.py
|
|
7
19
|
docs/index.rst
|
|
8
20
|
src/cachetools/__init__.py
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[tox]
|
|
2
|
-
envlist = docs,doctest,format,
|
|
2
|
+
envlist = py,docs,doctest,ruff,ruff-format,pyright
|
|
3
3
|
|
|
4
4
|
[testenv]
|
|
5
5
|
deps =
|
|
@@ -22,18 +22,18 @@ deps =
|
|
|
22
22
|
commands =
|
|
23
23
|
sphinx-build -W -b doctest -d {envtmpdir}/doctrees docs {envtmpdir}/doctest
|
|
24
24
|
|
|
25
|
-
[testenv:
|
|
25
|
+
[testenv:ruff]
|
|
26
26
|
deps =
|
|
27
27
|
ruff
|
|
28
28
|
commands =
|
|
29
|
-
ruff
|
|
29
|
+
ruff check {posargs}
|
|
30
30
|
skip_install = true
|
|
31
31
|
|
|
32
|
-
[testenv:
|
|
32
|
+
[testenv:ruff-format]
|
|
33
33
|
deps =
|
|
34
34
|
ruff
|
|
35
35
|
commands =
|
|
36
|
-
ruff
|
|
36
|
+
ruff format --diff -q {posargs}
|
|
37
37
|
skip_install = true
|
|
38
38
|
|
|
39
39
|
[testenv:pyright]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|