cachebox 6.2.4__tar.gz → 6.2.5__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 (79) hide show
  1. {cachebox-6.2.4 → cachebox-6.2.5}/Cargo.lock +29 -29
  2. {cachebox-6.2.4 → cachebox-6.2.5}/Cargo.toml +3 -3
  3. {cachebox-6.2.4 → cachebox-6.2.5}/PKG-INFO +7 -5
  4. {cachebox-6.2.4 → cachebox-6.2.5}/README.md +6 -4
  5. {cachebox-6.2.4 → cachebox-6.2.5}/cachebox/_core.pyi +65 -28
  6. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/lazyheap.rs +18 -0
  7. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/linked_list.rs +13 -0
  8. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/utils.rs +38 -0
  9. {cachebox-6.2.4 → cachebox-6.2.5}/src/macro_rules.rs +27 -0
  10. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/fifopolicy.rs +1 -0
  11. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/lfupolicy.rs +1 -0
  12. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/lrupolicy.rs +8 -1
  13. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/nopolicy.rs +1 -0
  14. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/rrpolicy.rs +1 -0
  15. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/traits.rs +1 -0
  16. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/ttlpolicy.rs +1 -0
  17. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/vttlpolicy.rs +1 -0
  18. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/wrapped.rs +1 -1
  19. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/cache.rs +15 -11
  20. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/fifocache.rs +15 -11
  21. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/lfucache.rs +15 -11
  22. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/lrucache.rs +15 -11
  23. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/rrcache.rs +15 -11
  24. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/ttlcache.rs +29 -12
  25. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/vttlcache.rs +29 -12
  26. {cachebox-6.2.4 → cachebox-6.2.5}/tests/mixins.py +40 -0
  27. {cachebox-6.2.4 → cachebox-6.2.5}/tests/test_impls.py +87 -0
  28. {cachebox-6.2.4 → cachebox-6.2.5}/.github/dependabot.yaml +0 -0
  29. {cachebox-6.2.4 → cachebox-6.2.5}/.github/workflows/CI.yml +0 -0
  30. {cachebox-6.2.4 → cachebox-6.2.5}/.github/workflows/docs.yml +0 -0
  31. {cachebox-6.2.4 → cachebox-6.2.5}/.github/workflows/python-test.yml +0 -0
  32. {cachebox-6.2.4 → cachebox-6.2.5}/.gitignore +0 -0
  33. {cachebox-6.2.4 → cachebox-6.2.5}/LICENSE +0 -0
  34. {cachebox-6.2.4 → cachebox-6.2.5}/LICENSE-THIRD-PARTY +0 -0
  35. {cachebox-6.2.4 → cachebox-6.2.5}/build.rs +0 -0
  36. {cachebox-6.2.4 → cachebox-6.2.5}/cachebox/__init__.py +0 -0
  37. {cachebox-6.2.4 → cachebox-6.2.5}/cachebox/_cachebox.py +0 -0
  38. {cachebox-6.2.4 → cachebox-6.2.5}/cachebox/_wrappers.py +0 -0
  39. {cachebox-6.2.4 → cachebox-6.2.5}/cachebox/utils.py +0 -0
  40. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/api/impls.md +0 -0
  41. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/api/index.md +0 -0
  42. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/api/utils.md +0 -0
  43. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/getting-started.md +0 -0
  44. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/index.md +0 -0
  45. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/installation.md +0 -0
  46. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/migration.md +0 -0
  47. {cachebox-6.2.4 → cachebox-6.2.5}/docs/docs/tips.md +0 -0
  48. {cachebox-6.2.4 → cachebox-6.2.5}/docs/mkdocs.yml +0 -0
  49. {cachebox-6.2.4 → cachebox-6.2.5}/pyproject.toml +0 -0
  50. {cachebox-6.2.4 → cachebox-6.2.5}/rust-toolchain.toml +0 -0
  51. {cachebox-6.2.4 → cachebox-6.2.5}/rustfmt.toml +0 -0
  52. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/alloc.rs +0 -0
  53. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/bitmask.rs +0 -0
  54. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/group/generic.rs +0 -0
  55. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/group/lsx.rs +0 -0
  56. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/group/mod.rs +0 -0
  57. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/group/neon.rs +0 -0
  58. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/group/sse2.rs +0 -0
  59. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/mod.rs +0 -0
  60. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/control/tag.rs +0 -0
  61. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/mod.rs +0 -0
  62. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/raw.rs +0 -0
  63. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/scopeguard.rs +0 -0
  64. {cachebox-6.2.4 → cachebox-6.2.5}/src/hashbrown/util.rs +0 -0
  65. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/alias.rs +0 -0
  66. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/mod.rs +0 -0
  67. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/onceinit.rs +0 -0
  68. {cachebox-6.2.4 → cachebox-6.2.5}/src/internal/pickle.rs +0 -0
  69. {cachebox-6.2.4 → cachebox-6.2.5}/src/lib.rs +0 -0
  70. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/common.rs +0 -0
  71. {cachebox-6.2.4 → cachebox-6.2.5}/src/policies/mod.rs +0 -0
  72. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/base.rs +0 -0
  73. {cachebox-6.2.4 → cachebox-6.2.5}/src/pyclasses/mod.rs +0 -0
  74. {cachebox-6.2.4 → cachebox-6.2.5}/src/typeref.rs +0 -0
  75. {cachebox-6.2.4 → cachebox-6.2.5}/tests/__init__.py +0 -0
  76. {cachebox-6.2.4 → cachebox-6.2.5}/tests/conftest.py +0 -0
  77. {cachebox-6.2.4 → cachebox-6.2.5}/tests/test_utils.py +0 -0
  78. {cachebox-6.2.4 → cachebox-6.2.5}/typos.toml +0 -0
  79. {cachebox-6.2.4 → cachebox-6.2.5}/uv.lock +0 -0
@@ -10,9 +10,9 @@ checksum = "c880a97d28a3681c0267bd29cff89621202715b065127cd445fa0f0fe0aa2880"
10
10
 
11
11
  [[package]]
12
12
  name = "android_system_properties"
13
- version = "0.1.5"
13
+ version = "0.1.6"
14
14
  source = "registry+https://github.com/rust-lang/crates.io-index"
15
- checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
15
+ checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc"
16
16
  dependencies = [
17
17
  "libc",
18
18
  ]
@@ -37,7 +37,7 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
37
37
 
38
38
  [[package]]
39
39
  name = "cachebox"
40
- version = "6.2.4"
40
+ version = "6.2.5"
41
41
  dependencies = [
42
42
  "allocator-api2",
43
43
  "cfg-if",
@@ -50,9 +50,9 @@ dependencies = [
50
50
 
51
51
  [[package]]
52
52
  name = "cc"
53
- version = "1.4.0"
53
+ version = "1.4.2"
54
54
  source = "registry+https://github.com/rust-lang/crates.io-index"
55
- checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
55
+ checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e"
56
56
  dependencies = [
57
57
  "find-msvc-tools",
58
58
  "shlex",
@@ -91,9 +91,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
91
91
 
92
92
  [[package]]
93
93
  name = "find-msvc-tools"
94
- version = "0.1.9"
94
+ version = "0.1.10"
95
95
  source = "registry+https://github.com/rust-lang/crates.io-index"
96
- checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
96
+ checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de"
97
97
 
98
98
  [[package]]
99
99
  name = "futures-core"
@@ -151,9 +151,9 @@ dependencies = [
151
151
 
152
152
  [[package]]
153
153
  name = "js-sys"
154
- version = "0.3.103"
154
+ version = "0.3.104"
155
155
  source = "registry+https://github.com/rust-lang/crates.io-index"
156
- checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
156
+ checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
157
157
  dependencies = [
158
158
  "cfg-if",
159
159
  "futures-util",
@@ -227,9 +227,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
227
227
 
228
228
  [[package]]
229
229
  name = "portable-atomic"
230
- version = "1.14.0"
230
+ version = "1.15.0"
231
231
  source = "registry+https://github.com/rust-lang/crates.io-index"
232
- checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
232
+ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
233
233
 
234
234
  [[package]]
235
235
  name = "proc-macro2"
@@ -242,9 +242,9 @@ dependencies = [
242
242
 
243
243
  [[package]]
244
244
  name = "pyo3"
245
- version = "0.29.1"
245
+ version = "0.29.2"
246
246
  source = "registry+https://github.com/rust-lang/crates.io-index"
247
- checksum = "fc153f5fd745cc038b5eed86622125969f8a39834a57bc96beaaf2512b1da729"
247
+ checksum = "4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b"
248
248
  dependencies = [
249
249
  "chrono",
250
250
  "libc",
@@ -257,18 +257,18 @@ dependencies = [
257
257
 
258
258
  [[package]]
259
259
  name = "pyo3-build-config"
260
- version = "0.29.1"
260
+ version = "0.29.2"
261
261
  source = "registry+https://github.com/rust-lang/crates.io-index"
262
- checksum = "bb77d9aa6d647507b55c69ee714d266d84c526c78ff0bc6dd8757f58591e64d1"
262
+ checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"
263
263
  dependencies = [
264
264
  "target-lexicon",
265
265
  ]
266
266
 
267
267
  [[package]]
268
268
  name = "pyo3-ffi"
269
- version = "0.29.1"
269
+ version = "0.29.2"
270
270
  source = "registry+https://github.com/rust-lang/crates.io-index"
271
- checksum = "3160087aa5733bce7d9a729f8c55f85a2a53b74742a09613178eeebff0722253"
271
+ checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327"
272
272
  dependencies = [
273
273
  "libc",
274
274
  "pyo3-build-config",
@@ -276,9 +276,9 @@ dependencies = [
276
276
 
277
277
  [[package]]
278
278
  name = "pyo3-macros"
279
- version = "0.29.1"
279
+ version = "0.29.2"
280
280
  source = "registry+https://github.com/rust-lang/crates.io-index"
281
- checksum = "91f9d455db760a9a0b0ddeaac25f1390b8a36ba73dfbda9f127cac6fc340d4d5"
281
+ checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c"
282
282
  dependencies = [
283
283
  "proc-macro2",
284
284
  "pyo3-macros-backend",
@@ -288,9 +288,9 @@ dependencies = [
288
288
 
289
289
  [[package]]
290
290
  name = "pyo3-macros-backend"
291
- version = "0.29.1"
291
+ version = "0.29.2"
292
292
  source = "registry+https://github.com/rust-lang/crates.io-index"
293
- checksum = "e343bcec300ff262f5806a33a4e51b6d097a8a46435f512fcb83e95592581625"
293
+ checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952"
294
294
  dependencies = [
295
295
  "heck",
296
296
  "proc-macro2",
@@ -371,9 +371,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
371
371
 
372
372
  [[package]]
373
373
  name = "wasm-bindgen"
374
- version = "0.2.126"
374
+ version = "0.2.127"
375
375
  source = "registry+https://github.com/rust-lang/crates.io-index"
376
- checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
376
+ checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
377
377
  dependencies = [
378
378
  "cfg-if",
379
379
  "once_cell",
@@ -384,9 +384,9 @@ dependencies = [
384
384
 
385
385
  [[package]]
386
386
  name = "wasm-bindgen-macro"
387
- version = "0.2.126"
387
+ version = "0.2.127"
388
388
  source = "registry+https://github.com/rust-lang/crates.io-index"
389
- checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
389
+ checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
390
390
  dependencies = [
391
391
  "quote",
392
392
  "wasm-bindgen-macro-support",
@@ -394,9 +394,9 @@ dependencies = [
394
394
 
395
395
  [[package]]
396
396
  name = "wasm-bindgen-macro-support"
397
- version = "0.2.126"
397
+ version = "0.2.127"
398
398
  source = "registry+https://github.com/rust-lang/crates.io-index"
399
- checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
399
+ checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
400
400
  dependencies = [
401
401
  "bumpalo",
402
402
  "proc-macro2",
@@ -407,9 +407,9 @@ dependencies = [
407
407
 
408
408
  [[package]]
409
409
  name = "wasm-bindgen-shared"
410
- version = "0.2.126"
410
+ version = "0.2.127"
411
411
  source = "registry+https://github.com/rust-lang/crates.io-index"
412
- checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
412
+ checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
413
413
  dependencies = [
414
414
  "unicode-ident",
415
415
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "cachebox"
3
- version = "6.2.4"
3
+ version = "6.2.5"
4
4
  edition = "2021"
5
5
  description = "The fastest memoizing and caching Python library written in Rust"
6
6
  readme = "README.md"
@@ -27,10 +27,10 @@ cfg-if = "1.0.4"
27
27
  chrono = "0.4.45"
28
28
  fastrand = "2.5.0"
29
29
  parking_lot = { version = "0.12.5", default-features = false }
30
- pyo3 = { version = "0.29.1", default-features = false, features = ["macros", "chrono"] }
30
+ pyo3 = { version = "0.29.2", default-features = false, features = ["macros", "chrono"] }
31
31
 
32
32
  [build-dependencies]
33
- pyo3-build-config = { version = "0.29.1", default-features = false, features = ["resolve-config"] }
33
+ pyo3-build-config = { version = "0.29.2", default-features = false, features = ["resolve-config"] }
34
34
 
35
35
  [features]
36
36
  default = ["inline-more", "extension-module"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachebox
3
- Version: 6.2.4
3
+ Version: 6.2.5
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3
@@ -47,9 +47,9 @@ _The fastest caching Python library written in Rust_
47
47
  [![Monthly Downloads](https://shieldcn.dev/pypi/dm/cachebox.svg?variant=branded&font=geist-mono&size=xs)](https://pypi.org/project/cachebox)
48
48
  [![Python Version](https://shieldcn.dev/pypi/python/cachebox.svg?variant=branded&font=geist-mono&size=xs)](https://pypi.org/project/cachebox)
49
49
 
50
- [![CI](https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse)](https://github.com/awolverp/cachebox/actions?query=branch%3Amain)
51
- [![Last Commit](https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs)](https://github.com/awolverp/cachebox/commits/main)
52
- [![License](https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs)](https://github.com/awolverp/cachebox/blob/main/LICENSE)
50
+ <a href="https://github.com/awolverp/cachebox/actions?query=branch%3Amain"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse&mode=dark"><img alt="CI" src="https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse&mode=light"></picture></a>
51
+ <a href="https://github.com/awolverp/cachebox/commits/main"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&mode=dark"><img alt="Last Commit" src="https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&mode=light"></picture></a>
52
+ <a href="https://github.com/awolverp/cachebox/blob/main/LICENSE"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs&mode=dark"><img alt="License" src="https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs&mode=light"></picture></a>
53
53
 
54
54
  </div>
55
55
 
@@ -184,7 +184,9 @@ Read the documentation for full information and learn more: [**Documentation**](
184
184
 
185
185
  ## Contributors
186
186
 
187
- [![Contributers](https://contrib.rocks/image?repo=awolverp/cachebox)](https://github.com/awolverp/cachebox/graphs/contributors)
187
+ <p align="center">
188
+ <a href="https://github.com/awolverp/cachebox/graphs/contributors"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/contributors/awolverp/cachebox.svg?title=false&amp;preset=transparent&amp;size=80&amp;names=true&amp;titleAlign=center&amp;mode=dark" /><img alt="contributors" src="https://shieldcn.dev/contributors/awolverp/cachebox.svg?title=false&amp;preset=transparent&amp;size=80&amp;names=true&amp;titleAlign=center&amp;mode=light" /></picture></a>
189
+ </p>
188
190
 
189
191
  ## License
190
192
 
@@ -11,9 +11,9 @@ _The fastest caching Python library written in Rust_
11
11
  [![Monthly Downloads](https://shieldcn.dev/pypi/dm/cachebox.svg?variant=branded&font=geist-mono&size=xs)](https://pypi.org/project/cachebox)
12
12
  [![Python Version](https://shieldcn.dev/pypi/python/cachebox.svg?variant=branded&font=geist-mono&size=xs)](https://pypi.org/project/cachebox)
13
13
 
14
- [![CI](https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse)](https://github.com/awolverp/cachebox/actions?query=branch%3Amain)
15
- [![Last Commit](https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs)](https://github.com/awolverp/cachebox/commits/main)
16
- [![License](https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs)](https://github.com/awolverp/cachebox/blob/main/LICENSE)
14
+ <a href="https://github.com/awolverp/cachebox/actions?query=branch%3Amain"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse&mode=dark"><img alt="CI" src="https://shieldcn.dev/github/ci/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&animate=pulse&mode=light"></picture></a>
15
+ <a href="https://github.com/awolverp/cachebox/commits/main"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&mode=dark"><img alt="Last Commit" src="https://shieldcn.dev/github/last-commit/awolverp/cachebox.svg?variant=outline&font=geist-mono&size=xs&mode=light"></picture></a>
16
+ <a href="https://github.com/awolverp/cachebox/blob/main/LICENSE"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs&mode=dark"><img alt="License" src="https://shieldcn.dev/github/awolverp/cachebox/license.svg?variant=outline&font=geist-mono&size=xs&mode=light"></picture></a>
17
17
 
18
18
  </div>
19
19
 
@@ -148,7 +148,9 @@ Read the documentation for full information and learn more: [**Documentation**](
148
148
 
149
149
  ## Contributors
150
150
 
151
- [![Contributers](https://contrib.rocks/image?repo=awolverp/cachebox)](https://github.com/awolverp/cachebox/graphs/contributors)
151
+ <p align="center">
152
+ <a href="https://github.com/awolverp/cachebox/graphs/contributors"><picture><source media="(prefers-color-scheme: dark)" srcset="https://shieldcn.dev/contributors/awolverp/cachebox.svg?title=false&amp;preset=transparent&amp;size=80&amp;names=true&amp;titleAlign=center&amp;mode=dark" /><img alt="contributors" src="https://shieldcn.dev/contributors/awolverp/cachebox.svg?title=false&amp;preset=transparent&amp;size=80&amp;names=true&amp;titleAlign=center&amp;mode=light" /></picture></a>
153
+ </p>
152
154
 
153
155
  ## License
154
156
 
@@ -9,6 +9,7 @@ __version__: typing.Final[str]
9
9
  KT = typing.TypeVar("KT", bound=typing.Hashable)
10
10
  VT = typing.TypeVar("VT")
11
11
  DT = typing.TypeVar("DT")
12
+ T_co = typing.TypeVar("T_co", covariant=True)
12
13
 
13
14
  _IterableType: typing.TypeAlias = (
14
15
  typing.Dict[KT, VT]
@@ -17,6 +18,42 @@ _IterableType: typing.TypeAlias = (
17
18
  | typing.Iterable[typing.Tuple[KT, VT]]
18
19
  )
19
20
 
21
+ class CacheIterator(typing.Iterator[T_co]):
22
+ """
23
+ What ``keys()``, ``values()`` and ``items()`` return.
24
+
25
+ This is a one-shot iterator, not a ``dict`` view: it walks the cache once
26
+ and is empty after that. It knows how many items it still has to yield, so
27
+ ``len()`` and ``bool()`` work on it, but it does not support ``in`` or set
28
+ operations the way ``dict.keys()`` does.
29
+
30
+ Warning:
31
+ Do not modify the cache while one of these is alive. Every method
32
+ raises ``RuntimeError`` if the cache changed.
33
+ """
34
+
35
+ def __next__(self) -> T_co: ...
36
+ def __len__(self) -> int:
37
+ """
38
+ Returns how many items are left to yield.
39
+
40
+ For ``TTLCache`` and ``VTTLCache`` this skips expired entries, which
41
+ takes O(n).
42
+
43
+ Returns:
44
+ The number of items left.
45
+ """
46
+ ...
47
+
48
+ def __bool__(self) -> bool:
49
+ """
50
+ Returns whether any item is left to yield.
51
+
52
+ Returns:
53
+ ``True`` if at least one item is left.
54
+ """
55
+ ...
56
+
20
57
  class BaseCacheImpl(typing.Generic[KT, VT]):
21
58
  """
22
59
  Base implementation for cache classes.
@@ -221,10 +258,10 @@ class BaseCacheImpl(typing.Generic[KT, VT]):
221
258
 
222
259
  def __eq__(self, other: typing.Any) -> bool: ...
223
260
  def __ne__(self, other: typing.Any) -> bool: ...
224
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]: ...
225
- def values(self) -> typing.Iterable[VT]: ...
226
- def keys(self) -> typing.Iterable[KT]: ...
227
- def __iter__(self) -> typing.Iterator[KT]: ...
261
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]: ...
262
+ def values(self) -> CacheIterator[VT]: ...
263
+ def keys(self) -> CacheIterator[KT]: ...
264
+ def __iter__(self) -> CacheIterator[KT]: ...
228
265
  def copy(self) -> typing.Self: ...
229
266
  def __copy__(self) -> typing.Self: ...
230
267
  def __getstate__(self) -> object: ...
@@ -410,7 +447,7 @@ class Cache(BaseCacheImpl[KT, VT]):
410
447
  """
411
448
  ...
412
449
 
413
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
450
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
414
451
  """
415
452
  Returns an iterable of the cache's ``(key, value)`` pairs.
416
453
 
@@ -422,7 +459,7 @@ class Cache(BaseCacheImpl[KT, VT]):
422
459
  """
423
460
  ...
424
461
 
425
- def keys(self) -> typing.Iterable[KT]:
462
+ def keys(self) -> CacheIterator[KT]:
426
463
  """
427
464
  Returns an iterable of the cache's keys.
428
465
 
@@ -434,7 +471,7 @@ class Cache(BaseCacheImpl[KT, VT]):
434
471
  """
435
472
  ...
436
473
 
437
- def values(self) -> typing.Iterable[VT]:
474
+ def values(self) -> CacheIterator[VT]:
438
475
  """
439
476
  Returns an iterable of the cache's values.
440
477
 
@@ -593,7 +630,7 @@ class FIFOCache(BaseCacheImpl[KT, VT]):
593
630
  """
594
631
  ...
595
632
 
596
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
633
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
597
634
  """
598
635
  Returns an ordered iterable of the cache's ``(key, value)`` pairs.
599
636
 
@@ -605,7 +642,7 @@ class FIFOCache(BaseCacheImpl[KT, VT]):
605
642
  """
606
643
  ...
607
644
 
608
- def keys(self) -> typing.Iterable[KT]:
645
+ def keys(self) -> CacheIterator[KT]:
609
646
  """
610
647
  Returns an ordered iterable of the cache's keys.
611
648
 
@@ -617,7 +654,7 @@ class FIFOCache(BaseCacheImpl[KT, VT]):
617
654
  """
618
655
  ...
619
656
 
620
- def values(self) -> typing.Iterable[VT]:
657
+ def values(self) -> CacheIterator[VT]:
621
658
  """
622
659
  Returns an ordered iterable of the cache's values.
623
660
 
@@ -808,7 +845,7 @@ class RRCache(BaseCacheImpl[KT, VT]):
808
845
  """
809
846
  ...
810
847
 
811
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
848
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
812
849
  """
813
850
  Returns an iterable of the cache's ``(key, value)`` pairs.
814
851
 
@@ -820,7 +857,7 @@ class RRCache(BaseCacheImpl[KT, VT]):
820
857
  """
821
858
  ...
822
859
 
823
- def keys(self) -> typing.Iterable[KT]:
860
+ def keys(self) -> CacheIterator[KT]:
824
861
  """
825
862
  Returns an iterable of the cache's keys.
826
863
 
@@ -832,7 +869,7 @@ class RRCache(BaseCacheImpl[KT, VT]):
832
869
  """
833
870
  ...
834
871
 
835
- def values(self) -> typing.Iterable[VT]:
872
+ def values(self) -> CacheIterator[VT]:
836
873
  """
837
874
  Returns an iterable of the cache's values.
838
875
 
@@ -1016,7 +1053,7 @@ class LRUCache(BaseCacheImpl[KT, VT]):
1016
1053
  """
1017
1054
  ...
1018
1055
 
1019
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
1056
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
1020
1057
  """
1021
1058
  Returns an ordered iterable of the cache's ``(key, value)`` pairs.
1022
1059
 
@@ -1028,7 +1065,7 @@ class LRUCache(BaseCacheImpl[KT, VT]):
1028
1065
  """
1029
1066
  ...
1030
1067
 
1031
- def keys(self) -> typing.Iterable[KT]:
1068
+ def keys(self) -> CacheIterator[KT]:
1032
1069
  """
1033
1070
  Returns an ordered iterable of the cache's keys.
1034
1071
 
@@ -1040,7 +1077,7 @@ class LRUCache(BaseCacheImpl[KT, VT]):
1040
1077
  """
1041
1078
  ...
1042
1079
 
1043
- def values(self) -> typing.Iterable[VT]:
1080
+ def values(self) -> CacheIterator[VT]:
1044
1081
  """
1045
1082
  Returns an ordered iterable of the cache's values.
1046
1083
 
@@ -1265,7 +1302,7 @@ class LFUCache(BaseCacheImpl[KT, VT]):
1265
1302
  """
1266
1303
  ...
1267
1304
 
1268
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
1305
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
1269
1306
  """
1270
1307
  Returns an ordered iterable of the cache's ``(key, value)`` pairs.
1271
1308
 
@@ -1277,7 +1314,7 @@ class LFUCache(BaseCacheImpl[KT, VT]):
1277
1314
  """
1278
1315
  ...
1279
1316
 
1280
- def keys(self) -> typing.Iterable[KT]:
1317
+ def keys(self) -> CacheIterator[KT]:
1281
1318
  """
1282
1319
  Returns an ordered iterable of the cache's keys.
1283
1320
 
@@ -1289,7 +1326,7 @@ class LFUCache(BaseCacheImpl[KT, VT]):
1289
1326
  """
1290
1327
  ...
1291
1328
 
1292
- def values(self) -> typing.Iterable[VT]:
1329
+ def values(self) -> CacheIterator[VT]:
1293
1330
  """
1294
1331
  Returns an ordered iterable of the cache's values.
1295
1332
 
@@ -1301,7 +1338,7 @@ class LFUCache(BaseCacheImpl[KT, VT]):
1301
1338
  """
1302
1339
  ...
1303
1340
 
1304
- def items_with_frequency(self) -> typing.Iterable[typing.Tuple[KT, VT, int]]:
1341
+ def items_with_frequency(self) -> CacheIterator[typing.Tuple[KT, VT, int]]:
1305
1342
  """
1306
1343
  Returns an ordered iterable of the cache's ``(key, value)`` pairs with their
1307
1344
  frequency counter.
@@ -1473,7 +1510,7 @@ class TTLCache(BaseCacheImpl[KT, VT]):
1473
1510
  """
1474
1511
  ...
1475
1512
 
1476
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
1513
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
1477
1514
  """
1478
1515
  Returns an ordered iterable of the cache's ``(key, value)`` pairs.
1479
1516
 
@@ -1485,7 +1522,7 @@ class TTLCache(BaseCacheImpl[KT, VT]):
1485
1522
  """
1486
1523
  ...
1487
1524
 
1488
- def keys(self) -> typing.Iterable[KT]:
1525
+ def keys(self) -> CacheIterator[KT]:
1489
1526
  """
1490
1527
  Returns an ordered iterable of the cache's keys.
1491
1528
 
@@ -1497,7 +1534,7 @@ class TTLCache(BaseCacheImpl[KT, VT]):
1497
1534
  """
1498
1535
  ...
1499
1536
 
1500
- def values(self) -> typing.Iterable[VT]:
1537
+ def values(self) -> CacheIterator[VT]:
1501
1538
  """
1502
1539
  Returns an ordered iterable of the cache's values.
1503
1540
 
@@ -1599,7 +1636,7 @@ class TTLCache(BaseCacheImpl[KT, VT]):
1599
1636
  """
1600
1637
  ...
1601
1638
 
1602
- def items_with_expire(self) -> typing.Iterable[typing.Tuple[KT, VT, float]]:
1639
+ def items_with_expire(self) -> CacheIterator[typing.Tuple[KT, VT, float]]:
1603
1640
  """
1604
1641
  Returns an ordered iterable of items with their remaining TTL.
1605
1642
 
@@ -1741,7 +1778,7 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
1741
1778
  KeyError: If the cache is empty.
1742
1779
  """
1743
1780
 
1744
- def items(self) -> typing.Iterable[typing.Tuple[KT, VT]]:
1781
+ def items(self) -> CacheIterator[typing.Tuple[KT, VT]]:
1745
1782
  """
1746
1783
  Returns an ordered iterable of the cache's ``(key, value)`` pairs.
1747
1784
 
@@ -1753,7 +1790,7 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
1753
1790
  """
1754
1791
  ...
1755
1792
 
1756
- def keys(self) -> typing.Iterable[KT]:
1793
+ def keys(self) -> CacheIterator[KT]:
1757
1794
  """
1758
1795
  Returns an ordered iterable of the cache's keys.
1759
1796
 
@@ -1765,7 +1802,7 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
1765
1802
  """
1766
1803
  ...
1767
1804
 
1768
- def values(self) -> typing.Iterable[VT]:
1805
+ def values(self) -> CacheIterator[VT]:
1769
1806
  """
1770
1807
  Returns an ordered iterable of the cache's values.
1771
1808
 
@@ -1838,7 +1875,7 @@ class VTTLCache(BaseCacheImpl[KT, VT]):
1838
1875
  """
1839
1876
  ...
1840
1877
 
1841
- def items_with_expire(self) -> typing.Iterable[typing.Tuple[KT, VT, float | None]]:
1878
+ def items_with_expire(self) -> CacheIterator[typing.Tuple[KT, VT, float | None]]:
1842
1879
  """
1843
1880
  Returns an ordered iterable of items with their remaining TTL.
1844
1881
 
@@ -340,6 +340,24 @@ impl<T> Iterator for RawIter<T> {
340
340
  }
341
341
  }
342
342
  }
343
+
344
+ #[inline]
345
+ fn size_hint(&self) -> (usize, Option<usize>) {
346
+ let left = self.first.len() + self.second.len();
347
+ (left, Some(left))
348
+ }
349
+ }
350
+
351
+ impl<T> ExactSizeIterator for RawIter<T> {}
352
+
353
+ impl<T> Clone for RawIter<T> {
354
+ #[inline]
355
+ fn clone(&self) -> Self {
356
+ Self {
357
+ first: self.first.clone(),
358
+ second: self.second.clone(),
359
+ }
360
+ }
343
361
  }
344
362
 
345
363
  unsafe impl<T: Send + Send> Send for LazyHeap<T> {}
@@ -571,6 +571,17 @@ impl<T> Cursor<T> {
571
571
  unsafe { list.push_front_node(links) };
572
572
  }
573
573
 
574
+ /// Returns `true` if the node this cursor points to is the last node of `list`.
575
+ ///
576
+ /// # Safety
577
+ ///
578
+ /// Same contract as [`move_to_front`](Self::move_to_front).
579
+ #[inline]
580
+ pub unsafe fn is_back(&self, list: &LinkedList<T>) -> bool {
581
+ // SAFETY: the sentinel is always valid; caller guarantees the node is linked.
582
+ unsafe { (*list.sentinel.as_ptr()).prev == self.links().as_ptr() }
583
+ }
584
+
574
585
  /// Moves the node this cursor points to the back of `list`.
575
586
  ///
576
587
  /// # Safety
@@ -640,6 +651,8 @@ impl<T> Iterator for RawIter<T> {
640
651
  }
641
652
  }
642
653
 
654
+ impl<T> ExactSizeIterator for RawIter<T> {}
655
+
643
656
  unsafe impl<T: Send + Send> Send for LinkedList<T> {}
644
657
  unsafe impl<T: Sync + Sync> Sync for LinkedList<T> {}
645
658
  unsafe impl<T: Send + Send> Send for RawIter<T> {}
@@ -476,6 +476,26 @@ impl<T> Iterator for RawSliceIter<T> {
476
476
  Some(value)
477
477
  }
478
478
  }
479
+
480
+ #[inline]
481
+ fn size_hint(&self) -> (usize, Option<usize>) {
482
+ let left = self.len - self.index;
483
+ (left, Some(left))
484
+ }
485
+ }
486
+
487
+ impl<T> ExactSizeIterator for RawSliceIter<T> {}
488
+
489
+ // Cloning gives a second cursor over the same elements; it never touches them.
490
+ impl<T> Clone for RawSliceIter<T> {
491
+ #[inline]
492
+ fn clone(&self) -> Self {
493
+ Self {
494
+ pointer: self.pointer,
495
+ index: self.index,
496
+ len: self.len,
497
+ }
498
+ }
479
499
  }
480
500
 
481
501
  unsafe impl<T: Sync> Send for RawSliceIter<T> {}
@@ -514,4 +534,22 @@ impl<T> Iterator for RawVecDequeIter<T> {
514
534
  }
515
535
  }
516
536
  }
537
+
538
+ #[inline]
539
+ fn size_hint(&self) -> (usize, Option<usize>) {
540
+ let left = self.first.len() + self.second.len();
541
+ (left, Some(left))
542
+ }
543
+ }
544
+
545
+ impl<T> ExactSizeIterator for RawVecDequeIter<T> {}
546
+
547
+ impl<T> Clone for RawVecDequeIter<T> {
548
+ #[inline]
549
+ fn clone(&self) -> Self {
550
+ Self {
551
+ first: self.first.clone(),
552
+ second: self.second.clone(),
553
+ }
554
+ }
517
555
  }
@@ -25,6 +25,33 @@ macro_rules! implement_pyclass {
25
25
  };
26
26
  }
27
27
 
28
+ /// Implements the generation-version guard shared by every cache view type.
29
+ ///
30
+ /// # Example
31
+ ///
32
+ /// ```ignore
33
+ /// implement_view_guard!(PyCacheKeys);
34
+ /// ```
35
+ #[macro_export]
36
+ macro_rules! implement_view_guard {
37
+ ($name:ident) => {
38
+ impl $name {
39
+ /// Fails if the cache changed after this view was created.
40
+ #[inline]
41
+ fn check_generation(&self) -> pyo3::PyResult<()> {
42
+ if self.initial_gv == self.gv.get() {
43
+ return Ok(());
44
+ }
45
+
46
+ Err($crate::new_py_error!(
47
+ PyRuntimeError,
48
+ "cache size changed during iteration"
49
+ ))
50
+ }
51
+ }
52
+ };
53
+ }
54
+
28
55
  /// Creates a new [`PyErr`] of the given exception type.
29
56
  #[macro_export]
30
57
  macro_rules! new_py_error {
@@ -255,6 +255,7 @@ impl PolicyExt for FIFOPolicy {
255
255
  &mut self,
256
256
  py: pyo3::Python,
257
257
  key: &<Self::Handle as HandleExt>::Key,
258
+ _shared: &Self::Shared,
258
259
  ) -> pyo3::PyResult<Option<&Self::Handle>> {
259
260
  let eq = |index: &usize| get_handle!(&self, *index).key().py_eq(py, key);
260
261
  match self.table.get(key.hash(), eq)? {