r47126 - Merge oldstyle-decorator-8244-2: Add a decorator which optionally updates old-style classes to new-ones
hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org Thu, 31 Mar 2016 09:39:57 -0600 (MDT)
| Newsgroups | gmane.comp.python.twisted.commits |
|---|---|
| Message-ID | <[email protected]> |
Author: hawkowl
Date: Thu Mar 31 09:39:51 2016
New Revision: 47126
Added:
trunk/twisted/python/_oldstyle.py
trunk/twisted/test/test_nooldstyle.py
trunk/twisted/topfiles/8244.misc
Modified:
trunk/twisted/python/dist3.py
trunk/twisted/python/test/test_util.py
trunk/twisted/python/util.py
Log:
Merge oldstyle-decorator-8244-2: Add a decorator which optionally updates old-style classes to new-ones
Author: hawkowl
Reviewer: glyph
Fixes: #8244
Modified: trunk/twisted/python/dist3.py
==============================================================================
--- trunk/twisted/python/dist3.py (original)
+++ trunk/twisted/python/dist3.py Thu Mar 31 09:39:51 2016
@@ -163,6 +163,7 @@
"twisted.python.__init__",
"twisted.python._appdirs",
"twisted.python._tzhelper",
+ "twisted.python._oldstyle",
"twisted.python._url",
"twisted.python.compat",
"twisted.python.components",
@@ -359,9 +360,10 @@
"twisted.test.test_loopback",
"twisted.test.test_modules",
"twisted.test.test_monkey",
+ "twisted.test.test_nooldstyle",
"twisted.test.test_paths",
- "twisted.test.test_plugin",
"twisted.test.test_persisted",
+ "twisted.test.test_plugin",
"twisted.test.test_policies",
"twisted.test.test_process",
"twisted.test.test_randbytes",
@@ -378,8 +380,8 @@
"twisted.test.test_threadable",
"twisted.test.test_threadpool",
"twisted.test.test_threads",
- "twisted.test.test_twisted",
"twisted.test.test_twistd",
+ "twisted.test.test_twisted",
"twisted.test.test_udp",
"twisted.test.test_unix",
"twisted.test.test_usage",
Modified: trunk/twisted/python/test/test_util.py
==============================================================================
--- trunk/twisted/python/test/test_util.py (original)
+++ trunk/twisted/python/test/test_util.py Thu Mar 31 09:39:51 2016
@@ -1117,3 +1117,66 @@
items = []
util.padTo(4, items)
self.assertEqual([], items)
+
+
+
+class ReplaceIfTests(unittest.TestCase):
+ """
+ Tests for L{util._replaceIf}.
+ """
+
+ def test_replacesIfTrue(self):
+ """
+ L{util._replaceIf} swaps out the body of a function if the conditional
+ is C{True}.
+ """
+ @util._replaceIf(True, lambda: "hi")
+ def test():
+ return "bye"
+
+ self.assertEqual(test(), "hi")
+ self.assertEqual(test.__name__, "test")
+ self.assertEqual(test.__module__, "twisted.python.test.test_util")
+
+
+ def test_keepsIfFalse(self):
+ """
+ L{util._replaceIf} keeps the original body of the function if the
+ conditional is C{False}.
+ """
+ @util._replaceIf(False, lambda: "hi")
+ def test():
+ return "bye"
+
+ self.assertEqual(test(), "bye")
+
+
+ def test_multipleReplace(self):
+ """
+ In the case that multiple conditions are true, the first one
+ (to the reader) is chosen by L{util._replaceIf}
+ """
+ @util._replaceIf(True, lambda: "hi")
+ @util._replaceIf(False, lambda: "bar")
+ @util._replaceIf(True, lambda: "baz")
+ def test():
+ return "bye"
+
+ self.assertEqual(test(), "hi")
+
+
+ def test_boolsOnly(self):
+ """
+ L{util._replaceIf}'s condition argument only accepts bools.
+ """
+ with self.assertRaises(ValueError) as e:
+
+ @util._replaceIf("hi", "there")
+ def test():
+ """
+ Some test function.
+ """
+
+ self.assertEqual(e.exception.args[0],
+ ("condition argument to _replaceIf requires a bool, "
+ "not 'hi'"))
Modified: trunk/twisted/python/util.py
==============================================================================
--- trunk/twisted/python/util.py (original)
+++ trunk/twisted/python/util.py Thu Mar 31 09:39:51 2016
@@ -14,6 +14,8 @@
except ImportError:
setgroups = getgroups = None
+from functools import wraps
+
from twisted.python.compat import _PY3, unicode
from twisted.python.versions import Version
from twisted.python.deprecate import deprecatedModuleAttribute
@@ -905,6 +907,37 @@
+def _replaceIf(condition, alternative):
+ """
+ If C{condition}, replace this function with C{alternative}.
+
+ @param condition: A L{bool} which says whether this should be replaced.
+
+ @param alternative: An alternative function that will be swapped in instead
+ of the original, if C{condition} is truthy.
+
+ @return: A decorator.
+ """
+ def decorator(func):
+
+ if condition is True:
+ call = alternative
+ elif condition is False:
+ call = func
+ else:
+ raise ValueError(("condition argument to _replaceIf requires a "
+ "bool, not {}").format(repr(condition)))
+
+ @wraps(func)
+ def wrapped(*args, **kwargs):
+ return call(*args, **kwargs)
+
+ return wrapped
+
+ return decorator
+
+
+
__all__ = [
"uniquify", "padTo", "getPluginDirs", "addPluginDir", "sibpath",
"getPassword", "println", "makeStatBar", "OrderedDict",