Skip to content
Merged
Prev Previous commit
Next Next commit
Allow reuse of cached_property as long as name remains the same.
  • Loading branch information
carljm committed Jul 30, 2018
commit b504a20942cc7143958cf6afaabae4b888b393d4
6 changes: 3 additions & 3 deletions Lib/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,10 +887,10 @@ def __init__(self, func):
def __set_name__(self, owner, name):
if self.attrname is None:
self.attrname = name
else:
elif name != self.attrname:
raise TypeError(
"Cannot assign the same cached_property to two names "
f"({self.attrname!r} and {name!r}) on the same class."
"Cannot assign the same cached_property to two different names "
f"({self.attrname!r} and {name!r})."
)

def __get__(self, instance, owner):
Expand Down
27 changes: 25 additions & 2 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2406,7 +2406,7 @@ def test_object_with_slots(self):
):
item.cost

def test_reuse(self):
def test_reuse_different_names(self):
"""Disallow this case because decorated function a would not be cached."""
with self.assertRaises(RuntimeError) as ctx:
class ReusedCachedProperty:
Expand All @@ -2418,9 +2418,32 @@ def a(self):

self.assertEqual(
str(ctx.exception.__context__),
str(TypeError("Cannot assign the same cached_property to two names ('a' and 'b') on the same class."))
str(TypeError("Cannot assign the same cached_property to two different names ('a' and 'b')."))
)

def test_reuse_same_name(self):
"""Reusing a cached_property on different classes under the same name is OK."""
counter = 0

@py_functools.cached_property
def _cp(_self):
nonlocal counter
counter += 1
return counter

class A:
cp = _cp

class B:
cp = _cp

a = A()
b = B()

self.assertEqual(a.cp, 1)
self.assertEqual(b.cp, 2)
self.assertEqual(a.cp, 1)

def test_set_name_not_called(self):
cp = py_functools.cached_property(lambda s: None)
class Foo:
Expand Down