Skip to content

Commit 26c2659

Browse files
committed
Review comments
1 parent 7cb546e commit 26c2659

File tree

3 files changed

+28
-19
lines changed

3 files changed

+28
-19
lines changed

Doc/library/functools.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ The :mod:`functools` module defines the following functions:
9292
property would execute only once per instance, but it also prevents
9393
concurrent execution on different instances of the same class, causing
9494
unnecessary and excessive serialization of updates. This locking behavior is
95-
deprecated and can be avoided by passing ``lock=False``.
95+
deprecated and will be removed in Python 3.14. It can be avoided by passing
96+
``lock=False``.
9697

9798
With ``lock=False``, ``cached_property`` provides no guarantee that it will
9899
run only once per instance, if accessed in multiple threads. An application
@@ -127,6 +128,10 @@ The :mod:`functools` module defines the following functions:
127128
.. versionchanged:: 3.12
128129
The ``lock`` argument was added.
129130

131+
.. deprecated-removed:: 3.12 3.14
132+
The locking behavior of ``cached_property`` is deprecated and will be
133+
removed in 3.14. Use ``lock=False`` to avoid the deprecated behavior.
134+
130135

131136
.. function:: cmp_to_key(func)
132137

Lib/functools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from reprlib import recursive_repr
2121
from _thread import RLock
2222
from types import GenericAlias
23-
from warnings import warn
2423

2524

2625
################################################################################
@@ -970,13 +969,14 @@ def __init__(self, func=None, *, lock=True):
970969
if func is not None:
971970
self.__doc__ = func.__doc__
972971
if lock:
972+
from warnings import warn
973973
warn("Locking cached_property is deprecated; use @cached_property(lock=False)",
974974
PendingDeprecationWarning, 2)
975975
self.lock = RLock() if lock else None
976976

977977
def __call__(self, func=None):
978978
if self.func is not None:
979-
raise TypeError("'cached_property' object is not callable")
979+
raise TypeError(f"{type(self).__name__!r} object is not callable")
980980
self.func = func
981981
if func is not None:
982982
self.__doc__ = func.__doc__

Lib/test/test_functools.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
import typing
1414
import unittest
1515
import unittest.mock
16+
import warnings
1617
import weakref
1718
import gc
1819
from weakref import proxy
1920
import contextlib
2021
from inspect import Signature
2122

23+
from test.support.warnings_helper import ignore_warnings
2224
from test.support import import_helper
2325
from test.support import threading_helper
2426

@@ -2931,19 +2933,21 @@ def get_cost(self):
29312933
cached_cost = py_functools.cached_property(get_cost, lock=False)
29322934

29332935

2934-
class CachedCostItemWait:
2936+
with warnings.catch_warnings():
2937+
warnings.simplefilter("ignore", category=PendingDeprecationWarning)
2938+
class CachedCostItemWait:
29352939

2936-
def __init__(self, event):
2937-
self._cost = 1
2938-
self.lock = py_functools.RLock()
2939-
self.event = event
2940+
def __init__(self, event):
2941+
self._cost = 1
2942+
self.lock = py_functools.RLock()
2943+
self.event = event
29402944

2941-
@py_functools.cached_property
2942-
def cost(self):
2943-
self.event.wait(1)
2944-
with self.lock:
2945-
self._cost += 1
2946-
return self._cost
2945+
@py_functools.cached_property
2946+
def cost(self):
2947+
self.event.wait(1)
2948+
with self.lock:
2949+
self._cost += 1
2950+
return self._cost
29472951

29482952

29492953
class CachedCostItemWaitNoLock:
@@ -3033,7 +3037,7 @@ def test_object_with_slots(self):
30333037

30343038
def test_immutable_dict(self):
30353039
class MyMeta(type):
3036-
@py_functools.cached_property
3040+
@py_functools.cached_property(lock=False)
30373041
def prop(self):
30383042
return True
30393043

@@ -3050,7 +3054,7 @@ def test_reuse_different_names(self):
30503054
"""Disallow this case because decorated function a would not be cached."""
30513055
with self.assertRaises(RuntimeError) as ctx:
30523056
class ReusedCachedProperty:
3053-
@py_functools.cached_property
3057+
@py_functools.cached_property(lock=False)
30543058
def a(self):
30553059
pass
30563060

@@ -3065,7 +3069,7 @@ def test_reuse_same_name(self):
30653069
"""Reusing a cached_property on different classes under the same name is OK."""
30663070
counter = 0
30673071

3068-
@py_functools.cached_property
3072+
@py_functools.cached_property(lock=False)
30693073
def _cp(_self):
30703074
nonlocal counter
30713075
counter += 1
@@ -3085,7 +3089,7 @@ class B:
30853089
self.assertEqual(a.cp, 1)
30863090

30873091
def test_set_name_not_called(self):
3088-
cp = py_functools.cached_property(lambda s: None)
3092+
cp = py_functools.cached_property(lambda s: None, lock=False)
30893093
class Foo:
30903094
pass
30913095

@@ -3098,7 +3102,7 @@ class Foo:
30983102
Foo().cp
30993103

31003104
def test_call_once_completed(self):
3101-
cp = py_functools.cached_property(lambda s: None)
3105+
cp = py_functools.cached_property(lambda s: None, lock=False)
31023106

31033107
with self.assertRaisesRegex(
31043108
TypeError,

0 commit comments

Comments
 (0)