Skip to content

Commit ee9ef57

Browse files
committed
improve NO_VALUE and CacheRegion.get()
Fixed the return type for :meth:`.CacheRegion.get`, which was inadvertently hardcoded to use ``CacheReturnType`` that only resolved to ``CachedValue`` or ``NoValue``. Fixed to return ``ValuePayload`` which resolves to ``Any``, as well as a new literal indicating an enum constant for :data:`.api.NO_VALUE`. The :data:`.api.NO_VALUE` constant remains available as the single element of this enum. References: 074cb77#r141358374 Change-Id: I5755736da6d2529c77edc29a0dafe3e67bc419e5
1 parent cd3ec37 commit ee9ef57

File tree

5 files changed

+31
-14
lines changed

5 files changed

+31
-14
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. change::
2+
:tags: bug, typing
3+
4+
Fixed the return type for :meth:`.CacheRegion.get`, which was inadvertently
5+
hardcoded to use ``CacheReturnType`` that only resolved to ``CachedValue``
6+
or ``NoValue``. Fixed to return ``ValuePayload`` which resolves to
7+
``Any``, as well as a new literal indicating an enum constant for
8+
:data:`.api.NO_VALUE`. The :data:`.api.NO_VALUE` constant remains
9+
available as the single element of this enum.

dogpile/cache/api.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from __future__ import annotations
22

33
import abc
4+
import enum
45
import pickle
56
import time
67
from typing import Any
78
from typing import Callable
89
from typing import cast
10+
from typing import Literal
911
from typing import Mapping
1012
from typing import NamedTuple
1113
from typing import Optional
@@ -15,7 +17,7 @@
1517
from ..util.typing import Self
1618

1719

18-
class NoValue:
20+
class NoValue(enum.Enum):
1921
"""Describe a missing cache value.
2022
2123
The :data:`.NO_VALUE` constant should be used.
@@ -33,12 +35,16 @@ def __repr__(self):
3335
"""
3436
return "<dogpile.cache.api.NoValue object>"
3537

36-
def __bool__(self): # pragma NO COVERAGE
38+
def __bool__(self) -> Literal[False]: # pragma NO COVERAGE
3739
return False
3840

41+
NO_VALUE = "NoValue"
3942

40-
NO_VALUE = NoValue()
41-
"""Value returned from ``get()`` that describes
43+
44+
NoValueType = Literal[NoValue.NO_VALUE]
45+
46+
NO_VALUE = NoValue.NO_VALUE
47+
"""Value returned from :meth:`.CacheRegion.get` that describes
4248
a key not present."""
4349

4450
MetaDataType = Mapping[str, Any]
@@ -160,13 +166,13 @@ def age(self) -> float:
160166
return time.time() - self.cached_time
161167

162168

163-
CacheReturnType = Union[CachedValue, NoValue]
169+
CacheReturnType = Union[CachedValue, NoValueType]
164170
"""The non-serialized form of what may be returned from a backend
165171
get method.
166172
167173
"""
168174

169-
SerializedReturnType = Union[bytes, NoValue]
175+
SerializedReturnType = Union[bytes, NoValueType]
170176
"""the serialized form of what may be returned from a backend get method."""
171177

172178
BackendFormatted = Union[CacheReturnType, SerializedReturnType]

dogpile/cache/region.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from .api import KeyType
3333
from .api import MetaDataType
3434
from .api import NO_VALUE
35+
from .api import NoValueType
3536
from .api import SerializedReturnType
3637
from .api import Serializer
3738
from .api import ValuePayload
@@ -706,19 +707,20 @@ def get(
706707
key: KeyType,
707708
expiration_time: Optional[float] = None,
708709
ignore_expiration: bool = False,
709-
) -> CacheReturnType:
710+
) -> Union[ValuePayload, NoValueType]:
710711
"""Return a value from the cache, based on the given key.
711712
712713
If the value is not present, the method returns the token
713-
``NO_VALUE``. ``NO_VALUE`` evaluates to False, but is separate from
714-
``None`` to distinguish between a cached value of ``None``.
714+
:data:`.api.NO_VALUE`. :data:`.api.NO_VALUE` evaluates to False, but is
715+
separate from ``None`` to distinguish between a cached value of
716+
``None``.
715717
716718
By default, the configured expiration time of the
717719
:class:`.CacheRegion`, or alternatively the expiration
718720
time supplied by the ``expiration_time`` argument,
719721
is tested against the creation time of the retrieved
720722
value versus the current time (as reported by ``time.time()``).
721-
If stale, the cached value is ignored and the ``NO_VALUE``
723+
If stale, the cached value is ignored and the :data:`.api.NO_VALUE`
722724
token is returned. Passing the flag ``ignore_expiration=True``
723725
bypasses the expiration time check.
724726
@@ -731,7 +733,7 @@ def get(
731733
of the current "invalidation" time as set by
732734
the :meth:`.invalidate` method. If a value is present,
733735
but its creation time is older than the current
734-
invalidation time, the ``NO_VALUE`` token is returned.
736+
invalidation time, the :data:`.api.NO_VALUE` token is returned.
735737
Passing the flag ``ignore_expiration=True`` bypasses
736738
the invalidation time check.
737739
@@ -1083,7 +1085,7 @@ def go():
10831085
return creator(*ca[0], **ca[1])
10841086

10851087
else:
1086-
go = creator
1088+
go = creator # type: ignore
10871089
return acr(self, orig_key, go, mutex)
10881090

10891091
else:

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
enable-extensions = G
33
# E203 is due to https://github.com/PyCQA/pycodestyle/issues/373
44
ignore =
5-
A003,
5+
A003,A005
66
D,
77
E203,E305,E711,E712,E721,E722,E741,
88
N801,N802,N806,

tests/cache/test_region.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def key_mangler(key):
3030

3131
class APITest:
3232
def test_no_value_str(self):
33-
eq_(str(NO_VALUE), "<dogpile.cache.api.NoValue object>")
33+
eq_(str(NO_VALUE), "NoValue.NO_VALUE")
3434

3535

3636
class RegionTest:

0 commit comments

Comments
 (0)