Commit fde0203b authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

utils: Add function for partial application of function arguments

The function's code was mostly copied from Python's documentation
and it's equivalent to “functools.partial” in Python 2.5 and above.
Signed-off-by: default avatarMichael Hanselmann <>
Reviewed-by: default avatarIustin Pop <>
parent d4f119bd
......@@ -55,6 +55,11 @@ except ImportError:
import sha
sha1 =
import functools
except ImportError:
functools = None
from ganeti import errors
from ganeti import constants
......@@ -1501,6 +1506,31 @@ def any(seq, pred=bool): # pylint: disable-msg=W0622
return False
# Even though we're using Python's built-in "partial" function if available,
# this one is always defined for testing.
def _partial(func, *args, **keywords): # pylint: disable-msg=W0622
"""Decorator with partial application of arguments and keywords.
This function was copied from Python's documentation.
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
return func(*(args + fargs), **newkeywords) # pylint: disable-msg=W0142
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
if functools is None:
partial = _partial
partial = functools.partial
def SingleWaitForFdCondition(fdobj, event, timeout):
"""Waits for a condition to occur on the socket.
......@@ -1592,5 +1592,32 @@ class TestLineSplitter(unittest.TestCase):
"", "x"])
class TestPartial(testutils.GanetiTestCase):
def test(self):
def _Test(self, fn):
def _TestFunc1(x, power=2):
return x ** power
cubic = fn(_TestFunc1, power=3)
self.assertEqual(cubic(1), 1)
self.assertEqual(cubic(3), 27)
self.assertEqual(cubic(4), 64)
def _TestFunc2(*args, **kwargs):
return (args, kwargs)
self.assertEqualValues(fn(_TestFunc2, "Hello", "World")("Foo"),
(("Hello", "World", "Foo"), {}))
self.assertEqualValues(fn(_TestFunc2, "Hello", xyz=123)("Foo"),
(("Hello", "Foo"), {"xyz": 123}))
self.assertEqualValues(fn(_TestFunc2, xyz=123)("Foo", xyz=999),
(("Foo", ), {"xyz": 999,}))
if __name__ == '__main__':
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment