[Python-3000] Fwd: Conventions for annotation consumers (original) (raw)

Ron Adam rrr at ronadam.com
Sun Aug 20 23:01:46 CEST 2006


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': testskey result = f(*args, **kwds) if 'returns' in tests: tests'returns' 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 """



More information about the Python-3000 mailing list