def load_behavior(_context, behavior): conf = behavior['config'] klass = resolve_dotted_name(behavior['klass']) factory = conf.get('factory') or klass real_factory = resolve_dotted_name(factory) if IInterface.providedBy(real_factory): # create concret class to register for behavior schema = real_factory from guillotina.behaviors.instance import AnnotationBehavior class real_factory(AnnotationBehavior): __annotations_data_key__ = conf.get('data_key', 'default') auto_serialize = conf.get('auto_serialize', True) else: schema = resolve_dotted_name(conf['provides']) classImplements(real_factory, schema) name = conf.get('name') name_only = conf.get('name_only', False) title = conf.get('title', '') for_ = resolve_dotted_name(conf.get('for_')) marker = resolve_dotted_name(conf.get('marker')) if marker is None and real_factory is None: marker = schema if marker is not None and real_factory is None and marker is not schema: raise ConfigurationError( u"You cannot specify a different 'marker' and 'provides' if " u"there is no adapter factory for the provided interface." ) if name_only and name is None: raise ConfigurationError( u"If you decide to only register by 'name', a name must be given." ) # Instantiate the real factory if it's the schema-aware type. We do # this here so that the for_ interface may take this into account. if factory is not None and IBehaviorSchemaAwareFactory.providedBy(factory): factory = factory(schema) registration = BehaviorRegistration( title=conf.get('title', ''), description=conf.get('description', ''), interface=schema, marker=marker, factory=real_factory, name=name, for_=for_ ) if not name_only: # behavior registration by provides interface identifier component.utility( _context, provides=IBehavior, name=schema.__identifier__, component=registration ) if name is not None: # for convinience we register with a given name component.utility( _context, provides=IBehavior, name=name, component=registration ) if factory is None: if for_ is not None: logger.warning( u"Specifying 'for' in behavior '{0}' if no 'factory' is given " u"has no effect and is superfluous.".format(title) ) # w/o factory we're done here return if for_ is None: # Attempt to guess the factory's adapted interface and use it as # the 'for_'. # Fallback to '*' (=Interface). adapts = getattr(factory, '__component_adapts__', None) or [Interface] if len(adapts) != 1: raise ConfigurationError( u"The factory can not be declared as multi-adapter." ) for_ = adapts[0] adapter_factory = BehaviorAdapterFactory(registration) component.adapter( _context, factory=(adapter_factory,), provides=schema, for_=(for_,) )