def __init__(aspect, name, bases, dct): """Will be called when a aspect class is created Parse the aspects dictionary and generate instructions from it. Undecorated attributes are understood as finalize instructions. >>> class P(Aspect): ... a = Instruction(1) ... b = 2 >>> Instructions(P) [('a', <class 'metachao._instructions.Instruction'>, 1), ('b', <class 'metachao._instructions.overwrite'>, 2)] """ super(AspectMeta, aspect).__init__(name, bases, dct) # Get the aspect's instructions list instructions = Instructions(aspect) # walk the mro, w/o object, gathering/creating instructions for cls in getmro(aspect)[:-1]: for name, item in cls.__dict__.iteritems(): # ignored attributes if name.startswith('__metachao_'): continue if name in ( '__implemented__', '__metaclass__', '__provides__', '__providedBy__', ): continue if name in DICT_KEYS_OF_PLAIN_CLASS: continue if name in instructions: continue # XXX: rethink this # undecorated items are understood as overwrite if not isinstance(item, Instruction): item = overwrite(item) item.__name__ = name item.__parent__ = aspect instructions.append(item)
def __init__(aspect, name, bases, dct): """Will be called when a aspect class is created Parse the aspects dictionary and generate instructions from it. Undecorated attributes are understood as finalize instructions. >>> class P(Aspect): ... a = Instruction(1) ... b = 2 >>> Instructions(P) [('a', <class 'metachao._instructions.Instruction'>, 1), ('b', <class 'metachao._instructions.overwrite'>, 2)] """ super(AspectMeta, aspect).__init__(name, bases, dct) # Get the aspect's instructions list instructions = Instructions(aspect) # walk the mro, w/o object, gathering/creating instructions # XXX: not sure whether that is good for cls in getmro(aspect)[:-1]: for name, item in cls.__dict__.iteritems(): # ignored attributes if name.startswith('_abc_'): continue if name == '__abstractmethods__': continue if name.startswith('__metachao_'): continue if name in ( '__implemented__', '__metaclass__', '__provides__', '__providedBy__', ): continue if name in DICT_KEYS_OF_PLAIN_CLASS: continue if name in instructions: continue # XXX: rethink this # undecorated items are understood as overwrite if not isinstance(item, Instruction): item = overwrite(item) item.__name__ = name item.__parent__ = aspect instructions.append(item) # for (every) aspectkw we need to plumb __init__ aspectkws = dict([(x.key, x) for x in instructions if isinstance(x, aspectkw)]) if aspectkws: @plumb def __init__(_next, self, *args, **kw): for k in kw.keys(): if k not in aspectkws: continue value = kw.pop(k) akw = aspectkws[k] if value is not akw.item: setattr(self, akw.name, value) _next(*args, **kw) __init__.__name__ = '__init__' __init__.__parent__ = aspect instructions.append(__init__)
def parse_aspect(aspect): config = dict() instructions = dict() seen = list() children = dict() # walk the mro, w/o object, gathering/creating instructions # XXX: not sure whether that is good # XXX: why doesn't getmembers do the job? for cls in getmro(aspect)[:-1]: for name, item in cls.__dict__.iteritems(): # ignored attributes if name.startswith('_abc_'): continue if name == '__abstractmethods__': continue if name.startswith('__metachao_'): continue if name in ( '__implemented__', '__metaclass__', '__provides__', '__providedBy__', ): continue if name in DICT_KEYS_OF_PLAIN_CLASS: continue if name in seen: continue seen.append(name) if isinstance(item, child_instruction): key = getattr(item, 'key', name) children[key] = item continue # undecorated items are understood as overwrite if isinstance(item, Instruction): instruction = item else: instruction = overwrite(item) instruction.name = name instruction.parent = cls instructions[name] = instruction if isinstance(instruction, config_instruction): config[instruction.key] = instruction if children: for name, instr in child_instruction.instructions( aspect, children).items(): if name in instructions: instr = instr.compose(instructions[name]) instructions[name] = instr aspectkws = config if aspectkws: @plumb def __init__(_next, self, *args, **kw): for k in kw.keys(): if k not in aspectkws: continue value = kw.pop(k) akw = aspectkws[k] if value is not akw.item: setattr(self, akw.name, value) _next(*args, **kw) __init__.name = '__init__' __init__.parent = aspect if '__init__' in instructions: __init__ = __init__.compose(instructions['__init__']) instructions['__init__'] = __init__ return (config, instructions)