--- 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