From 3133c0bfce491e52e09250dec3ce7d1fe4176606 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 20 May 2009 13:33:00 -0400 Subject: [PATCH] Added better error handling to _kwargs() and added doctests. The docstring examples were close, and it's not good to get out-of-date. --- splittable_kwargs.py | 94 +++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/splittable_kwargs.py b/splittable_kwargs.py index 732ad37..0d87095 100755 --- a/splittable_kwargs.py +++ b/splittable_kwargs.py @@ -1,46 +1,81 @@ #!/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"): @@ -100,7 +135,11 @@ def _kwargs(self): 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 @@ -247,6 +286,7 @@ if __name__ == "__main__": unitsuite = unittest.TestLoader().loadTestsFromTestCase( \ SplittableKwargsTestCase) + unitsuite.addTest(doctest.DocTestSuite()) result = unittest.TextTestRunner(verbosity=2).run(unitsuite) numErrors = len(result.errors) numFailures = len(result.failures) -- 2.26.2