def for_frame(cls, frame, *args): a = enclosing_frame(frame).f_locals addon_key = cls.addon_key(*args) try: return a[addon_key] except KeyError: # Use setdefault() to prevent race conditions ob = a.setdefault(addon_key, type.__call__(cls, None, *args)) # we use a lambda here so that if we are a registry, Python 2.5 # won't consider our method equal to some other registry's method decorate_class(lambda c: ob.__decorate(c), frame=frame) return ob
def callback(frame, name, func, old_locals): assert f is not func # XXX kind, module, locals_, globals_ = frameinfo(frame) context = ParseContext(func, maker, locals_, globals_, lineno) def register_for_class(cls, f=f): _register_rule(f, pred, context, cls) return cls if kind=='class': # 'when()' in class body; defer adding the method decorate_class(register_for_class, frame=frame) else: register_for_class(None) if old_locals.get(name) is f: return f # prevent overwriting if name is the same return func
def replaces(target): """Class decorator to indicate that this service replaces another""" def decorator(cls): if not issubclass(cls, Service): raise TypeError( "context.replaces() can only be used in a context.Service" " subclass") cls.get = staticmethod(target.get) return cls from peak.util.decorators import decorate_class decorate_class(decorator) # Ensure that context.replaces() is used only once per class suite cdict = sys._getframe(1).f_locals if cdict.setdefault('get', target.get) is not target.get: raise ValueError("replaces() must be used only once per class;" " there is already a value for ``get``: %r" % (cdict['get'], ))
def replaces(target): """Class decorator to indicate that this service replaces another""" def decorator(cls): if not issubclass(cls, Service): raise TypeError("context.replaces() can only be used in a context.Service" " subclass") cls.get = staticmethod(target.get) return cls from peak.util.decorators import decorate_class decorate_class(decorator) # Ensure that context.replaces() is used only once per class suite cdict = sys._getframe(1).f_locals if cdict.setdefault("get", target.get) is not target.get: raise ValueError( "replaces() must be used only once per class;" " there is already a value for ``get``: %r" % (cdict["get"],) )
def metadata(*args, **kw): """Declare metadata for containing class and its attributes Usage:: class Foo: binding.metadata(baz, a=b, x=y) is a shortcut for:: class Foo: pass binding.declareMetadata(Foo, baz, a=b, x=y) See 'binding.declareMetadata()' for more details. """ def callback(klass): declareMetadata(klass, *args, **kw) return klass decorators.decorate_class(callback)
def registerMethod(frm, name, value, old_locals): if qualifier is None: func = value else: func = qualifier, value kind, module, locals_, globals_ = frameinfo(frm) if kind == 'class': # 'when()' in class body; defer adding the method def registerClassSpecificMethod(cls): req = strategy.Signature([(strategy.Argument(0), ICriterion(cls))]) self.addMethod(req & cond, func) return cls decorate_class(registerClassSpecificMethod, frame=frm) else: self.addMethod(cond, func) if old_locals.get(name) in (self, self.delegate): return self.delegate return value
def registerMethod(frm,name,value,old_locals): if qualifier is None: func = value else: func = qualifier,value kind,module,locals_,globals_ = frameinfo(frm) if kind=='class': # 'when()' in class body; defer adding the method def registerClassSpecificMethod(cls): req = strategy.Signature( [(strategy.Argument(0),ICriterion(cls))] ) self.addMethod(req & cond, func) return cls decorate_class(registerClassSpecificMethod,frame=frm) else: self.addMethod(cond,func) if old_locals.get(name) in (self,self.delegate): return self.delegate return value
def advise(**kw): kw = kw.copy() frame = _getframe(1) kind, module, caller_locals, caller_globals = frameinfo(frame) if kind=="module": moduleProvides = kw.setdefault('moduleProvides',()) del kw['moduleProvides'] for k in kw: raise TypeError( "Invalid keyword argument for advising modules: %s" % k ) adviseObject(module, provides=moduleProvides ) return elif kind != "class": raise SyntaxError( "protocols.advise() must be called directly in a class or" " module body, not in a function or exec." ) classProvides = kw.setdefault('classProvides',()) classDoesNotProvide = kw.setdefault('classDoesNotProvide',()) instancesProvide = kw.setdefault('instancesProvide',()) instancesDoNotProvide = kw.setdefault('instancesDoNotProvide',()) asAdapterForTypes = kw.setdefault('asAdapterForTypes',()) asAdapterForProtocols = kw.setdefault('asAdapterForProtocols',()) protocolExtends = kw.setdefault('protocolExtends',()) protocolIsSubsetOf = kw.setdefault('protocolIsSubsetOf',()) factoryMethod = kw.setdefault('factoryMethod',None) equivalentProtocols = kw.setdefault('equivalentProtocols',()) map(kw.__delitem__,"classProvides classDoesNotProvide instancesProvide" " instancesDoNotProvide asAdapterForTypes asAdapterForProtocols" " protocolExtends protocolIsSubsetOf factoryMethod equivalentProtocols" .split()) for k in kw: raise TypeError( "Invalid keyword argument for advising classes: %s" % k ) def callback(klass): if classProvides or classDoesNotProvide: adviseObject(klass, provides=classProvides, doesNotProvide=classDoesNotProvide ) if instancesProvide or instancesDoNotProvide: declareImplementation(klass, instancesProvide=instancesProvide, instancesDoNotProvide=instancesDoNotProvide ) if asAdapterForTypes or asAdapterForProtocols: if not instancesProvide: raise TypeError( "When declaring an adapter, you must specify what" " its instances will provide." ) if factoryMethod: factory = getattr(klass,factoryMethod) else: factory = klass declareAdapter(factory, instancesProvide, forTypes=asAdapterForTypes, forProtocols=asAdapterForProtocols ) elif factoryMethod: raise TypeError( "'factoryMethod' is only used when declaring an adapter type" ) if protocolExtends: declareAdapter(NO_ADAPTER_NEEDED, protocolExtends, forProtocols=[klass] ) if protocolIsSubsetOf: declareAdapter(NO_ADAPTER_NEEDED, [klass], forProtocols=protocolIsSubsetOf ) if equivalentProtocols: declareAdapter( NO_ADAPTER_NEEDED, equivalentProtocols, forProtocols=[klass] ) declareAdapter( NO_ADAPTER_NEEDED, [klass], forProtocols=equivalentProtocols ) return klass decorate_class(callback)
def TokenPtrSubclass(kind): def decorator(cls): TokenPtr.subclasses[kind] = cls return cls decorate_class(decorator)
def advise(**kw): kw = kw.copy() frame = _getframe(1) kind, module, caller_locals, caller_globals = frameinfo(frame) if kind == "module": moduleProvides = kw.setdefault('moduleProvides', ()) del kw['moduleProvides'] for k in kw: raise TypeError( "Invalid keyword argument for advising modules: %s" % k) adviseObject(module, provides=moduleProvides) return elif kind != "class": raise SyntaxError( "protocols.advise() must be called directly in a class or" " module body, not in a function or exec.") classProvides = kw.setdefault('classProvides', ()) classDoesNotProvide = kw.setdefault('classDoesNotProvide', ()) instancesProvide = kw.setdefault('instancesProvide', ()) instancesDoNotProvide = kw.setdefault('instancesDoNotProvide', ()) asAdapterForTypes = kw.setdefault('asAdapterForTypes', ()) asAdapterForProtocols = kw.setdefault('asAdapterForProtocols', ()) protocolExtends = kw.setdefault('protocolExtends', ()) protocolIsSubsetOf = kw.setdefault('protocolIsSubsetOf', ()) factoryMethod = kw.setdefault('factoryMethod', None) equivalentProtocols = kw.setdefault('equivalentProtocols', ()) map( kw.__delitem__, "classProvides classDoesNotProvide instancesProvide" " instancesDoNotProvide asAdapterForTypes asAdapterForProtocols" " protocolExtends protocolIsSubsetOf factoryMethod equivalentProtocols" .split()) for k in kw: raise TypeError("Invalid keyword argument for advising classes: %s" % k) def callback(klass): if classProvides or classDoesNotProvide: adviseObject(klass, provides=classProvides, doesNotProvide=classDoesNotProvide) if instancesProvide or instancesDoNotProvide: declareImplementation(klass, instancesProvide=instancesProvide, instancesDoNotProvide=instancesDoNotProvide) if asAdapterForTypes or asAdapterForProtocols: if not instancesProvide: raise TypeError( "When declaring an adapter, you must specify what" " its instances will provide.") if factoryMethod: factory = getattr(klass, factoryMethod) else: factory = klass declareAdapter(factory, instancesProvide, forTypes=asAdapterForTypes, forProtocols=asAdapterForProtocols) elif factoryMethod: raise TypeError( "'factoryMethod' is only used when declaring an adapter type") if protocolExtends: declareAdapter(NO_ADAPTER_NEEDED, protocolExtends, forProtocols=[klass]) if protocolIsSubsetOf: declareAdapter(NO_ADAPTER_NEEDED, [klass], forProtocols=protocolIsSubsetOf) if equivalentProtocols: declareAdapter(NO_ADAPTER_NEEDED, equivalentProtocols, forProtocols=[klass]) declareAdapter(NO_ADAPTER_NEEDED, [klass], forProtocols=equivalentProtocols) return klass decorate_class(callback)
def BaseRbuSubclass(): def decorator(cls): BaseRbu.subclasses.append(cls) return cls decorate_class(decorator)
def addClassAdvisor(callback, depth=2, frame=None): "protocols.advice.addClassAdvisor is deprecated, please use" " peak.util.decorators.decorate_class instead" from warnings import warn warn(addClassAdvisor.__doc__, DeprecationWarning, 2) return decorators.decorate_class(callback, (depth or 0) + 1, frame)
def addClassAdvisor(callback, depth=2,frame=None): "protocols.advice.addClassAdvisor is deprecated, please use" " peak.util.decorators.decorate_class instead" from warnings import warn warn(addClassAdvisor.__doc__, DeprecationWarning, 2) return decorators.decorate_class(callback, (depth or 0)+1, frame)