Method/Function Signature Type checking
Seo Sanghyeon
unendliche at hanmail.net
Wed Aug 14 02:14:53 EDT 2002
Is this what you want?
----
# typecheck.py
import re
def typecheck(function):
typeline = re.compile(
r'\s*(?P<var>@|\w+)\s*::\s*(?P<type>\w+(?:,\s*\w+)*)\s*$')
typesigns = function.func_doc.split('\n')
typesigns = filter(None, map(typeline.match, typesigns))
typesigns = dict([ (typesign.group('var'), typesign.group('type'))
for typesign in typesigns ])
formal = typesigns['@'] # @ is from NetHack
del typesigns['@']
code = ''
code += 'def it(%s, magic=function):\n'%formal
for var, type in typesigns.items():
code += '\tassert isinstance(%s, %s), "%s is not of %s"\n'%(
var, type, var, type)
code += '\tmagic(%s)\n'%formal
exec code
return it
class Drinker:
def __init__(self, name):
self.name = name
def drink(self, beverage):
'''
@ :: self, beverage
beverage :: Beverage
'''
print '%s drinks %s liter of %s' % (
self.name, beverage.liter, beverage.name)
class CarelessDrinker(Drinker):
pass
class CarefulDrinker(Drinker):
drink = typecheck(Drinker.drink)
class Beverage:
pass
class Water(Beverage):
name = 'water'
def __init__(self, liter):
self.liter = liter
class Coke(Beverage):
name = 'coke'
def __init__(self, liter):
self.liter = liter
class Petronium:
name = 'petronium'
def __init__(self, liter):
self.liter = liter
effbot = CarelessDrinker('effbot')
timbot = CarefulDrinker('timbot')
glass = Water(1L)
bottle = Coke(2L)
barrel = Petronium(10L)
effbot.drink(glass)
timbot.drink(glass)
effbot.drink(bottle)
timbot.drink(bottle)
effbot.drink(barrel)
timbot.drink(barrel) # Error!
----
Python 2.2.1 (#34, Apr 9 2002, 19:34:33) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
IDLE 0.8 -- press F1 for help
>>>
effbot drinks 1 liter of water
timbot drinks 1 liter of water
effbot drinks 2 liter of coke
timbot drinks 2 liter of coke
effbot drinks 10 liter of petronium
Traceback (most recent call last):
File "C:\Study\Python\typecheck.py", line 70, in ?
timbot.drink(barrel) # Error!
File "<string>", line 2, in it
AssertionError: beverage is not of Beverage
>>> print "There-is-at-least-one-obscure-way-to-do-it-ly y'rs"
There-is-at-least-one-obscure-way-to-do-it-ly y'rs
----
Seo Sanghyeon
More information about the Python-list
mailing list