Make LazyClassProperty / cached_classproperty reusable

This commit is contained in:
Šarūnas Nejus 2024-05-02 12:02:10 +01:00
parent 0e87389994
commit 265e40b14e
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
4 changed files with 23 additions and 21 deletions

View file

@ -39,7 +39,7 @@ from unidecode import unidecode
from beets import config, logging, plugins
from beets.autotag import mb
from beets.library import Item
from beets.util import as_string
from beets.util import as_string, cached_classproperty
log = logging.getLogger("beets")
@ -413,23 +413,6 @@ def string_dist(str1: Optional[str], str2: Optional[str]) -> float:
return base_dist + penalty
class LazyClassProperty:
"""A decorator implementing a read-only property that is *lazy* in
the sense that the getter is only invoked once. Subsequent accesses
through *any* instance use the cached result.
"""
def __init__(self, getter):
self.getter = getter
self.computed = False
def __get__(self, obj, owner):
if not self.computed:
self.value = self.getter(owner)
self.computed = True
return self.value
@total_ordering
class Distance:
"""Keeps track of multiple distance penalties. Provides a single
@ -441,7 +424,7 @@ class Distance:
self._penalties = {}
self.tracks: Dict[TrackInfo, Distance] = {}
@LazyClassProperty
@cached_classproperty
def _weights(cls) -> Dict[str, float]: # noqa: N805
"""A dictionary from keys to floating-point weights."""
weights_view = config["match"]["distance_weights"]

View file

@ -1055,3 +1055,20 @@ def par_map(transform: Callable, items: Iterable):
pool.map(transform, items)
pool.close()
pool.join()
class cached_classproperty: # noqa: N801
"""A decorator implementing a read-only property that is *lazy* in
the sense that the getter is only invoked once. Subsequent accesses
through *any* instance use the cached result.
"""
def __init__(self, getter):
self.getter = getter
self.cache = {}
def __get__(self, instance, owner):
if owner not in self.cache:
self.cache[owner] = self.getter(owner)
return self.cache[owner]

View file

@ -31,7 +31,9 @@ show_contexts = true
min-version = 3.8
accept-encodings = utf-8
max-line-length = 88
docstring-convention = google
classmethod-decorators =
classmethod
cached_classproperty
# errors we ignore; see https://www.flake8rules.com/ for more info
ignore =
# pycodestyle errors

View file

@ -143,7 +143,7 @@ def _clear_weights():
"""Hack around the lazy descriptor used to cache weights for
Distance calculations.
"""
Distance.__dict__["_weights"].computed = False
Distance.__dict__["_weights"].cache = {}
class DistanceTest(_common.TestCase):