# HG changeset patch # User Damien Correia # Date 1526635942 -7200 # Node ID 24d96b180e55d41885169ba3409bc276308e78a6 # Parent ecccb445b517ae756665cb33c82971d3685c04ca# Parent 9fe970c45c7b2d239d4c92fb363acec5d4389066 merge default diff -r ecccb445b517 -r 24d96b180e55 src/pyams_utils/adapter.py --- a/src/pyams_utils/adapter.py Wed May 16 14:05:38 2018 +0200 +++ b/src/pyams_utils/adapter.py Fri May 18 11:32:22 2018 +0200 @@ -28,9 +28,13 @@ import venusian # import interfaces +from zope.annotation.interfaces import IAnnotations # import packages -from zope.interface import implementedBy +from pyams_utils.registry import get_current_registry +from zope.interface import implementedBy, alsoProvides +from zope.lifecycleevent import ObjectCreatedEvent +from zope.location import locate as zope_locate class ContextAdapter(object): @@ -125,3 +129,34 @@ settings['_info'] = info.codeinfo # fbo "action_method" return wrapped + + +def get_annotation_adapter(context, key, factory, markers=None, notify=True, + locate=True, parent=None, name=None): + """Get an adapter via object's annotations, creating it if not existent + + :param object context: context object which should be adapted + :param str key: annotations key to look for + :param factory: if annotations key is not found, this is the factory which will be used to + create a new object + :param markers: if not None, list of marker interfaces which created adapter should provide + :param bool notify: if 'False', no notification event will be sent on object creation + :param bool locate: if 'False', the new object is not attached to any parent + :param object parent: parent to which new object is attached + :param str name: if locate is not False, this is the name with which the new object is attached + to it's parent. + """ + annotations = IAnnotations(context, None) + if annotations is None: + return None + adapter = annotations.get(key) + if adapter is None: + adapter = annotations[key] = factory() + if markers: + for marker in markers: + alsoProvides(adapter, marker) + if notify: + get_current_registry().notify(ObjectCreatedEvent(adapter)) + if locate: + zope_locate(adapter, context if parent is None else parent, name) + return adapter diff -r ecccb445b517 -r 24d96b180e55 src/pyams_utils/doctests/request.txt --- a/src/pyams_utils/doctests/request.txt Wed May 16 14:05:38 2018 +0200 +++ b/src/pyams_utils/doctests/request.txt Fri May 18 11:32:22 2018 +0200 @@ -13,7 +13,7 @@ True >>> request = check_request() >>> request - + If a new request is created "from scratch", it's registry is assigned to global registry: