summaryrefslogtreecommitdiff
path: root/numpy/core/_internal.py
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2018-09-17 09:08:42 +0300
committerEric Wieser <wieser.eric@gmail.com>2018-09-16 23:08:42 -0700
commit73d7871970a951edd48e5c40bdc7609385ce61e6 (patch)
tree7e71e96faf55f1d716417c5f057323152d97bbe6 /numpy/core/_internal.py
parentf49c0169f5a62d4bfa62c791e2a4e2b78ddf7517 (diff)
downloadnumpy-73d7871970a951edd48e5c40bdc7609385ce61e6.tar.gz
MAINT: refactor design of recursive closures (#11910)
Diffstat (limited to 'numpy/core/_internal.py')
-rw-r--r--numpy/core/_internal.py34
1 files changed, 33 insertions, 1 deletions
diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py
index 48ede14d0..9b8f5aef3 100644
--- a/numpy/core/_internal.py
+++ b/numpy/core/_internal.py
@@ -1,5 +1,5 @@
"""
-A place for code to be called from core C-code.
+A place for internal code
Some things are more easily handled Python.
@@ -808,3 +808,35 @@ def _is_from_ctypes(obj):
return 'ctypes' in ctype_base.__module__
except Exception:
return False
+
+
+class recursive(object):
+ '''
+ A decorator class for recursive nested functions.
+ Naive recursive nested functions hold a reference to themselves:
+
+ def outer(*args):
+ def stringify_leaky(arg0, *arg1):
+ if len(arg1) > 0:
+ return stringify_leaky(*arg1) # <- HERE
+ return str(arg0)
+ stringify_leaky(*args)
+
+ This design pattern creates a reference cycle that is difficult for a
+ garbage collector to resolve. The decorator class prevents the
+ cycle by passing the nested function in as an argument `self`:
+
+ def outer(*args):
+ @recursive
+ def stringify(self, arg0, *arg1):
+ if len(arg1) > 0:
+ return self(*arg1)
+ return str(arg0)
+ stringify(*args)
+
+ '''
+ def __init__(self, func):
+ self.func = func
+ def __call__(self, *args, **kwargs):
+ return self.func(self, *args, **kwargs)
+