#!/usr/bin/python
"""
splittable_kwargs allows the splitting of **kwargs arguments among
-several functions. This
+several functions.
-Copyright (C) W. Trevor King 2008
+Copyright (C) W. Trevor King 2008, 2009
This code is released to the public domain.
Example usage (adapted from the unittests)
- @splittableKwargsFunction()
- def foo(x, y, z=2):
- return "foo: x "+str(x)+", y "+str(y)+", z "+str(z)+"\n"
-
- @splittableKwargsFunction()
- def bar(a, b, c=2):
- return "bar: a "+str(a)+", b "+str(b)+", c "+str(c)+"\n"
-
- @splittableKwargsFunction((bar, 'a'))
- def baz(d, **kwargs):
- string = bar(c=4, **kwargs)
- return string + "baz: d "+str(d)+"\n"
-
- @splittableKwargsFunction(foo, bar)
- def simple_joint(**kwargs):
- fookw,bazkw = simple_joint._splitargs(simple_joint, kwargs)
- string = foo(**fookw)
- string += baz(**bazkw)
- return string
-
- simple_joint(y=3,c=1,d=5)
+ >>> from splittable_kwargs import *
+ >>>
+ >>> @splittableKwargsFunction()
+ ... def foo(x, y, z=2):
+ ... return "foo: x "+str(x)+", y "+str(y)+", z "+str(z)+"\\n"
+ ...
+ >>> @splittableKwargsFunction()
+ ... def bar(a, b, c=2):
+ ... return "bar: a "+str(a)+", b "+str(b)+", c "+str(c)+"\\n"
+ >>>
+ >>> @splittableKwargsFunction((bar, 'a'))
+ ... def baz(d, **kwargs):
+ ... string = bar(a=5, c=4, **kwargs)
+ ... return string + "baz: d "+str(d)+"\\n"
+ >>>
+ >>> @splittableKwargsFunction(foo, baz)
+ ... def simple_joint(**kwargs):
+ ... fookw,bazkw = simple_joint._splitargs(simple_joint, kwargs)
+ ... string = foo(**fookw)
+ ... string += baz(**bazkw)
+ ... return string.strip()
+ >>>
+ >>> print simple_joint(x=1,y=3,b=6,d=7)
+ foo: x 1, y 3, z 2
+ bar: a 5, b 6, c 4
+ baz: d 7
If, say, simple_joint's children had not been defined (you wanted to
-define bar after simple_joint in your module), you can skip the
+define baz after simple_joint in your module), you can skip the
decorator in simple_joint, and make it splittable later (after you
-define bar) with
+define baz) with
- make_splittable_kwargs_function(simple_joint, foo, bar)
+ make_splittable_kwargs_function(simple_joint, foo, baz)
+
+You can also get a list of the available named arguments with
+
+ >>> simple_joint._kwargs(simple_joint)
+ ['x', 'y', 'z', 'd', 'b', 'c']
+
+It may seem redundant to need to pass the function (here simple_joint)
+to a method of simple_joint, but remember that simple_joint is a
+_function_, not a class instance. If it really bothers you, try
+something like
+
+ >>> class ClassJoint (object):
+ ... @splittableKwargsFunction(foo, baz)
+ ... def __call__(self, **kwargs):
+ ... fookw,bazkw = simple_joint._splitargs(simple_joint, kwargs)
+ ... string = foo(**fookw)
+ ... string += baz(**bazkw)
+ ... return string.strip()
+ ... def _kwargs(self):
+ ... return self.__call__._kwargs(self.__call__)
+ >>> cj = ClassJoint()
+ >>> print cj(x=1,y=3,b=6,d=7)
+ foo: x 1, y 3, z 2
+ bar: a 5, b 6, c 4
+ baz: d 7
+ >>> cj._kwargs()
+ ['self', 'x', 'y', 'z', 'd', 'b', 'c']
"""
import inspect
+import doctest
import unittest
+VERSION = "0.2"
+
class UnknownKwarg (KeyError):
def __init__(self, fn, kwarg, value):
if hasattr(fn, "_kwargs"):
child,masked = _parse_splittable(child)
child_args = child._kwargs(child)
for arg in masked:
- child_args.remove(arg)
+ try:
+ child_args.remove(arg)
+ except ValueError, e:
+ msg = "%s not in %s" % (arg, child_args)
+ raise ValueError(msg)
args.extend(child_args)
return args
unitsuite = unittest.TestLoader().loadTestsFromTestCase( \
SplittableKwargsTestCase)
+ unitsuite.addTest(doctest.DocTestSuite())
result = unittest.TextTestRunner(verbosity=2).run(unitsuite)
numErrors = len(result.errors)
numFailures = len(result.failures)