Added 'prefix' argument to 'request_property' and 'session_property' decorators
authorThierry Florac <thierry.florac@onf.fr>
Tue, 08 Nov 2016 12:22:05 +0100
changeset 68 7f90df24ceca
parent 67 8b172808ca6c
child 69 0b859bda300e
Added 'prefix' argument to 'request_property' and 'session_property' decorators
src/pyams_utils/property.py
--- a/src/pyams_utils/property.py	Tue Oct 11 16:21:25 2016 +0200
+++ b/src/pyams_utils/property.py	Tue Nov 08 12:22:05 2016 +0100
@@ -20,12 +20,25 @@
 # import packages
 from pyams_utils.request import check_request, get_request_data, set_request_data
 from pyams_utils.session import get_session_data, set_session_data
+from zope.schema.fieldproperty import FieldProperty
+
+
+class DocFieldProperty(FieldProperty):
+    """Field property with doc
+
+    This field property class extracts it's docstring from parent field description, if any.
+    It's main purpose is for documentation needs.
+    """
+
+    @property
+    def __doc__(self):
+        return self._FieldProperty__field.description or super(FieldProperty, self).__doc__
 
 
 class cached(object):
     """Custom property decorator to define a property or function
     which is calculated only once
-       
+
     When applied on a function, caching is based on input arguments
     """
 
@@ -65,19 +78,21 @@
 _marker = object()
 
 
-def request_property(key):
-    """Define a method decorator used to store result into request's annotations
+def request_property(key, prefix=None):
+    """Define a method decorator used to store result into current request's annotations
 
+    If not request is currently running, a new one is created.
     `key` is a required argument; if None, the key will be the method's object
     """
 
     def request_decorator(func):
+
         def wrapper(obj, key, *args, **kwargs):
             request = check_request()
             if callable(key):
                 key = key(obj)
             if not key:
-                key = '{0!r}'.format(obj)
+                key = '{1}::{0!r}'.format(obj, prefix or func.__name__)
             data = get_request_data(request, key, _marker)
             if data is _marker:
                 data = func
@@ -85,25 +100,29 @@
                     data = data(obj, *args, **kwargs)
                 set_request_data(request, key, data)
             return data
+
         return lambda x: wrapper(x, key=key)
 
     return request_decorator
 
 
-def session_property(app, key=None):
+def session_property(app, key=None, prefix=None):
     """Define a method decorator used to store result into request's session
 
-    `app` is an application identifier used to prefix session keys
-    `key` is session's value key; if None, the key will be the method's object
+    If no request is currently running, a new one is created.
+
+    @app: application identifier used to prefix session keys
+    @key: session's value key; if None, the key will be the method's object
     """
 
     def session_decorator(func):
+
         def wrapper(obj, app, key, *args, **kwargs):
             request = check_request()
             if callable(key):
                 key = key(obj)
             if not key:
-                key = '{0!r}'.format(obj)
+                key = '{1}::{0!r}'.format(obj, prefix or func.__name__)
             data = get_session_data(request, app, key, _marker)
             if data is _marker:
                 data = func
@@ -111,6 +130,7 @@
                     data = data(obj, *args, **kwargs)
                 set_session_data(request, app, key, data)
             return data
+
         return lambda x: wrapper(x, app=app, key=key)
 
     return session_decorator