summaryrefslogtreecommitdiff
path: root/Lib/inspect.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py9
1 files changed, 6 insertions, 3 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 9c072eb074..9a843d6420 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -505,13 +505,16 @@ def unwrap(func, *, stop=None):
def _is_wrapper(f):
return hasattr(f, '__wrapped__') and not stop(f)
f = func # remember the original func for error reporting
- memo = {id(f)} # Memoise by id to tolerate non-hashable objects
+ # Memoise by id to tolerate non-hashable objects, but store objects to
+ # ensure they aren't destroyed, which would allow their IDs to be reused.
+ memo = {id(f): f}
+ recursion_limit = sys.getrecursionlimit()
while _is_wrapper(func):
func = func.__wrapped__
id_func = id(func)
- if id_func in memo:
+ if (id_func in memo) or (len(memo) >= recursion_limit):
raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
- memo.add(id_func)
+ memo[id_func] = func
return func
# -------------------------------------------------- source code extraction