def make_converter(proto): """Return a function that will convert its argument using <proto> as a prototype. The <proto> is either a type or an instance of a Quantity or a string that can be parsed as a Quantity. """ if proto in (int, float): # simple numerical type def topod(other): return proto(other) return topod if proto == str: # treat string special to instrument some error checking def tostr(other): other = str(other) if other == "": raise ValueError, "Empty string is an illegal value for str" if other is None: raise ValueError, "None is an illegal value for str" return other return tostr if isquantity(proto): return toquantity(proto) # it better be of some type of self-converting prototype def toobj(other): ret = proto(other) return ret return toobj
def validate_input(proto, *args, **kwargs): """Validate the input <args> and <kwargs> against the prototypes in <proto>. <proto> is a list of ("name",object) tuples. <args> is a list of positional arguments assumed to follow the ordering of <proto> but may be of shorter length. <kwargs> is a dictionary of "name"/object pairs supplying any remaining arguments. Any unspecified arguments are given the default from <proto> and no keys in <kwargs> may be given in addition to what are specified in <args>. A an ordered list of values are returned. """ # print 'VALIDATE INPUT', str(proto) members = OrderedDict() converters = dict() for name, pval in proto: c = make_converter(pval) converters[name] = c # print 'CONVERTER:',name,c,pval # set default if isquantity(pval): members[name] = c(pval) elif hasattr(pval, "default"): # print 'SET DEFAULT:',name,pval.default members[name] = pval.default() else: members[name] = None # if isquantity(pval): # pval = toquantity(pval)(pval) # members[name] = pval # converters[name] = make_converter(pval) already = list() for k, v in zip(members.keys(), args): members[k] = converters[k](v) # print 'ARGS:',k,v,members[k] already.append(k) for k, v in kwargs.items(): if k not in converters.keys(): raise ValueError, 'Object "%s" not in prototype' % (k,) if k in already: raise ValueError, "Keyword argument already supplied as positional: %s" % k members[k] = converters[k](v) # print 'KWDS:',k,v,members[k] return members.values()