r47123 - merging forward

hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org Thu, 31 Mar 2016 08:52:55 -0600 (MDT)
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: hawkowl
Date: Thu Mar 31 08:52:51 2016
New Revision: 47123

Added:
   branches/oldstyle-decorator-8244-2/twisted/python/_oldstyle.py
   branches/oldstyle-decorator-8244-2/twisted/test/test_nooldstyle.py
Modified:
   branches/oldstyle-decorator-8244-2/twisted/python/test/test_util.py
   branches/oldstyle-decorator-8244-2/twisted/python/util.py

Log:
merging forward

Modified: branches/oldstyle-decorator-8244-2/twisted/python/test/test_util.py
==============================================================================
--- branches/oldstyle-decorator-8244-2/twisted/python/test/test_util.py	(original)
+++ branches/oldstyle-decorator-8244-2/twisted/python/test/test_util.py	Thu Mar 31 08:52: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: branches/oldstyle-decorator-8244-2/twisted/python/util.py
==============================================================================
--- branches/oldstyle-decorator-8244-2/twisted/python/util.py	(original)
+++ branches/oldstyle-decorator-8244-2/twisted/python/util.py	Thu Mar 31 08:52: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",