Welcome, guest | Sign In | My Account | Store | Cart

Here is how to use the new decorator feature of python 2.4 to systematically check the argument types for type-sensitive functions.

Python, 54 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def require(*types):
    '''
    Return a decorator function that requires specified types.
    types -- tuple each element of which is a type or class or a tuple of
             several types or classes.
    Example to require a string then a numeric argument
    @require(str, (int, long, float))

    will do the trick
    '''
    def deco(func):
        '''
        Decorator function to be returned from require().  Returns a function
        wrapper that validates argument types.
        '''
        def wrapper (*args):
            '''
            Function wrapper that checks argument types.
            '''
            assert len(args) == len(types), 'Wrong number of arguments.'
            for a, t in zip(args, types):
                if type(t) == type(()):
                    # any of these types are ok
                    assert sum(isinstance(a, tp) for tp in t) > 0, '''\
%s is not a valid type.  Valid types:
%s
''' % (a, '\n'.join(str(x) for x in t))
                assert isinstance(a, t), '%s is not a %s type' % (a, t)
            return func(*args)
        return wrapper
    return deco

@require(int)
def inter(int_val):
    print 'int_val is ', int_val

@require(float)
def floater(f_val):
    print 'f_val is ', f_val

@require(str, (int, long, float))
def nameAge1(name, age):
    print '%s is %s years old' % (name, age)

# another way to do the same thing
number = (int, float, long)
@require(str, number)
def nameAge2(name, age):
    print '%s is %s years old' % (name, age)

nameAge1('Emily', 8)       # str, int ok
nameAge1('Elizabeth', 4.5) # str, float ok
nameAge2('Romita', 9L)     # str, long ok
nameAge2('Emily', 'eight') # raises an exception!

Sometimes it may necessary to validate the argument types for a certain function. This recipe accomplishes that goal with a minimum amount of hassle. Groupings of allowable types such as “number” = int or float or long are defined as tuples.

This is an extension of an example presented by A.M. Kuchling in his great “What’s New in Python2.4” page.

Created by Justin Shaw on Sun, 5 Dec 2004 (PSF)
Python recipes (4591)
Justin Shaw's recipes (11)

Required Modules

  • (none specified)

Other Information and Tasks