src/pyams_utils/vocabulary.py
changeset 180 1bb9673c3be1
parent 77 13f3fb3fc4ef
child 292 b338586588ad
--- a/src/pyams_utils/vocabulary.py	Fri May 18 11:17:56 2018 +0200
+++ b/src/pyams_utils/vocabulary.py	Thu May 24 13:54:24 2018 +0200
@@ -17,6 +17,8 @@
 import logging
 logger = logging.getLogger('PyAMS (utils)')
 
+import venusian
+
 # import interfaces
 from zope.schema.interfaces import IVocabularyFactory
 
@@ -64,11 +66,30 @@
                                          required=False)
     """
 
-    def __init__(self, name):
+    venusian = venusian
+
+    def __init__(self, name, **settings):
         self.name = name
+        self.__dict__.update(settings)
+
+    def __call__(self, wrapped):
+        settings = self.__dict__.copy()
+        depth = settings.pop('_depth', 0)
 
-    def __call__(self, klass):
-        logger.debug('Registering class {0} as vocabulary with name "{1}"'.format(str(klass), self.name))
-        directlyProvides(klass, IVocabularyFactory)
-        getVocabularyRegistry().register(self.name, klass)
-        return klass
+        def callback(context, name, ob):
+            logger.debug('Registering class {0} as vocabulary with name "{1}"'.format(str(ob), self.name))
+            directlyProvides(ob, IVocabularyFactory)
+            getVocabularyRegistry().register(self.name, ob)
+
+        info = self.venusian.attach(wrapped, callback, category='pyams_vocabulary',
+                                    depth=depth + 1)
+
+        if info.scope == 'class':
+            # if the decorator was attached to a method in a class, or
+            # otherwise executed at class scope, we need to set an
+            # 'attr' into the settings if one isn't already in there
+            if settings.get('attr') is None:
+                settings['attr'] = wrapped.__name__
+
+        settings['_info'] = info.codeinfo  # fbo "action_method"
+        return wrapped