From d379573e679d8034335336bc52483060f0eed694 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Tue, 17 Jan 2017 17:37:41 +0000 Subject: [PATCH 1/3] Added a function to avoid circular calling of methods (useful when dealing with callbacks) --- glue/utils/decorators.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/glue/utils/decorators.py b/glue/utils/decorators.py index 86d979e8f..0063f6ab3 100644 --- a/glue/utils/decorators.py +++ b/glue/utils/decorators.py @@ -2,7 +2,7 @@ import traceback -__all__ = ['die_on_error'] +__all__ = ['die_on_error', 'avoid_circular'] def die_on_error(msg): @@ -23,3 +23,14 @@ def wrapper(*args, **kwargs): print('=' * 72) return wrapper return decorator + + +def avoid_circular(meth): + def wrapper(self, *args, **kwargs): + if not hasattr(self, '_active_callback') or not self._active_callback: + self._active_callback = True + try: + return meth(self, *args, **kwargs) + finally: + self._active_callback = False + return wrapper From 54d65fde09de864c5533ebe6a3867da88c20c7cf Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Tue, 17 Jan 2017 17:42:42 +0000 Subject: [PATCH 2/3] Added unit test and changelog entry --- CHANGES.md | 3 +++ glue/utils/decorators.py | 6 +++--- glue/utils/tests/test_decorator.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 glue/utils/tests/test_decorator.py diff --git a/CHANGES.md b/CHANGES.md index 31eb47403..185afdc42 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,9 @@ v0.10.0 (unreleased) Finally, ``ComponentID`` objects now hold a reference to the first parent data they are used in. [#1189] +- Added a decorator that can be used to avoid circular calling of methods (can + occur when dealing with callbacks). + v0.9.2 (unreleased) ------------------- diff --git a/glue/utils/decorators.py b/glue/utils/decorators.py index 0063f6ab3..780a796f4 100644 --- a/glue/utils/decorators.py +++ b/glue/utils/decorators.py @@ -27,10 +27,10 @@ def wrapper(*args, **kwargs): def avoid_circular(meth): def wrapper(self, *args, **kwargs): - if not hasattr(self, '_active_callback') or not self._active_callback: - self._active_callback = True + if not hasattr(self, '_in_avoid_circular') or not self._in_avoid_circular: + self._in_avoid_circular = True try: return meth(self, *args, **kwargs) finally: - self._active_callback = False + self._in_avoid_circular = False return wrapper diff --git a/glue/utils/tests/test_decorator.py b/glue/utils/tests/test_decorator.py new file mode 100644 index 000000000..a009cffab --- /dev/null +++ b/glue/utils/tests/test_decorator.py @@ -0,0 +1,19 @@ +from ..decorators import avoid_circular + + +def test_avoid_circular(): + + class CircularCall(object): + + @avoid_circular + def a(self): + self.b() + + @avoid_circular + def b(self): + self.a() + + c = CircularCall() + + # Without avoid_circular, the following causes a recursion error + c.a() From 0a0f7f845bc79ce673519280ddc6c4f603b18e6d Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Tue, 17 Jan 2017 18:54:08 +0000 Subject: [PATCH 3/3] Added PR number in changelog [ci skip] --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 185afdc42..fff8f5bc0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,7 +22,7 @@ v0.10.0 (unreleased) they are used in. [#1189] - Added a decorator that can be used to avoid circular calling of methods (can - occur when dealing with callbacks). + occur when dealing with callbacks). [#1207] v0.9.2 (unreleased) -------------------