Method/Function Signature Type checking

Seo Sanghyeon unendliche at hanmail.net
Wed Aug 14 08:14:53 CEST 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