vregistry.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 03 Aug 2009 10:50:57 +0200
changeset 2650 18aec79ec3a3
parent 2589 92f2bc945261
child 2655 48cd71bdb5cd
permissions -rw-r--r--
R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""
2308
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2173
diff changeset
     2
* the vregistry handles various types of objects interacting
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2173
diff changeset
     3
  together. The vregistry handles registration of dynamically loaded
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2173
diff changeset
     4
  objects and provides a convenient api to access those objects
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
  according to a context
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
2308
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2173
diff changeset
     7
* to interact with the vregistry, objects should inherit from the
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
  VObject abstract class
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
     9
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
* the selection procedure has been generalized by delegating to a
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
  selector, which is responsible to score the vobject according to the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
  current state (req, rset, row, col). At the end of the selection, if
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
  a vobject class has been found, an instance of this class is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
  returned. The selector is instantiated at vobject registration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1943
diff changeset
    18
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1943
diff changeset
    20
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
import sys
2083
f8f94c2951d3 add warning when rset isn't a named argument in select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
    25
import types
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
from os import listdir, stat
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    27
from os.path import dirname, join, realpath, split, isdir, exists
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from logging import getLogger
2083
f8f94c2951d3 add warning when rset isn't a named argument in select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
    29
from warnings import warn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
    31
from logilab.common.deprecation import deprecated
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
    32
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    37
def _toload_info(path, extrapath, _toload=None):
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    38
    """return a dictionary of <modname>: <modpath> and an ordered list of
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    39
    (file, module name) to load
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
    """
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    41
    from logilab.common.modutils import modpath_from_file
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    42
    if _toload is None:
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    43
        assert isinstance(path, list)
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    44
        _toload = {}, []
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    45
    for fileordir in path:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    46
        if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    47
            subfiles = [join(fileordir, fname) for fname in listdir(fileordir)]
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    48
            _toload_info(subfiles, extrapath, _toload)
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    49
        elif fileordir[-3:] == '.py':
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    50
            modname = '.'.join(modpath_from_file(fileordir, extrapath))
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    51
            _toload[0][modname] = fileordir
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    52
            _toload[1].append((fileordir, modname))
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
    53
    return _toload
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
class VObject(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
    """visual object, use to be handled somehow by the visual components
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    registry.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    The following attributes should be set on concret vobject subclasses:
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
    61
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
    :__registry__:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
      name of the registry for this object (string like 'views',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
      'templates'...)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    :id:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
      object's identifier in the registry (string like 'main',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
      'primary', 'folder_box')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
    :__select__:
719
2a610efe21ce default to yes_registerer
sylvain.thenault@logilab.fr
parents: 718
diff changeset
    69
      class'selector
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
    70
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    Moreover, the `__abstract__` attribute may be set to True to indicate
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
    that a vobject is abstract and should not be registered
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
    # necessary attributes to interact with the registry
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
    id = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
    __registry__ = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    __select__ = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
    def registered(cls, registry):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        """called by the registry when the vobject has been registered.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        It must return the  object that will be actually registered (this
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        may be the right hook to create an instance for example). By
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        default the vobject is returned without any transformation.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        """
741
8c810ee593a3 fix selectors compat
sylvain.thenault@logilab.fr
parents: 739
diff changeset
    87
        cls.build___select__()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        return cls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    def selected(cls, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        """called by the registry when the vobject has been selected.
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
    93
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        It must return the  object that will be actually returned by the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        .select method (this may be the right hook to create an
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        instance for example). By default the selected object is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        returned without any transformation.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        return cls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    def classid(cls):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
        """returns a unique identifier for the vobject"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        return '%s.%s' % (cls.__module__, cls.__name__)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
736
18c940e3f98d need safety belt for class registered twice (during test for instance)
sylvain.thenault@logilab.fr
parents: 735
diff changeset
   106
    # XXX bw compat code
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   107
    @classmethod
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   108
    def build___select__(cls):
943
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   109
        for klass in cls.mro():
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   110
            if klass.__name__ == 'AppRsetObject':
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   111
                continue # the bw compat __selector__ is there
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   112
            klassdict = klass.__dict__
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   113
            if ('__select__' in klassdict and '__selectors__' in klassdict
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   114
                and '__selgenerated__' not in klassdict):
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   115
                raise TypeError("__select__ and __selectors__ can't be used together on class %s" % cls)
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   116
            if '__selectors__' in klassdict and '__selgenerated__' not in klassdict:
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   117
                cls.__selgenerated__ = True
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   118
                # case where __selectors__ is defined locally (but __select__
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   119
                # is in a parent class)
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   120
                selectors = klassdict['__selectors__']
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   121
                if len(selectors) == 1:
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   122
                    # micro optimization: don't bother with AndSelector if there's
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   123
                    # only one selector
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   124
                    select = _instantiate_selector(selectors[0])
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   125
                else:
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   126
                    select = AndSelector(*selectors)
9fdfa8d38359 [selectors] for bacwkard compatibility, we must search the mro, not just the current class, in order not to miss __selectors__ in classes that do not redefine it
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 835
diff changeset
   127
                cls.__select__ = select
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   128
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   130
class Registry(dict):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   132
    def __init__(self, config):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   133
        super(Registry, self).__init__()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   134
        self.config = config
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   136
    def __getitem__(self, name):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
        """return the registry (dictionary of class objects) associated to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        this name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        try:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   141
            return super(Registry, self).__getitem__(name)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        except KeyError:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   143
            raise ObjectNotFound(name), None, sys.exc_info()[-1]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   144
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   145
    def register(self, obj, oid=None, clear=False):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   146
        """base method to add an object in the registry"""
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   147
        assert not '__abstract__' in obj.__dict__
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   148
        oid = oid or obj.id
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   149
        assert oid
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   150
        if clear:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   151
            vobjects = self[oid] =  []
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   152
        else:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   153
            vobjects = self.setdefault(oid, [])
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   154
        # registered() is technically a classmethod but is not declared
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   155
        # as such because we need to compose registered in some cases
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   156
        vobject = obj.registered.im_func(obj, self)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   157
        assert not vobject in vobjects, \
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   158
               'object %s is already registered' % vobject
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   159
        assert callable(vobject.__select__), vobject
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   160
        vobjects.append(vobject)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   162
    def register_and_replace(self, obj, replaced):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   163
        # XXXFIXME this is a duplication of unregister()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   164
        # remove register_and_replace in favor of unregister + register
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   165
        # or simplify by calling unregister then register here
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   166
        if hasattr(replaced, 'classid'):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   167
            replaced = replaced.classid()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   168
        registered_objs = self.get(obj.id, ())
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   169
        for index, registered in enumerate(registered_objs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   170
            if registered.classid() == replaced:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   171
                del registered_objs[index]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   172
                break
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   173
        else:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   174
            self.warning('trying to replace an unregistered view %s by %s',
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   175
                         replaced, obj)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   176
        self.register(obj)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   177
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   178
    def unregister(self, obj):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   179
        oid = obj.classid()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   180
        for registered in self.get(obj.id, ()):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   181
            # use classid() to compare classes because vreg will probably
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   182
            # have its own version of the class, loaded through execfile
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   183
            if registered.classid() == oid:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   184
                # XXX automatic reloading management
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   185
                self[obj.id].remove(registered)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   186
                break
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   187
        else:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   188
            self.warning('can\'t remove %s, no id %s in the registry',
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   189
                         oid, obj.id)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   190
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   191
    def all_objects(self):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   192
        """return a list containing all objects in this registry.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        """
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   194
        result = []
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   195
        for objs in self.values():
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   196
            result += objs
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   197
        return result
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   198
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   199
    # dynamic selection methods ################################################
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   200
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   201
    def object_by_id(self, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   202
        """return object with the given oid. Only one object is expected to be
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   203
        found.
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   204
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   205
        raise `ObjectNotFound` if not object with id <oid> in <registry>
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   206
        raise `AssertionError` if there is more than one object there
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   207
        """
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   208
        objects = self[oid]
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   209
        assert len(objects) == 1, objects
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   210
        return objects[0].selected(*args, **kwargs)
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   211
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   212
    def select(self, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   213
        """return the most specific object among those with the given oid
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   214
        according to the given context.
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   215
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   216
        raise `ObjectNotFound` if not object with id <oid> in <registry>
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   217
        raise `NoSelectableObject` if not object apply
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   218
        """
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   219
        return self.select_best(self[oid], *args, **kwargs)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   220
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   221
    def select_object(self, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   222
        """return the most specific object among those with the given oid
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   223
        according to the given context, or None if no object applies.
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   224
        """
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   225
        try:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   226
            return self.select(oid, *args, **kwargs)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   227
        except (NoSelectableObject, ObjectNotFound):
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   228
            return None
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   229
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   230
    def possible_objects(self, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   231
        """return an iterator on possible objects in this registry for the given
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   232
        context
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   233
        """
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   234
        for vobjects in self.itervalues():
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   235
            try:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   236
                yield self.select_best(vobjects, *args, **kwargs)
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   237
            except NoSelectableObject:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   238
                continue
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   239
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   240
    def select_best(self, vobjects, *args, **kwargs):
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   241
        """return an instance of the most specific object according
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   242
        to parameters
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   243
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   244
        raise `NoSelectableObject` if not object apply
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   245
        """
2083
f8f94c2951d3 add warning when rset isn't a named argument in select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   246
        if len(args) > 1:
f8f94c2951d3 add warning when rset isn't a named argument in select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2058
diff changeset
   247
            warn('only the request param can not be named when calling select',
2302
e0393451e9a5 fix stacklevel
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2181
diff changeset
   248
                 DeprecationWarning, stacklevel=3)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   249
        score, winners = 0, []
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   250
        for vobject in vobjects:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   251
            vobjectscore = vobject.__select__(vobject, *args, **kwargs)
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   252
            if vobjectscore > score:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   253
                score, winners = vobjectscore, [vobject]
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   254
            elif vobjectscore > 0 and vobjectscore == score:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   255
                winners.append(vobject)
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   256
        if not winners:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   257
            raise NoSelectableObject('args: %s\nkwargs: %s %s'
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   258
                                     % (args, kwargs.keys(),
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   259
                                        [repr(v) for v in vobjects]))
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   260
        if len(winners) > 1:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   261
            if self.config.mode == 'installed':
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   262
                self.error('select ambiguity, args: %s\nkwargs: %s %s',
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   263
                           args, kwargs.keys(), [repr(v) for v in winners])
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   264
            else:
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   265
                raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   266
                                % (args, kwargs.keys(),
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   267
                                   [repr(v) for v in winners]))
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   268
        # return the result of the .selected method of the vobject
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   269
        return winners[0].selected(*args, **kwargs)
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   270
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   271
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   272
class VRegistry(dict):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   273
    """class responsible to register, propose and select the various
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   274
    elements used to build the web interface. Currently, we have templates,
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   275
    views, actions and components.
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   276
    """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   277
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   278
    def __init__(self, config):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   279
        super(VRegistry, self).__init__()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   280
        self.config = config
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   281
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   282
    def reset(self):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   283
        self.clear()
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   284
        self._lastmodifs = {}
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   285
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   286
    def __getitem__(self, name):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   287
        """return the registry (dictionary of class objects) associated to
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   288
        this name
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   289
        """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   290
        try:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   291
            return super(VRegistry, self).__getitem__(name)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   292
        except KeyError:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   293
            raise RegistryNotFound(name), None, sys.exc_info()[-1]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   294
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   295
    # dynamic selection methods ################################################
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   296
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   297
    @deprecated('use vreg[registry].object_by_id(oid, *args, **kwargs)')
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   298
    def object_by_id(self, registry, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   299
        """return object in <registry>.<oid>
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   300
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   301
        raise `ObjectNotFound` if not object with id <oid> in <registry>
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   302
        raise `AssertionError` if there is more than one object there
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   303
        """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   304
        return self[registry].object_by_id(oid)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   305
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   306
    @deprecated('use vreg[registry].select(oid, *args, **kwargs)')
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   307
    def select(self, registry, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   308
        """return the most specific object in <registry>.<oid> according to
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   309
        the given context
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   310
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   311
        raise `ObjectNotFound` if not object with id <oid> in <registry>
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   312
        raise `NoSelectableObject` if not object apply
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   313
        """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   314
        return self[registry].select(oid, *args, **kwargs)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   315
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   316
    @deprecated('use vreg[registry].select_object(oid, *args, **kwargs)')
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   317
    def select_object(self, registry, oid, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   318
        """return the most specific object in <registry>.<oid> according to
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   319
        the given context, or None if no object apply
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   320
        """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   321
        return self[registry].select_object(oid, *args, **kwargs)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   322
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   323
    @deprecated('use vreg[registry].possible_objects(*args, **kwargs)')
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   324
    def possible_objects(self, registry, *args, **kwargs):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   325
        """return an iterator on possible objects in <registry> for the given
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   326
        context
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   327
        """
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   328
        return self[registry].possible_objects(*args, **kwargs)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   329
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   330
    # methods for explicit (un)registration ###################################
668
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   331
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   332
    # default class, when no specific class set
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   333
    REGISTRY_FACTORY = {None: Registry}
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   334
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   335
    def registry_class(self, regid):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   336
        try:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   337
            return self.REGISTRY_FACTORY[regid]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   338
        except KeyError:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   339
            return self.REGISTRY_FACTORY[None]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   340
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   341
    def setdefault(self, regid):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   342
        try:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   343
            return self[regid]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   344
        except KeyError:
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   345
            self[regid] = self.registry_class(regid)(self.config)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   346
            return self[regid]
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   347
668
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   348
#     def clear(self, key):
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   349
#         regname, oid = key.split('.')
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   350
#         self[regname].pop(oid, None)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2035
diff changeset
   351
695
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   352
    def register_all(self, objects, modname, butclasses=()):
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   353
        for obj in objects:
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   354
            try:
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   355
                if obj.__module__ != modname or obj in butclasses:
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   356
                    continue
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   357
                oid = obj.id
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   358
            except AttributeError:
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   359
                continue
2587
79bbc5045288 [vreg] consider __abstract__ in register_all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2308
diff changeset
   360
            if oid and not '__abstract__' in obj.__dict__:
695
356da23c57f1 try a register_all method
sylvain.thenault@logilab.fr
parents: 693
diff changeset
   361
                self.register(obj)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   362
668
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   363
    def register(self, obj, registryname=None, oid=None, clear=False):
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   364
        """base method to add an object in the registry"""
707
21a59b468f1a __selectors__ -> __select__
sylvain.thenault@logilab.fr
parents: 698
diff changeset
   365
        assert not '__abstract__' in obj.__dict__
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   366
        registryname = registryname or obj.__registry__
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   367
        registry = self.setdefault(registryname)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   368
        registry.register(obj, oid=oid, clear=clear)
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   369
        try:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   370
            vname = obj.__name__
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   371
        except AttributeError:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   372
            vname = obj.__class__.__name__
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   373
        self.debug('registered vobject %s in registry %s with id %s',
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   374
                   vname, registryname, oid)
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   375
        # automatic reloading management
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   376
        self._loadedmods[obj.__module__]['%s.%s' % (obj.__module__, oid)] = obj
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   377
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   378
    def unregister(self, obj, registryname=None):
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   379
        self[registryname or obj.__registry__].unregister(obj)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   380
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   381
    def register_and_replace(self, obj, replaced, registryname=None):
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   382
        self[registryname or obj.__registry__].register_and_replace(obj, replaced)
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   383
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   384
    # initialization methods ###################################################
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   385
2035
946ed7349e1a bugfix: extrapath is optional arg for init_registration
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2025
diff changeset
   386
    def init_registration(self, path, extrapath=None):
1316
6d71d38822ee introduce init_registration method and call it in repo initialization
sylvain.thenault@logilab.fr
parents: 1310
diff changeset
   387
        # compute list of all modules that have to be loaded
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   388
        self._toloadmods, filemods = _toload_info(path, extrapath)
1316
6d71d38822ee introduce init_registration method and call it in repo initialization
sylvain.thenault@logilab.fr
parents: 1310
diff changeset
   389
        self._loadedmods = {}
6d71d38822ee introduce init_registration method and call it in repo initialization
sylvain.thenault@logilab.fr
parents: 1310
diff changeset
   390
        return filemods
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   391
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   392
    def register_objects(self, path, force_reload=None, extrapath=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
        if force_reload is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
            force_reload = self.config.mode == 'dev'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
        elif not force_reload:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
            # force_reload == False usually mean modules have been reloaded
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
            # by another connection, so we want to update the registry
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
            # content even if there has been no module content modification
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
            self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
        # need to clean sys.path this to avoid import confusion pb (i.e.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
        # having the same module loaded as 'cubicweb.web.views' subpackage and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        # as views'  or 'web.views' subpackage
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        # this is mainly for testing purpose, we should'nt need this in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
        # production environment
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
        for webdir in (join(dirname(realpath(__file__)), 'web'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
                       join(dirname(__file__), 'web')):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
            if webdir in sys.path:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
                sys.path.remove(webdir)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        if CW_SOFTWARE_ROOT in sys.path:
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   410
            sys.path.remove(CW_SOFTWARE_ROOT)
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   411
        # load views from each directory in the instance's path
2025
010a4b0fe855 fix lookup of files to load when using CW_CUBES_PATH
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   412
        filemods = self.init_registration(path, extrapath)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
        change = False
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   414
        for filepath, modname in filemods:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   415
            if self.load_file(filepath, modname, force_reload):
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   416
                change = True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
        return change
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   418
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   419
    def load_file(self, filepath, modname, force_reload=False):
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   420
        """load visual objects from a python file"""
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   421
        from logilab.common.modutils import load_module_from_name
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   422
        if modname in self._loadedmods:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   423
            return
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   424
        self._loadedmods[modname] = {}
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   425
        try:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   426
            modified_on = stat(filepath)[-2]
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   427
        except OSError:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   428
            # this typically happens on emacs backup files (.#foo.py)
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   429
            self.warning('Unable to load %s. It is likely to be a backup file',
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   430
                         filepath)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
            return False
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   432
        if filepath in self._lastmodifs:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
            # only load file if it was modified
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   434
            if modified_on <= self._lastmodifs[filepath]:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
                return
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   436
            # if it was modified, unregister all exisiting objects
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   437
            # from this module, and keep track of what was unregistered
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   438
            unregistered = self.unregister_module_vobjects(modname)
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   439
        else:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   440
            unregistered = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        # load the module
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   442
        module = load_module_from_name(modname, use_sys=not force_reload)
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   443
        self.load_module(module)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
        # if something was unregistered, we need to update places where it was
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   445
        # referenced
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
        if unregistered:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
            # oldnew_mapping = {}
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   448
            registered = self._loadedmods[modname]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
            oldnew_mapping = dict((unregistered[name], registered[name])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
                                  for name in unregistered if name in registered)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
            self.update_registered_subclasses(oldnew_mapping)
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   452
        self._lastmodifs[filepath] = modified_on
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
    def load_module(self, module):
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   456
        self.info('loading %s', module)
668
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   457
        if hasattr(module, 'registration_callback'):
61b2328f9ed9 rename registration callback, clear argument to register
sylvain.thenault@logilab.fr
parents: 665
diff changeset
   458
            module.registration_callback(self)
660
5233a9457f6b work in progress, draft for manual registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 652
diff changeset
   459
        else:
5233a9457f6b work in progress, draft for manual registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 652
diff changeset
   460
            for objname, obj in vars(module).items():
5233a9457f6b work in progress, draft for manual registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 652
diff changeset
   461
                if objname.startswith('_'):
5233a9457f6b work in progress, draft for manual registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 652
diff changeset
   462
                    continue
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   463
                self._load_ancestors_then_object(module.__name__, obj)
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   464
        self.debug('loaded %s', module)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   465
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   466
    def _load_ancestors_then_object(self, modname, obj):
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   467
        # imported classes
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   468
        objmodname = getattr(obj, '__module__', None)
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   469
        if objmodname != modname:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   470
            if objmodname in self._toloadmods:
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   471
                self.load_file(self._toloadmods[objmodname], objmodname)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        # skip non registerable object
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
            if not issubclass(obj, VObject):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
                return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        except TypeError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
        objname = '%s.%s' % (modname, obj.__name__)
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   480
        if objname in self._loadedmods[modname]:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
            return
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   482
        self._loadedmods[modname][objname] = obj
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
        for parent in obj.__bases__:
1310
99dfced5673e fix vobjects registration to deal with objects inter-dependancy
sylvain.thenault@logilab.fr
parents: 1282
diff changeset
   484
            self._load_ancestors_then_object(modname, parent)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
        self.load_object(obj)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   486
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
    def load_object(self, obj):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
            self.register_vobject_class(obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
        except Exception, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
            if self.config.mode in ('test', 'dev'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
                raise
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
            self.exception('vobject %s registration failed: %s', obj, ex)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   494
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   495
    # old automatic registration XXX deprecated ###############################
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   496
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   497
    def register_vobject_class(self, cls):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
        """handle vobject class registration
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   499
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
        vobject class with __abstract__ == True in their local dictionnary or
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        with a name starting starting by an underscore are not registered.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   502
        Also a vobject class needs to have __registry__ and id attributes set
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
        to a non empty string to be registered.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   504
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
        if (cls.__dict__.get('__abstract__') or cls.__name__[0] == '_'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
            or not cls.__registry__ or not cls.id):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
            return
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   508
        regname = cls.__registry__
1046
52ee022d87e3 simplify registry options to disable some appobjects to use a single option
sylvain.thenault@logilab.fr
parents: 946
diff changeset
   509
        if '%s.%s' % (regname, cls.id) in self.config['disable-appobjects']:
665
1305da1ce3f9 reorganize a bit, some cleanup and fixes
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   510
            return
1432
2c3711d4570b drop hopeless registerer bw compat
sylvain.thenault@logilab.fr
parents: 1316
diff changeset
   511
        self.register(cls)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   512
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
    def unregister_module_vobjects(self, modname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
        """removes registered objects coming from a given module
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   516
        returns a dictionnary classid/class of all classes that will need
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
        to be updated after reload (i.e. vobjects referencing classes defined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
        in the <modname> module)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
        unregistered = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
        # browse each registered object
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
        for registry, objdict in self.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
            for oid, objects in objdict.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
                for obj in objects[:]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
                    objname = obj.classid()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
                    # if the vobject is defined in this module, remove it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
                    if objname.startswith(modname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
                        unregistered[objname] = obj
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   529
                        objects.remove(obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   530
                        self.debug('unregistering %s in %s registry',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
                                  objname, registry)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
                    # if not, check if the vobject can be found in baseclasses
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
                    # (because we also want subclasses to be updated)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
                        if not isinstance(obj, type):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
                            obj = obj.__class__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
                        for baseclass in obj.__bases__:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
                            if hasattr(baseclass, 'classid'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
                                baseclassid = baseclass.classid()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   540
                                if baseclassid.startswith(modname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   541
                                    unregistered[baseclassid] = baseclass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   542
                # update oid entry
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   543
                if objects:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   544
                    objdict[oid] = objects
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   545
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   546
                    del objdict[oid]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   547
        return unregistered
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   548
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
    def update_registered_subclasses(self, oldnew_mapping):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   550
        """updates subclasses of re-registered vobjects
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
        if baseviews.PrimaryView is changed, baseviews.py will be reloaded
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
        automatically and the new version of PrimaryView will be registered.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
        But all existing subclasses must also be notified of this change, and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
        that's what this method does
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   556
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
        :param oldnew_mapping: a dict mapping old version of a class to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
                               the new version
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
        # browse each registered object
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
        for objdict in self.values():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
            for objects in objdict.values():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
                for obj in objects:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
                    if not isinstance(obj, type):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
                        obj = obj.__class__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
                    # build new baseclasses tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
                    newbases = tuple(oldnew_mapping.get(baseclass, baseclass)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
                                     for baseclass in obj.__bases__)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
                    # update obj's baseclasses tuple (__bases__) if needed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
                    if newbases != obj.__bases__:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
                        self.debug('updating %s.%s base classes',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
                                  obj.__module__, obj.__name__)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
                        obj.__bases__ = newbases
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   575
# init logging
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   576
set_log_methods(VObject, getLogger('cubicweb.appobject'))
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   577
set_log_methods(VRegistry, getLogger('cubicweb.vreg'))
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2589
diff changeset
   578
set_log_methods(Registry, getLogger('cubicweb.registry'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   581
# selector base classes and operations ########################################
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 630
diff changeset
   582
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   583
class Selector(object):
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   584
    """base class for selector classes providing implementation
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   585
    for operators ``&`` and ``|``
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   586
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   587
    This class is only here to give access to binary operators, the
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   588
    selector logic itself should be implemented in the __call__ method
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   590
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   591
    a selector is called to help choosing the correct object for a
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   592
    particular context by returning a score (`int`) telling how well
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   593
    the class given as first argument apply to the given context.
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   594
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   595
    0 score means that the class doesn't apply.
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   596
    """
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   597
711
f758b86cf484 Selector objects need to provide a `func_name` attribute for minimum (backward)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 710
diff changeset
   598
    @property
f758b86cf484 Selector objects need to provide a `func_name` attribute for minimum (backward)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 710
diff changeset
   599
    def func_name(self):
f758b86cf484 Selector objects need to provide a `func_name` attribute for minimum (backward)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 710
diff changeset
   600
        # backward compatibility
f758b86cf484 Selector objects need to provide a `func_name` attribute for minimum (backward)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 710
diff changeset
   601
        return self.__class__.__name__
f758b86cf484 Selector objects need to provide a `func_name` attribute for minimum (backward)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 710
diff changeset
   602
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   603
    def search_selector(self, selector):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   604
        """search for the given selector or selector instance in the selectors
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   605
        tree. Return it of None if not found
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   606
        """
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   607
        if self is selector:
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   608
            return self
721
sylvain.thenault@logilab.fr
parents: 719
diff changeset
   609
        if isinstance(selector, type) and isinstance(self, selector):
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   610
            return self
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   611
        return None
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   612
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   613
    def __str__(self):
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   614
        return self.__class__.__name__
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   615
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   616
    def __and__(self, other):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   617
        return AndSelector(self, other)
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   618
    def __rand__(self, other):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   619
        return AndSelector(other, self)
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   620
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   621
    def __or__(self, other):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   622
        return OrSelector(self, other)
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   623
    def __ror__(self, other):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   624
        return OrSelector(other, self)
827
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   625
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   626
    def __invert__(self):
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   627
        return NotSelector(self)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   628
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   629
    # XXX (function | function) or (function & function) not managed yet
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   630
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   631
    def __call__(self, cls, *args, **kwargs):
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   632
        return NotImplementedError("selector %s must implement its logic "
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   633
                                   "in its __call__ method" % self.__class__)
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   634
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   635
class MultiSelector(Selector):
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 714
diff changeset
   636
    """base class for compound selector classes"""
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   637
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   638
    def __init__(self, *selectors):
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   639
        self.selectors = self.merge_selectors(selectors)
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   640
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   641
    def __str__(self):
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   642
        return '%s(%s)' % (self.__class__.__name__,
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   643
                           ','.join(str(s) for s in self.selectors))
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   644
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   645
    @classmethod
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   646
    def merge_selectors(cls, selectors):
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   647
        """deal with selector instanciation when necessary and merge
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   648
        multi-selectors if possible:
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   649
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   650
        AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   651
        ==> AndSelector(sel1, sel2, sel3, sel4)
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   652
        """
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   653
        merged_selectors = []
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   654
        for selector in selectors:
946
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   655
            try:
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   656
                selector = _instantiate_selector(selector)
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   657
            except:
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   658
                pass
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   659
            #assert isinstance(selector, Selector), selector
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   660
            if isinstance(selector, cls):
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   661
                merged_selectors += selector.selectors
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   662
            else:
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   663
                merged_selectors.append(selector)
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   664
        return merged_selectors
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   665
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   666
    def search_selector(self, selector):
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   667
        """search for the given selector or selector instance in the selectors
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   668
        tree. Return it of None if not found
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   669
        """
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   670
        for childselector in self.selectors:
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   671
            if childselector is selector:
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   672
                return childselector
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   673
            found = childselector.search_selector(selector)
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   674
            if found is not None:
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   675
                return found
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   676
        return None
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   677
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   678
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   679
def objectify_selector(selector_func):
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   680
    """convenience decorator for simple selectors where a class definition
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   681
    would be overkill::
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   682
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   683
        @objectify_selector
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   684
        def yes(cls, *args, **kwargs):
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   685
            return 1
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   686
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   687
    """
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   688
    return type(selector_func.__name__, (Selector,),
734
4153a82a60a4 get kwargs as well
sylvain.thenault@logilab.fr
parents: 727
diff changeset
   689
                {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 695
diff changeset
   690
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   691
def _instantiate_selector(selector):
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   692
    """ensures `selector` is a `Selector` instance
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   693
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   694
    NOTE: This should only be used locally in build___select__()
946
a130b5ceeca9 [selectors] _needs real fix_ whack 'till it works for me
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 943
diff changeset
   695
    XXX: then, why not do it ??
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   696
    """
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   697
    if isinstance(selector, types.FunctionType):
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   698
        return objectify_selector(selector)()
727
30fe8f5afbd8 fix _instantiate_selector() mini bug (make sure obj is a class before calling issubclass)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 724
diff changeset
   699
    if isinstance(selector, type) and issubclass(selector, Selector):
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   700
        return selector()
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   701
    return selector
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 711
diff changeset
   702
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   703
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   704
class AndSelector(MultiSelector):
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   705
    """and-chained selectors (formerly known as chainall)"""
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   706
    def __call__(self, cls, *args, **kwargs):
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   707
        score = 0
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   708
        for selector in self.selectors:
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   709
            partscore = selector(cls, *args, **kwargs)
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   710
            if not partscore:
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   711
                return 0
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   712
            score += partscore
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   713
        return score
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   714
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   715
698
7dfd03e9e810 introduce MultiSelector base class
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   716
class OrSelector(MultiSelector):
630
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   717
    """or-chained selectors (formerly known as chainfirst)"""
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   718
    def __call__(self, cls, *args, **kwargs):
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   719
        for selector in self.selectors:
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   720
            partscore = selector(cls, *args, **kwargs)
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   721
            if partscore:
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   722
                return partscore
66ff0b2f7d03 simple test implementation for binary operators on selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 615
diff changeset
   723
        return 0
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   724
827
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   725
class NotSelector(Selector):
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   726
    """negation selector"""
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   727
    def __init__(self, selector):
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   728
        self.selector = selector
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   729
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   730
    def __call__(self, cls, *args, **kwargs):
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   731
        score = self.selector(cls, *args, **kwargs)
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 827
diff changeset
   732
        return int(not score)
827
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   733
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   734
    def __str__(self):
3f08481e6e51 provide negation operator for selectors, unfortunately, it's not possible to user the python keyword 'not'
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 804
diff changeset
   735
        return 'NOT(%s)' % super(NotSelector, self).__str__()
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   736
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 827
diff changeset
   737
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 827
diff changeset
   738
# XXX bw compat functions #####################################################
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   739
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   740
def chainall(*selectors, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   741
    """return a selector chaining given selectors. If one of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   742
    the selectors fail, selection will fail, else the returned score
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   743
    will be the sum of each selector'score
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   744
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   745
    assert selectors
759
e044f28372bd chainall / chainfirst ensures selectors are instantiated
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 741
diff changeset
   746
    # XXX do we need to create the AndSelector here, a tuple might be enough
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   747
    selector = AndSelector(*selectors)
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   748
    if 'name' in kwargs:
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   749
        selector.__name__ = kwargs['name']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   750
    return selector
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   751
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   752
def chainfirst(*selectors, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   753
    """return a selector chaining given selectors. If all
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   754
    the selectors fail, selection will fail, else the returned score
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   755
    will be the first non-zero selector score
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   756
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   757
    assert selectors
780
5b6c93816871 fix selector search and refactor auto-instantiation
sylvain.thenault@logilab.fr
parents: 760
diff changeset
   758
    selector = OrSelector(*selectors)
693
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   759
    if 'name' in kwargs:
cf0817dfc787 reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
sylvain.thenault@logilab.fr
parents: 686
diff changeset
   760
        selector.__name__ = kwargs['name']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
    return selector