Skip to content

Commit

Permalink
Merge pull request #7 from zopefoundation/cachedin-preserve-doc
Browse files Browse the repository at this point in the history
method.cachedIn preserves __doc__, etc
  • Loading branch information
jamadden committed Sep 2, 2016
2 parents c3ec1f2 + 02ec91c commit b706ce1
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Changes
- ``property.CachedProperty`` is usable as a decorator, with or
without dependent attribute names.

- ``method.cachedIn`` preserves the documentation string of the
underlying function, and everything else that ``functools.wraps`` preserves.

4.1.0 (2014-12-26)
------------------

Expand Down
6 changes: 5 additions & 1 deletion src/zope/cachedescriptors/method.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
##############################################################################
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Expand All @@ -12,6 +12,9 @@
"""Cached Methods
"""

from functools import wraps


class cachedIn(object):
"""Cached method with given cache attribute."""

Expand All @@ -21,6 +24,7 @@ def __init__(self, attribute_name, factory=dict):

def __call__(self, func):

@wraps(func)
def decorated(instance, *args, **kwargs):
cache = self.cache(instance)
key = self._get_cache_key(*args, **kwargs)
Expand Down
21 changes: 17 additions & 4 deletions src/zope/cachedescriptors/method.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ computed value:
>>> from zope.cachedescriptors import method

>>> class Point(object):
...
...
... def __init__(self, x, y):
... self.x, self.y = x, y
...
... @method.cachedIn('_cache')
... def distance(self, x, y):
... """Compute the distance"""
... print('computing distance')
... return math.hypot(self.x - x, self.y - y)
...
>>> point = Point(1.0, 2.0)
>>> point = Point(1.0, 2.0)

The value is computed once:

Expand Down Expand Up @@ -60,6 +61,18 @@ Invalidating keys which are not in the cache, does not result in an error:

>>> point.distance.invalidate(point, 47, 11)

The documentation of the function is preserved (whether through the
instance or the class), allowing Sphinx to extract it::

>>> print(point.distance.__doc__)
Compute the distance
>>> print(point.distance.__name__)
distance

>>> print(Point.distance.__doc__)
Compute the distance
>>> print(Point.distance.__name__)
distance

It is possible to pass in a factory for the cache attribute. Create another
Point class:
Expand All @@ -68,7 +81,7 @@ Point class:
>>> class MyDict(dict):
... pass
>>> class Point(object):
...
...
... def __init__(self, x, y):
... self.x, self.y = x, y
...
Expand All @@ -77,7 +90,7 @@ Point class:
... print('computing distance')
... return math.sqrt((self.x - x)**2 + (self.y - y)**2)
...
>>> point = Point(1.0, 2.0)
>>> point = Point(1.0, 2.0)
>>> point.distance(2, 2)
computing distance
1.0
Expand Down
1 change: 1 addition & 0 deletions src/zope/cachedescriptors/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __get__(self, inst, class_):

return value


def CachedProperty(*args):
"""
CachedProperties.
Expand Down

0 comments on commit b706ce1

Please sign in to comment.