memoize
memoize copied to clipboard
`str` keys are inconsistent and unpredictable
__str__
methods are not meant to be unique and should not be used to determine equality of objects. Currently cache keys are generated with str
function which uses __str__
methods of objects. This problem may lead to duplicate method calls or incorrectly cached results.
For example, let's consider the dict
type from Python Standard Library.
>>> x = {"a": "1", "b": "2"}
>>> y = {"b": "2", "a": "1"}
>>> x == y
True
>>> str(x) == str(y)
False
These two objects are equal but their string representations are different. Therefore, they will not be memoized by the library.
For another example, let's say that we have the following class:
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return str(f"MyClass(x={self.x})")
In this case, cache is not stable and will return incorrect results.
>>> x = MyClass("1", "1")
>>> y = MyClass("1", "555")
>>> x == y
False
>>> str(x) == str(y)
True
I think the default KeyExtractor
s provided by the library should not have this unstable behavior. As a workaround, I created a custom KeyExtractor
and returned the arguments themselves in format_key
method (by not complying to the str
return type hinting).
I'd appreciate suggestions for a better default KeyExtractor
. The current one (based on str
) is far from foolproof, and I'm unsure about what would truly be foolproof.
Alternatively, perhaps there shouldn't be a default KeyExtractor
, forcing the user to make an informed decision on how to implement keys? However, this approach might make usages more verbose (even in scenarios where str
would work just fine)
closed due to inactivity