Instantly share code, notes, and snippets.

Embed
What would you like to do?
poor man's contracts
class Entity(object):
def __init__(self, name):
self.name = name
class Powered(object):
def is_on(self):
return self.state == 'on'
class Machine(Entity, Powered):
def __init__(self, name, state):
super(Machine, self).__init__(name)
self.state = state
class Table(Entity):
def __init__(self, name):
super(Table, self).__init__(name)
def check_if_on(what):
if Powered not in type(what).__mro__:
raise Exception( "{} doesn't answer to Powered".format(what))
print 'Check if {} is on.'.format(what.name)
return what.is_on
table = Table('bronzy')
machine = Machine('car', 'on')
check_if_on(machine)
try:
check_if_on(table)
except Exception as e:
print e
# Build a decorator that takes a set of class as a parameter
# then checks one to one with the set of parameters passed to
# the function. The number of interfaces checked against
# must be equal to the number of parameters passed
def contract(*interfaces):
def _contract(function):
def wrapper(*args, **kwargs):
for a, b in zip(interfaces, args):
if a not in type(b).__mro__:
raise Exception(
"{} doesn't answer to {}".format(b, a))
else:
function(*args, **kwargs)
return wrapper
return _contract
# redefine check_if_on
@contract(Powered)
def check_if_on(what):
print 'Check if {} is on.'.format(what.name)
return what.is_on
check_if_on(machine)
try:
check_if_on(table)
except Exception as e:
print e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment