| """Key functions for memoizing decorators.""" |
| |
| from __future__ import absolute_import |
| |
| __all__ = ('hashkey', 'typedkey') |
| |
| |
| class _HashedTuple(tuple): |
| |
| __hashvalue = None |
| |
| def __hash__(self, hash=tuple.__hash__): |
| hashvalue = self.__hashvalue |
| if hashvalue is None: |
| self.__hashvalue = hashvalue = hash(self) |
| return hashvalue |
| |
| def __add__(self, other, add=tuple.__add__): |
| return _HashedTuple(add(self, other)) |
| |
| def __radd__(self, other, add=tuple.__add__): |
| return _HashedTuple(add(other, self)) |
| |
| _kwmark = (object(),) |
| |
| |
| def hashkey(*args, **kwargs): |
| """Return a cache key for the specified hashable arguments.""" |
| |
| if kwargs: |
| return _HashedTuple(args + sum(sorted(kwargs.items()), _kwmark)) |
| else: |
| return _HashedTuple(args) |
| |
| |
| def typedkey(*args, **kwargs): |
| """Return a typed cache key for the specified hashable arguments.""" |
| |
| key = hashkey(*args, **kwargs) |
| key += tuple(type(v) for v in args) |
| key += tuple(type(v) for _, v in sorted(kwargs.items())) |
| return key |