From 8747611e9efe2fdcfe9f21d0e6f910cb2e0bb4c0 Mon Sep 17 00:00:00 2001 From: John Garland Date: Tue, 27 Apr 2010 02:18:16 +1000 Subject: [PATCH] Add decorators module and test file --- deluge/decorators.py | 51 ++++++++++++++++++++++++++++++++++++++++ tests/test_decorators.py | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 deluge/decorators.py create mode 100644 tests/test_decorators.py diff --git a/deluge/decorators.py b/deluge/decorators.py new file mode 100644 index 000000000..0ac2c41ca --- /dev/null +++ b/deluge/decorators.py @@ -0,0 +1,51 @@ +# +# decorators.py +# +# Copyright (C) 2010 John Garland +# +# Deluge is free software. +# +# You may redistribute it and/or modify it under the terms of the +# GNU General Public License, as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# deluge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# +# In addition, as a special exception, the copyright holders give +# permission to link the code of portions of this program with the OpenSSL +# library. +# You must obey the GNU General Public License in all respects for all of +# the code used other than OpenSSL. If you modify file(s) with this +# exception, you may extend this exception to your version of the file(s), +# but you are not obligated to do so. If you do not wish to do so, delete +# this exception statement from your version. If you delete this exception +# statement from all source files in the program, then also delete it here. +# +# + +from functools import wraps + +def proxy(proxy_func): + """ + Factory class which returns a decorator that passes + the decorated function to a proxy function + + :param proxy_func: the proxy function + :type proxy_func: function + """ + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + return proxy_func(func, *args, **kwargs) + return wrapper + return decorator diff --git a/tests/test_decorators.py b/tests/test_decorators.py new file mode 100644 index 000000000..ad9423017 --- /dev/null +++ b/tests/test_decorators.py @@ -0,0 +1,42 @@ +from twisted.trial import unittest + +from deluge.decorators import proxy + +class DecoratorsTestCase(unittest.TestCase): + def test_proxy_with_simple_functions(self): + def negate(func, *args, **kwargs): + return not func(*args, **kwargs) + + @proxy(negate) + def something(bool): + return bool + + @proxy(negate) + @proxy(negate) + def double_nothing(bool): + return bool + + self.assertTrue(something(False)) + self.assertFalse(something(True)) + self.assertTrue(double_nothing(True)) + self.assertFalse(double_nothing(False)) + + def test_proxy_with_class_method(self): + def negate(func, *args, **kwargs): + return -func(*args, **kwargs) + + class Test(object): + def __init__(self, number): + self.number = number + + @proxy(negate) + def diff(self, number): + return self.number - number + + @proxy(negate) + def no_diff(self, number): + return self.diff(number) + + t = Test(5) + self.assertEqual(t.diff(1), -4) + self.assertEqual(t.no_diff(1), 4)