Paul Prescod wrote: > I guess I still don't really understand what he's getting at or what the > value of @callmeta is in that example. It just seems like extra noise > with no value to me... > > Ron: what *precisely* does the @callmeta decorator do? If you can > express it in code, so much the better. > > Paul Prescod >
Here's a working example. @callmeta could be named something else like @asserter, @checker, or whatever. And it should do more checks to avoid non callable annotations and to keep from writing over pre existing annotations, etc... As I said this could all be put in a module and it's easy to create new assert tests without having to know about decorators or any special classes. Ron # ----- Some assert test functions. def IsAny(arg): pass def IsNumber(arg): assert type(arg) in (int, long, float), \ "%r is not a number" % arg def IsInt(arg): assert type(arg) in (int, long), \ "%r is not an Int" % arg def IsFloat(arg): assert isinstance(arg, float), \ "%r is not a flaot" % arg def InRange(start, stop): def inrange(arg): assert start <= arg <= stop, \ "%r is not in range %r through %r" % (arg, start, stop) return inrange def InSet(list_): s = set(list_) def inset(arg): assert arg in s, \ "%r is not in %r" % (arg, s) return inset # ------- The add-annotation decorator. def annotate(**kwds): def setter(func): func.__setattr__('__signature__', dict()) func.__signature__['annotations'] = kwds return func return setter # ------ The do-asserts decorator. def callmeta(f): def new_f(*args, **kwds): d = dict(zip(f.func_code.co_varnames, args)) d.update(kwds) tests = f.__signature__['annotations'] for key in d: if key != 'returns': tests[key](d[key]) result = f(*args, **kwds) if 'returns' in tests: tests['returns'](result) return result new_f.func_name = f.func_name return new_f # --------- Examples of using callable annotations. @callmeta @annotate(a=Any, b=IsInt, returns=IsInt) def add(a, b): return a + b print add(1, 4) @callmeta @annotate(a=IsInt, b=IsInt, returns=IsInt) def add(a, b): return a + b print add(1, 4.1) # assertion error here. # which could also be... """ @callmeta def add(a:IsInt, b:IsInt) ->IsInt: return a + b """ _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com