appobject.py
branchstable
changeset 5147 70181998897f
parent 5093 8d073d2e089d
child 5306 763319a51e72
equal deleted inserted replaced
5146:fe56baf63ecb 5147:70181998897f
     1 """Base class for dynamically loaded objects accessible through the vregistry.
     1 # :organization: Logilab
     2 
     2 # :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     3 You'll also find some convenience classes to build selectors.
     3 # :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     4 
     4 # :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     5 :organization: Logilab
     5 """
     6 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     6 The `AppObject` class
     7 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     7 ---------------------
     8 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     8 
       
     9 The AppObject class is the base class for all dynamically loaded objects
       
    10 (application objects) accessible through the vregistry.
       
    11 
       
    12 We can find a certain number of attributes and methods defined in this class and
       
    13 common to all the application objects.
       
    14 
       
    15 .. autoclass:: AppObject
     9 """
    16 """
    10 __docformat__ = "restructuredtext en"
    17 __docformat__ = "restructuredtext en"
    11 
    18 
    12 import types
    19 import types
    13 from logging import getLogger
    20 from logging import getLogger
    19 
    26 
    20 
    27 
    21 # selector base classes and operations ########################################
    28 # selector base classes and operations ########################################
    22 
    29 
    23 def objectify_selector(selector_func):
    30 def objectify_selector(selector_func):
    24     """convenience decorator for simple selectors where a class definition
    31     """Most of the time, a simple score function is enough to build a selector.
    25     would be overkill::
    32     The :func:`objectify_selector` decorator turn it into a proper selector
       
    33     class::
    26 
    34 
    27         @objectify_selector
    35         @objectify_selector
    28         def one(cls, *args, **kwargs):
    36         def one(cls, *args, **kwargs):
    29             return 1
    37             return 1
       
    38 
       
    39         class MyView(View):
       
    40             __select__ = View.__select__ & one()
    30 
    41 
    31     """
    42     """
    32     return type(selector_func.__name__, (Selector,),
    43     return type(selector_func.__name__, (Selector,),
    33                 {'__doc__': selector_func.__doc__,
    44                 {'__doc__': selector_func.__doc__,
    34                  '__call__': lambda self, *a, **kw: selector_func(*a, **kw)})
    45                  '__call__': lambda self, *a, **kw: selector_func(*a, **kw)})
    47     return selector
    58     return selector
    48 
    59 
    49 
    60 
    50 class Selector(object):
    61 class Selector(object):
    51     """base class for selector classes providing implementation
    62     """base class for selector classes providing implementation
    52     for operators ``&`` and ``|``
    63     for operators ``&``, ``|`` and  ``~``
    53 
    64 
    54     This class is only here to give access to binary operators, the
    65     This class is only here to give access to binary operators, the
    55     selector logic itself should be implemented in the __call__ method
    66     selector logic itself should be implemented in the __call__ method
    56 
    67 
    57 
    68 
   203 class AppObject(object):
   214 class AppObject(object):
   204     """This is the base class for CubicWeb application objects which are
   215     """This is the base class for CubicWeb application objects which are
   205     selected according to a context (usually at least a request and a result
   216     selected according to a context (usually at least a request and a result
   206     set).
   217     set).
   207 
   218 
   208     Concrete application objects classes are designed to be loaded by the
       
   209     vregistry and should be accessed through it, not by direct instantiation.
       
   210 
       
   211     The following attributes should be set on concret appobject classes:
   219     The following attributes should be set on concret appobject classes:
   212     :__registry__:
   220 
       
   221     :attr:`__registry__`
   213       name of the registry for this object (string like 'views',
   222       name of the registry for this object (string like 'views',
   214       'templates'...)
   223       'templates'...)
   215     :__regid__:
   224 
       
   225     :attr:`__regid__`
   216       object's identifier in the registry (string like 'main',
   226       object's identifier in the registry (string like 'main',
   217       'primary', 'folder_box')
   227       'primary', 'folder_box')
   218     :__select__:
   228 
       
   229     :attr:`__select__`
   219       class'selector
   230       class'selector
   220 
   231 
   221     Moreover, the `__abstract__` attribute may be set to True to indicate
   232     Moreover, the `__abstract__` attribute may be set to True to indicate that a
   222     that a appobject is abstract and should not be registered.
   233     class is abstract and should not be registered.
   223 
   234 
   224     At selection time, the following attributes are set on the instance:
   235     At selection time, the following attributes are set on the instance:
   225 
   236 
   226     :_cw:
   237     :attr:`_cw`
   227       current request
   238       current request
   228     :cw_extra_kwargs:
   239     :attr:`cw_extra_kwargs`
   229       other received arguments
   240       other received arguments
   230 
   241 
   231     only if rset is found in arguments (in which case rset/row/col will be
   242     And also the following, only if `rset` is found in arguments (in which case
   232     removed from cwextra_kwargs):
   243     rset/row/col will be removed from `cwextra_kwargs`):
   233 
   244 
   234     :cw_rset:
   245     :attr:`cw_rset`
   235       context result set or None
   246       context result set or None
   236     :cw_row:
   247 
       
   248     :attr:`cw_row`
   237       if a result set is set and the context is about a particular cell in the
   249       if a result set is set and the context is about a particular cell in the
   238       result set, and not the result set as a whole, specify the row number we
   250       result set, and not the result set as a whole, specify the row number we
   239       are interested in, else None
   251       are interested in, else None
   240     :cw_col:
   252 
       
   253     :attr:`cw_col`
   241       if a result set is set and the context is about a particular cell in the
   254       if a result set is set and the context is about a particular cell in the
   242       result set, and not the result set as a whole, specify the col number we
   255       result set, and not the result set as a whole, specify the col number we
   243       are interested in, else None
   256       are interested in, else None
       
   257 
       
   258 
       
   259     .. Note::
       
   260 
       
   261       * do not inherit directly from this class but from a more specific class
       
   262         such as `AnyEntity`, `EntityView`, `AnyRsetView`, `Action`...
       
   263 
       
   264       * to be recordable, a subclass has to define its registry (attribute
       
   265         `__registry__`) and its identifier (attribute `__regid__`). Usually
       
   266         you don't have to take care of the registry since it's set by the base
       
   267         class, only the identifier `id`
       
   268 
       
   269       * application objects are designed to be loaded by the vregistry and
       
   270         should be accessed through it, not by direct instantiation, besides
       
   271         to use it as base classe.
       
   272 
       
   273 
       
   274       * When we inherit from `AppObject` (even not directly), you *always* have
       
   275         to use **super()** to get the methods and attributes of the superclasses,
       
   276         and not use the class identifier.
       
   277 
       
   278         For example, instead of writting::
       
   279 
       
   280           class Truc(PrimaryView):
       
   281               def f(self, arg1):
       
   282                   PrimaryView.f(self, arg1)
       
   283 
       
   284         You must write::
       
   285 
       
   286           class Truc(PrimaryView):
       
   287               def f(self, arg1):
       
   288                   super(Truc, self).f(arg1)
       
   289 
   244     """
   290     """
   245     __registry__ = None
   291     __registry__ = None
   246     __regid__ = None
   292     __regid__ = None
   247     __select__ = yes()
   293     __select__ = yes()
   248 
   294