Skip to content

Commit 4bcb8a3

Browse files
committed
Update changelog, readme; Fix __repr__
1 parent 022f875 commit 4bcb8a3

File tree

3 files changed

+146
-14
lines changed

3 files changed

+146
-14
lines changed

CHANGELOG.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## v5.0.0 - Unreleased
9-
### Targets:
10-
- Update `hashbrown` dependency
11-
- Make 2x faster by changing my *`isize` to `u64` strategy* in Rust.
12-
- Rewrite cache classes API in Python; this help users to use classes as subclass and customize them.
13-
- Make benchmarks better
14-
- Make error handlings better
9+
### Added
10+
- A new method named `random_key` added to `RRCache`.
11+
- A new method named `expire` added to `TTLCache`.
12+
- Some new methods added to `VTTLCache`: `expire`, `items_with_expire`.
13+
- `TTLCache` now supports `timedelta` as ttl.
14+
- `VTTLCache` now supports `timedelta` and `datetime` as ttl.
15+
- A new method `copy` added to all caches.
16+
17+
### Changed
18+
- The core codes (rust code) renamed from `_cachebox` to `_core`. Instead of that, all of classes
19+
implemented in Python which are using the core's classes. This change can help to customize the alghoritms.
20+
- Now the errors which occurred while doing `__eq__` operations will not be ignored.
21+
- Docstrings is now more complete.
22+
- The strictness in `__eq__` methods was reduced.
23+
- Add more strictness for loading pickle objects.
24+
- `LFUCache` now uses `VecDeque` instead of `Vec` (improves performance).
25+
- The `CacheInfo.cachememory` renamed to `CacheInfo.memory`.
26+
- *`isize` to `u64` strategy* changed in Rust.
27+
- `__repr__` methods refactored.
28+
29+
### Removed
30+
- The `n` parameter of the `LRUCache.least_recently_used` method has been removed.
31+
- The deprecated `always_copy` parameter of the `cached` and `cachedmethod` decorators has been removed.
1532

1633
## 4.5.3 - 2025-03-31
1734
### Changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -840,15 +840,17 @@ assert c.capacity() == loaded.capacity()
840840
* * *
841841

842842
#### How to copy the caches?
843-
Use `copy.deepcopy` or `copy.copy` for copying caches. For example:
843+
You can use `copy.deepcopy` or `cache.copy` for copying caches. For example:
844844
```python
845-
import cachebox, copy
846-
c = cachebox.LRUCache(100, {i:i for i in range(78)})
845+
import cachebox
846+
cache = cachebox.LRUCache(100, {i:i for i in range(78)})
847847

848-
copied = copy.copy(c)
848+
# shallow copy
849+
shallow = cache.copy()
849850

850-
assert c == copied
851-
assert c.capacity() == copied.capacity()
851+
# deep copy
852+
import copy
853+
deep = copy.deepcopy(cache)
852854
```
853855

854856
## License

python/cachebox/_cachebox.py

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from . import _core
22
from ._core import BaseCacheImpl
33
from datetime import timedelta, datetime
4+
import copy as _std_copy
45
import typing
56

67

@@ -11,7 +12,7 @@
1112

1213
def _items_to_str(items, length):
1314
if length <= 50:
14-
return "{" + ", ".join(f"{k}: {v}" for k, v in items) + "}"
15+
return "{" + ", ".join(f"{k!r}: {v!r}" for k, v in items) + "}"
1516

1617
c = 0
1718
left = []
@@ -20,7 +21,7 @@ def _items_to_str(items, length):
2021
k, v = next(items)
2122

2223
if c <= 50:
23-
left.append(f"{k}: {v}")
24+
left.append(f"{k!r}: {v!r}")
2425

2526
else:
2627
break
@@ -251,6 +252,22 @@ def values(self) -> IteratorView[VT]:
251252
"""
252253
return IteratorView(self._raw.items(), lambda x: x[1])
253254

255+
def copy(self) -> "Cache[KT, VT]":
256+
"""Returns a shallow copy of the cache"""
257+
return self.__copy__()
258+
259+
def __copy__(self) -> "Cache[KT, VT]":
260+
cls = type(self)
261+
copied = cls.__new__(cls)
262+
copied._raw = _std_copy.copy(self._raw)
263+
return copied
264+
265+
def __deepcopy__(self, memo) -> "Cache[KT, VT]":
266+
cls = type(self)
267+
copied = cls.__new__(cls)
268+
copied._raw = _std_copy.deepcopy(self._raw, memo)
269+
return copied
270+
254271
def __iter__(self) -> IteratorView[KT]:
255272
return self.keys()
256273

@@ -501,6 +518,22 @@ def last(self) -> typing.Optional[KT]:
501518
"""
502519
return self._raw.get_index(len(self._raw) - 1)
503520

521+
def copy(self) -> "FIFOCache[KT, VT]":
522+
"""Returns a shallow copy of the cache"""
523+
return self.__copy__()
524+
525+
def __copy__(self) -> "FIFOCache[KT, VT]":
526+
cls = type(self)
527+
copied = cls.__new__(cls)
528+
copied._raw = _std_copy.copy(self._raw)
529+
return copied
530+
531+
def __deepcopy__(self, memo) -> "FIFOCache[KT, VT]":
532+
cls = type(self)
533+
copied = cls.__new__(cls)
534+
copied._raw = _std_copy.deepcopy(self._raw, memo)
535+
return copied
536+
504537
def __iter__(self) -> IteratorView[KT]:
505538
return self.keys()
506539

@@ -739,6 +772,22 @@ def values(self) -> IteratorView[VT]:
739772
"""
740773
return IteratorView(self._raw.items(), lambda x: x[1])
741774

775+
def copy(self) -> "RRCache[KT, VT]":
776+
"""Returns a shallow copy of the cache"""
777+
return self.__copy__()
778+
779+
def __copy__(self) -> "RRCache[KT, VT]":
780+
cls = type(self)
781+
copied = cls.__new__(cls)
782+
copied._raw = _std_copy.copy(self._raw)
783+
return copied
784+
785+
def __deepcopy__(self, memo) -> "RRCache[KT, VT]":
786+
cls = type(self)
787+
copied = cls.__new__(cls)
788+
copied._raw = _std_copy.deepcopy(self._raw, memo)
789+
return copied
790+
742791
def __iter__(self) -> IteratorView[KT]:
743792
return self.keys()
744793

@@ -995,6 +1044,22 @@ def most_recently_used(self) -> typing.Optional[KT]:
9951044
"""
9961045
return self._raw.most_recently_used()
9971046

1047+
def copy(self) -> "LRUCache[KT, VT]":
1048+
"""Returns a shallow copy of the cache"""
1049+
return self.__copy__()
1050+
1051+
def __copy__(self) -> "LRUCache[KT, VT]":
1052+
cls = type(self)
1053+
copied = cls.__new__(cls)
1054+
copied._raw = _std_copy.copy(self._raw)
1055+
return copied
1056+
1057+
def __deepcopy__(self, memo) -> "LRUCache[KT, VT]":
1058+
cls = type(self)
1059+
copied = cls.__new__(cls)
1060+
copied._raw = _std_copy.deepcopy(self._raw, memo)
1061+
return copied
1062+
9981063
def __iter__(self) -> IteratorView[KT]:
9991064
return self.keys()
10001065

@@ -1264,6 +1329,22 @@ def least_frequently_used(self, n: int = 0) -> typing.Optional[KT]:
12641329

12651330
return self._raw.least_frequently_used(n)
12661331

1332+
def copy(self) -> "LFUCache[KT, VT]":
1333+
"""Returns a shallow copy of the cache"""
1334+
return self.__copy__()
1335+
1336+
def __copy__(self) -> "LFUCache[KT, VT]":
1337+
cls = type(self)
1338+
copied = cls.__new__(cls)
1339+
copied._raw = _std_copy.copy(self._raw)
1340+
return copied
1341+
1342+
def __deepcopy__(self, memo) -> "LFUCache[KT, VT]":
1343+
cls = type(self)
1344+
copied = cls.__new__(cls)
1345+
copied._raw = _std_copy.deepcopy(self._raw, memo)
1346+
return copied
1347+
12671348
def __iter__(self) -> IteratorView[KT]:
12681349
return self.keys()
12691350

@@ -1605,6 +1686,22 @@ def expire(self) -> None: # pragma: no cover
16051686
"""
16061687
self._raw.expire()
16071688

1689+
def copy(self) -> "TTLCache[KT, VT]":
1690+
"""Returns a shallow copy of the cache"""
1691+
return self.__copy__()
1692+
1693+
def __copy__(self) -> "TTLCache[KT, VT]":
1694+
cls = type(self)
1695+
copied = cls.__new__(cls)
1696+
copied._raw = _std_copy.copy(self._raw)
1697+
return copied
1698+
1699+
def __deepcopy__(self, memo) -> "TTLCache[KT, VT]":
1700+
cls = type(self)
1701+
copied = cls.__new__(cls)
1702+
copied._raw = _std_copy.deepcopy(self._raw, memo)
1703+
return copied
1704+
16081705
def __iter__(self) -> IteratorView[KT]:
16091706
return self.keys()
16101707

@@ -1982,6 +2079,22 @@ def expire(self) -> None: # pragma: no cover
19822079
"""
19832080
self._raw.expire()
19842081

2082+
def copy(self) -> "VTTLCache[KT, VT]":
2083+
"""Returns a shallow copy of the cache"""
2084+
return self.__copy__()
2085+
2086+
def __copy__(self) -> "VTTLCache[KT, VT]":
2087+
cls = type(self)
2088+
copied = cls.__new__(cls)
2089+
copied._raw = _std_copy.copy(self._raw)
2090+
return copied
2091+
2092+
def __deepcopy__(self, memo) -> "VTTLCache[KT, VT]":
2093+
cls = type(self)
2094+
copied = cls.__new__(cls)
2095+
copied._raw = _std_copy.deepcopy(self._raw, memo)
2096+
return copied
2097+
19852098
def __iter__(self) -> IteratorView[KT]:
19862099
return self.keys()
19872100

0 commit comments

Comments
 (0)