Skip to content

Commit

Permalink
Merge pull request #1474 from singingwolfboy/invalidate-cached-property
Browse files Browse the repository at this point in the history
Add utils.invalidate_cached_property()
  • Loading branch information
davidism committed Mar 28, 2019
2 parents 86f7bdf + 3dfd292 commit 0b031f4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Expand Up @@ -8,6 +8,8 @@ Unreleased
- Drop support for Python 3.4. (:issue:`1478`)
- Remove code that issued deprecation warnings in version 0.15.
(:issue:`1477`)
- Added ``utils.invalidate_cached_property()`` to invalidate cached
properties. (:pr:`1474`)


Version 0.15.1
Expand Down
2 changes: 2 additions & 0 deletions docs/utils.rst
Expand Up @@ -23,6 +23,8 @@ General Helpers
.. autoclass:: cached_property
:members:

.. autofunction:: invalidate_cached_property

.. autoclass:: environ_property

.. autoclass:: header_property
Expand Down
25 changes: 25 additions & 0 deletions src/werkzeug/utils.py
Expand Up @@ -92,6 +92,31 @@ def __get__(self, obj, type=None):
return value


def invalidate_cached_property(obj, name):
"""Invalidates the cache for a :class:`cached_property`:
>>> class Test(object):
... @cached_property
... def magic_number(self):
... print("recalculating...")
... return 42
...
>>> var = Test()
>>> var.magic_number
recalculating...
42
>>> var.magic_number
42
>>> invalidate_cached_property(var, "magic_number")
>>> var.magic_number
recalculating...
42
You must pass the name of the cached property as the second argument.
"""
obj.__dict__[name] = _missing


class environ_property(_DictAccessorProperty):
"""Maps request attributes to environment variables. This works not only
for the Werzeug request object, but also any other class with an
Expand Down
26 changes: 26 additions & 0 deletions tests/test_utils.py
Expand Up @@ -105,6 +105,32 @@ def _prop(self):
assert a._prop == "value"


def test_can_invalidate_cached_property():
foo = []

class A(object):
def prop(self):
foo.append(42)
return 42

prop = utils.cached_property(prop)

a = A()
p = a.prop
q = a.prop
assert p == q == 42
assert foo == [42]

utils.invalidate_cached_property(a, "prop")
r = a.prop
assert r == 42
assert foo == [42, 42]

s = a.prop
assert s == 42
assert foo == [42, 42]


def test_inspect_treats_cached_property_as_property():
class A(object):
@utils.cached_property
Expand Down

0 comments on commit 0b031f4

Please sign in to comment.