#!/usr/bin/python from copy import deepcopy, copy ##### UTILS def flatten(classdict): """ Flattens traits into a class """ if not classdict.has_key("__uses__"): return # Merge traits traits_methods = dict() for trait in classdict["__uses__"]: merge_trait(classdict, traits_methods, trait) # Flatten traits with class for m in traits_methods: if not classdict.has_key(m): classdict[m] = traits_methods[m] def merge_trait(classdict, traits_methods, trait): """ Merge and flatten traits between them """ for m in trait.__dict__: # Don't merge private methods if not m.startswith("__"): # Check if there's a clash between method names if not traits_methods.has_key(m): traits_methods[m] = trait.__dict__[m] else: # If overriden by class user, ignore clash if not classdict.has_key(m): raise TraitsMethodConflictException( "method <" + m + "> clashes, please resolve manually or implement this method in class user." ) ##### EXCEPTIONS class TraitException(Exception): pass class TraitsMethodConflictException(TraitException): pass class TraitsAreStatelessException(TraitException): def __init__(self, msg="You can't put state in traits."): TraitException.__init__(self, msg) ##### METACLASSES class TraitMetaClass(type): #def __setattr__(cls, a, b): # raise TraitsAreStatelessException() def __new__(mcls, clsname, bases, classdict): flatten(classdict) return type.__new__(mcls, clsname, bases, classdict) def alias(cls, aliases): newcls = type(cls)("TraitMetaClass", (type,), {}) # Add current class methods for name, selector in cls.__dict__.items(): setattr(newcls, name, selector) # remove old methods, create aliases for alias, target in aliases.items(): method = newcls.__dict__[target] delattr(newcls, target) setattr(newcls, alias, method) return newcls class TraitUserMetaClass(type): def __new__(mcls, clsname, bases, classdict): flatten(classdict) return type.__new__(mcls, clsname, bases, classdict) #### CLASSES class Trait(object): __metaclass__ = TraitMetaClass def __new__(self): raise Exception("Can't instanciate trait class") class TraitUser(object): __metaclass__ = TraitUserMetaClass