[appobject] kill VObject class, move base selector classes to appobject
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 03 Aug 2009 15:16:47 +0200
changeset 2657 de974465d381
parent 2656 a93ae0f6c0ad
child 2658 5535857eeaa5
[appobject] kill VObject class, move base selector classes to appobject
appobject.py
common/test/unittest_migration.py
cwconfig.py
cwvreg.py
dbapi.py
devtools/__init__.py
devtools/devctl.py
devtools/testlib.py
entities/test/unittest_base.py
etwist/server.py
etwist/twconfig.py
goa/goaconfig.py
goa/goavreg.py
selectors.py
server/serverconfig.py
test/unittest_rtags.py
test/unittest_selectors.py
test/unittest_vregistry.py
utils.py
vregistry.py
web/test/test_views.py
web/test/unittest_viewselector.py
web/views/actions.py
web/views/basetemplates.py
web/views/facets.py
web/views/forms.py
web/views/plots.py
web/views/urlpublishing.py
web/webconfig.py
--- a/appobject.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/appobject.py	Mon Aug 03 15:16:47 2009 +0200
@@ -1,4 +1,6 @@
-"""Base class for dynamically loaded objects manipulated in the web interface
+"""Base class for dynamically loaded objects accessible through the vregistry.
+
+You'll also find some convenience classes to build selectors.
 
 :organization: Logilab
 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
@@ -7,20 +9,23 @@
 """
 __docformat__ = "restructuredtext en"
 
+import types
+from logging import getLogger
 from datetime import datetime, timedelta, time
 
 from logilab.common.decorators import classproperty
 from logilab.common.deprecation import deprecated
+from logilab.common.logging_ext import set_log_methods
 
 from rql.nodes import VariableRef, SubQuery
 from rql.stmts import Union, Select
 
 from cubicweb import Unauthorized, NoSelectableObject
-from cubicweb.vregistry import VObject, AndSelector
-from cubicweb.selectors import yes
 from cubicweb.utils import UStringIO, ustrftime, strptime, todate, todatetime
 
 ONESECOND = timedelta(0, 1, 0)
+CACHE_REGISTRY = {}
+
 
 class Cache(dict):
     def __init__(self):
@@ -29,14 +34,200 @@
         self.cache_creation_date = _now
         self.latest_cache_lookup = _now
 
-CACHE_REGISTRY = {}
+
+# selector base classes and operations ########################################
+
+def objectify_selector(selector_func):
+    """convenience decorator for simple selectors where a class definition
+    would be overkill::
+
+        @objectify_selector
+        def yes(cls, *args, **kwargs):
+            return 1
+
+    """
+    return type(selector_func.__name__, (Selector,),
+                {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
+
+
+def _instantiate_selector(selector):
+    """ensures `selector` is a `Selector` instance
+
+    NOTE: This should only be used locally in build___select__()
+    XXX: then, why not do it ??
+    """
+    if isinstance(selector, types.FunctionType):
+        return objectify_selector(selector)()
+    if isinstance(selector, type) and issubclass(selector, Selector):
+        return selector()
+    return selector
+
+
+class Selector(object):
+    """base class for selector classes providing implementation
+    for operators ``&`` and ``|``
+
+    This class is only here to give access to binary operators, the
+    selector logic itself should be implemented in the __call__ method
+
+
+    a selector is called to help choosing the correct object for a
+    particular context by returning a score (`int`) telling how well
+    the class given as first argument apply to the given context.
+
+    0 score means that the class doesn't apply.
+    """
+
+    @property
+    def func_name(self):
+        # backward compatibility
+        return self.__class__.__name__
+
+    def search_selector(self, selector):
+        """search for the given selector or selector instance in the selectors
+        tree. Return it of None if not found
+        """
+        if self is selector:
+            return self
+        if isinstance(selector, type) and isinstance(self, selector):
+            return self
+        return None
+
+    def __str__(self):
+        return self.__class__.__name__
+
+    def __and__(self, other):
+        return AndSelector(self, other)
+    def __rand__(self, other):
+        return AndSelector(other, self)
+
+    def __or__(self, other):
+        return OrSelector(self, other)
+    def __ror__(self, other):
+        return OrSelector(other, self)
+
+    def __invert__(self):
+        return NotSelector(self)
+
+    # XXX (function | function) or (function & function) not managed yet
+
+    def __call__(self, cls, *args, **kwargs):
+        return NotImplementedError("selector %s must implement its logic "
+                                   "in its __call__ method" % self.__class__)
+
+
+class MultiSelector(Selector):
+    """base class for compound selector classes"""
+
+    def __init__(self, *selectors):
+        self.selectors = self.merge_selectors(selectors)
+
+    def __str__(self):
+        return '%s(%s)' % (self.__class__.__name__,
+                           ','.join(str(s) for s in self.selectors))
+
+    @classmethod
+    def merge_selectors(cls, selectors):
+        """deal with selector instanciation when necessary and merge
+        multi-selectors if possible:
 
-class AppObject(VObject):
-    """This is the base class for CubicWeb application objects
-    which are selected according to a request and result set.
+        AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
+        ==> AndSelector(sel1, sel2, sel3, sel4)
+        """
+        merged_selectors = []
+        for selector in selectors:
+            try:
+                selector = _instantiate_selector(selector)
+            except:
+                pass
+            #assert isinstance(selector, Selector), selector
+            if isinstance(selector, cls):
+                merged_selectors += selector.selectors
+            else:
+                merged_selectors.append(selector)
+        return merged_selectors
+
+    def search_selector(self, selector):
+        """search for the given selector or selector instance in the selectors
+        tree. Return it of None if not found
+        """
+        for childselector in self.selectors:
+            if childselector is selector:
+                return childselector
+            found = childselector.search_selector(selector)
+            if found is not None:
+                return found
+        return None
+
+
+class AndSelector(MultiSelector):
+    """and-chained selectors (formerly known as chainall)"""
+    def __call__(self, cls, *args, **kwargs):
+        score = 0
+        for selector in self.selectors:
+            partscore = selector(cls, *args, **kwargs)
+            if not partscore:
+                return 0
+            score += partscore
+        return score
+
 
-    Classes are kept in the vregistry and instantiation is done at selection
-    time.
+class OrSelector(MultiSelector):
+    """or-chained selectors (formerly known as chainfirst)"""
+    def __call__(self, cls, *args, **kwargs):
+        for selector in self.selectors:
+            partscore = selector(cls, *args, **kwargs)
+            if partscore:
+                return partscore
+        return 0
+
+class NotSelector(Selector):
+    """negation selector"""
+    def __init__(self, selector):
+        self.selector = selector
+
+    def __call__(self, cls, *args, **kwargs):
+        score = self.selector(cls, *args, **kwargs)
+        return int(not score)
+
+    def __str__(self):
+        return 'NOT(%s)' % super(NotSelector, self).__str__()
+
+
+class yes(Selector):
+    """return arbitrary score
+
+    default score of 0.5 so any other selector take precedence
+    """
+    def __init__(self, score=0.5):
+        self.score = score
+
+    def __call__(self, *args, **kwargs):
+        return self.score
+
+
+# the base class for all appobjects ############################################
+
+class AppObject(object):
+    """This is the base class for CubicWeb application objects which are
+    selected according to a context (usually at least a request and a result
+    set).
+
+    Concrete application objects classes are designed to be loaded by the
+    vregistry and should be accessed through it, not by direct instantiation.
+
+    The following attributes should be set on concret appobject classes:
+    :__registry__:
+      name of the registry for this object (string like 'views',
+      'templates'...)
+    :id:
+      object's identifier in the registry (string like 'main',
+      'primary', 'folder_box')
+    :__select__:
+      class'selector
+
+    Moreover, the `__abstract__` attribute may be set to True to indicate
+    that a appobject is abstract and should not be registered.
 
     At registration time, the following attributes are set on the class:
     :vreg:
@@ -46,20 +237,64 @@
     :config:
       the instance's configuration
 
-    At instantiation time, the following attributes are set on the instance:
+    At selection time, the following attributes are set on the instance:
     :req:
       current request
     :rset:
-      result set on which the object is applied
+      context result set or None
+    :row:
+      if a result set is set and the context is about a particular cell in the
+      result set, and not the result set as a whole, specify the row number we
+      are interested in, else None
+    :col:
+      if a result set is set and the context is about a particular cell in the
+      result set, and not the result set as a whole, specify the col number we
+      are interested in, else None
     """
+    __registry__ = None
+    id = None
     __select__ = yes()
 
     @classmethod
-    def registered(cls, reg):
-        super(AppObject, cls).registered(reg)
-        cls.vreg = reg.vreg
-        cls.schema = reg.schema
-        cls.config = reg.config
+    def classid(cls):
+        """returns a unique identifier for the appobject"""
+        return '%s.%s' % (cls.__module__, cls.__name__)
+
+    # XXX bw compat code
+    @classmethod
+    def build___select__(cls):
+        for klass in cls.mro():
+            if klass.__name__ == 'AppObject':
+                continue # the bw compat __selector__ is there
+            klassdict = klass.__dict__
+            if ('__select__' in klassdict and '__selectors__' in klassdict
+                and '__selgenerated__' not in klassdict):
+                raise TypeError("__select__ and __selectors__ can't be used together on class %s" % cls)
+            if '__selectors__' in klassdict and '__selgenerated__' not in klassdict:
+                cls.__selgenerated__ = True
+                # case where __selectors__ is defined locally (but __select__
+                # is in a parent class)
+                selectors = klassdict['__selectors__']
+                if len(selectors) == 1:
+                    # micro optimization: don't bother with AndSelector if there's
+                    # only one selector
+                    select = _instantiate_selector(selectors[0])
+                else:
+                    select = AndSelector(*selectors)
+                cls.__select__ = select
+
+    @classmethod
+    def registered(cls, registry):
+        """called by the registry when the appobject has been registered.
+
+        It must return the object that will be actually registered (this may be
+        the right hook to create an instance for example). By default the
+        appobject is returned without any transformation.
+        """
+        cls.build___select__()
+        cls.vreg = registry.vreg
+        cls.schema = registry.schema
+        cls.config = registry.config
         cls.register_properties()
         return cls
 
@@ -69,9 +304,13 @@
 
     @classmethod
     def selected(cls, *args, **kwargs):
-        """by default web app objects are usually instantiated on
-        selection according to a request, a result set, and optional
-        row and col
+        """called by the registry when the appobject has been selected.
+
+        It must return the object that will be actually returned by the .select
+        method (this may be the right hook to create an instance for
+        example). By default the selected object is called using the given args
+        and kwargs and the resulting value (usually a class instance) is
+        returned without any transformation.
         """
         return cls(*args, **kwargs)
 
@@ -340,3 +579,5 @@
         first = rql.split(' ', 1)[0].lower()
         if first in ('insert', 'set', 'delete'):
             raise Unauthorized(self.req._('only select queries are authorized'))
+
+set_log_methods(AppObject, getLogger('cubicweb.appobject'))
--- a/common/test/unittest_migration.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/common/test/unittest_migration.py	Mon Aug 03 15:16:47 2009 +0200
@@ -37,8 +37,8 @@
         self.config = MigrTestConfig('data')
         from yams.schema import Schema
         self.config.load_schema = lambda expand_cubes=False: Schema('test')
-        self.config.__class__.cubicweb_vobject_path = frozenset()
-        self.config.__class__.cube_vobject_path = frozenset()
+        self.config.__class__.cubicweb_appobject_path = frozenset()
+        self.config.__class__.cube_appobject_path = frozenset()
 
     def test_filter_scripts_base(self):
         self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,3,0), (2,4,0)),
--- a/cwconfig.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/cwconfig.py	Mon Aug 03 15:16:47 2009 +0200
@@ -142,7 +142,7 @@
     name = None
     # log messages format (see logging module documentation for available keys)
     log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s'
-    # nor remove vobjects based on unused interface
+    # nor remove appobjects based on unused interface
     cleanup_interface_sobjects = True
 
     if os.environ.get('APYCOT_ROOT'):
@@ -419,8 +419,8 @@
             except Exception, ex:
                 cls.warning("can't init cube %s: %s", cube, ex)
 
-    cubicweb_vobject_path = set(['entities'])
-    cube_vobject_path = set(['entities'])
+    cubicweb_appobject_path = set(['entities'])
+    cube_appobject_path = set(['entities'])
 
     @classmethod
     def build_vregistry_path(cls, templpath, evobjpath=None, tvobjpath=None):
@@ -430,13 +430,13 @@
         :param evobjpath:
           optional list of sub-directories (or files without the .py ext) of
           the cubicweb library that should be tested and added to the output list
-          if they exists. If not give, default to `cubicweb_vobject_path` class
+          if they exists. If not give, default to `cubicweb_appobject_path` class
           attribute.
         :param tvobjpath:
           optional list of sub-directories (or files without the .py ext) of
           directories given in `templpath` that should be tested and added to
           the output list if they exists. If not give, default to
-          `cube_vobject_path` class attribute.
+          `cube_appobject_path` class attribute.
         """
         vregpath = cls.build_vregistry_cubicweb_path(evobjpath)
         vregpath += cls.build_vregistry_cube_path(templpath, tvobjpath)
@@ -446,7 +446,7 @@
     def build_vregistry_cubicweb_path(cls, evobjpath=None):
         vregpath = []
         if evobjpath is None:
-            evobjpath = cls.cubicweb_vobject_path
+            evobjpath = cls.cubicweb_appobject_path
         for subdir in evobjpath:
             path = join(CW_SOFTWARE_ROOT, subdir)
             if exists(path):
@@ -457,7 +457,7 @@
     def build_vregistry_cube_path(cls, templpath, tvobjpath=None):
         vregpath = []
         if tvobjpath is None:
-            tvobjpath = cls.cube_vobject_path
+            tvobjpath = cls.cube_appobject_path
         for directory in templpath:
             for subdir in tvobjpath:
                 path = join(directory, subdir)
--- a/cwvreg.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/cwvreg.py	Mon Aug 03 15:16:47 2009 +0200
@@ -34,7 +34,7 @@
             if impl:
                 return sorted(impl.expected_ifaces)
         except AttributeError:
-            pass # old-style vobject classes with no accepts_interfaces
+            pass # old-style appobject classes with no accepts_interfaces
         except:
             print 'bad selector %s on %s' % (obj.__select__, obj)
             raise
@@ -308,7 +308,7 @@
         # we may want to keep interface dependent objects (e.g.for i18n
         # catalog generation)
         if self.config.cleanup_interface_sobjects:
-            # remove vobjects that don't support any available interface
+            # remove appobjects that don't support any available interface
             implemented_interfaces = set()
             if 'Any' in self.get('etypes', ()):
                 for etype in self.schema.entities():
@@ -323,7 +323,7 @@
                                    or iface
                                    for iface in ifaces)
                 if not ('Any' in ifaces or ifaces & implemented_interfaces):
-                    self.debug('kicking vobject %s (no implemented '
+                    self.debug('kicking appobject %s (no implemented '
                                'interface among %s)', obj, ifaces)
                     self.unregister(obj)
         # clear needs_iface so we don't try to remove some not-anymore-in
--- a/dbapi.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/dbapi.py	Mon Aug 03 15:16:47 2009 +0200
@@ -17,6 +17,7 @@
 
 from logilab.common.logging_ext import set_log_methods
 from logilab.common.decorators import monkeypatch
+from logilab.common.deprecation import deprecated
 
 from cubicweb import ETYPE_NAME_MAP, ConnectionError, RequestSessionMixIn
 from cubicweb import cwvreg, cwconfig
@@ -29,10 +30,10 @@
     except KeyError:
         return ''
 
-def _fix_cls_attrs(reg, vobject):
-    vobject.vreg = reg.vreg
-    vobject.schema = reg.schema
-    vobject.config = reg.config
+def _fix_cls_attrs(reg, appobject):
+    appobject.vreg = reg.vreg
+    appobject.schema = reg.schema
+    appobject.config = reg.config
 
 def multiple_connections_fix():
     """some monkey patching necessary when an application has to deal with
@@ -43,15 +44,15 @@
     defaultcls = cwvreg.VRegistry.REGISTRY_FACTORY[None]
     orig_select_best = defaultcls.orig_select_best = defaultcls.select_best
     @monkeypatch(defaultcls)
-    def select_best(self, vobjects, *args, **kwargs):
+    def select_best(self, appobjects, *args, **kwargs):
         """return an instance of the most specific object according
         to parameters
 
         raise NoSelectableObject if no object apply
         """
-        for vobjectcls in vobjects:
-            _fix_cls_attrs(self, vobjectcls)
-        selected = orig_select_best(self, vobjects, *args, **kwargs)
+        for appobjectcls in appobjects:
+            _fix_cls_attrs(self, appobjectcls)
+        selected = orig_select_best(self, appobjects, *args, **kwargs)
         # redo the same thing on the instance so it won't use equivalent class
         # attributes (which may change)
         _fix_cls_attrs(self, selected)
@@ -448,7 +449,7 @@
             raise ProgrammingError('Closed connection')
         return self._repo.get_schema()
 
-    def load_vobjects(self, cubes=_MARKER, subpath=None, expand=True,
+    def load_appobjects(self, cubes=_MARKER, subpath=None, expand=True,
                       force_reload=None):
         config = self.vreg.config
         if cubes is _MARKER:
@@ -481,11 +482,13 @@
             if self._repo.config.instance_hooks:
                 hm.register_hooks(config.load_hooks(self.vreg))
 
+    load_vobjects = deprecated()(load_appobjects)
+
     def use_web_compatible_requests(self, baseurl, sitetitle=None):
         """monkey patch DBAPIRequest to fake a cw.web.request, so you should
         able to call html views using rset from a simple dbapi connection.
 
-        You should call `load_vobjects` at some point to register those views.
+        You should call `load_appobjects` at some point to register those views.
         """
         from cubicweb.web.request import CubicWebRequestBase as cwrb
         DBAPIRequest.build_ajax_replace_url = cwrb.build_ajax_replace_url.im_func
--- a/devtools/__init__.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/devtools/__init__.py	Mon Aug 03 15:16:47 2009 +0200
@@ -142,8 +142,8 @@
 class BaseApptestConfiguration(TestServerConfiguration, TwistedConfiguration):
     repo_method = 'inmemory'
     options = merge_options(TestServerConfiguration.options + TwistedConfiguration.options)
-    cubicweb_vobject_path = TestServerConfiguration.cubicweb_vobject_path | TwistedConfiguration.cubicweb_vobject_path
-    cube_vobject_path = TestServerConfiguration.cube_vobject_path | TwistedConfiguration.cube_vobject_path
+    cubicweb_appobject_path = TestServerConfiguration.cubicweb_appobject_path | TwistedConfiguration.cubicweb_appobject_path
+    cube_appobject_path = TestServerConfiguration.cube_appobject_path | TwistedConfiguration.cube_appobject_path
 
     def available_languages(self, *args):
         return ('en', 'fr', 'de')
--- a/devtools/devctl.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/devtools/devctl.py	Mon Aug 03 15:16:47 2009 +0200
@@ -29,8 +29,8 @@
 class DevCubeConfiguration(ServerConfiguration, WebConfiguration):
     """dummy config to get full library schema and entities"""
     creating = True
-    cubicweb_vobject_path = ServerConfiguration.cubicweb_vobject_path | WebConfiguration.cubicweb_vobject_path
-    cube_vobject_path = ServerConfiguration.cube_vobject_path | WebConfiguration.cube_vobject_path
+    cubicweb_appobject_path = ServerConfiguration.cubicweb_appobject_path | WebConfiguration.cubicweb_appobject_path
+    cube_appobject_path = ServerConfiguration.cube_appobject_path | WebConfiguration.cube_appobject_path
 
     def __init__(self, cube):
         super(DevCubeConfiguration, self).__init__(cube)
--- a/devtools/testlib.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/devtools/testlib.py	Mon Aug 03 15:16:47 2009 +0200
@@ -377,9 +377,9 @@
                 rset2 = rset.limit(limit=1, offset=row)
                 yield rset2
 
-def not_selected(vreg, vobject):
+def not_selected(vreg, appobject):
     try:
-        vreg._selected[vobject.__class__] -= 1
+        vreg._selected[appobject.__class__] -= 1
     except (KeyError, AttributeError):
         pass
 
@@ -405,7 +405,7 @@
     for regname, reg in testclass._env.vreg.iteritems():
         if regname in skipregs:
             continue
-        for vobjects in reg.itervalues():
-            for vobject in vobjects:
-                if not reg._selected.get(vobject):
-                    print 'not tested', regname, vobject
+        for appobjects in reg.itervalues():
+            for appobject in appobjects:
+                if not reg._selected.get(appobject):
+                    print 'not tested', regname, appobject
--- a/entities/test/unittest_base.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/entities/test/unittest_base.py	Mon Aug 03 15:16:47 2009 +0200
@@ -266,7 +266,7 @@
         class MyUser(CWUser):
             __implements__ = (IMileStone,)
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(MyUser)
+        self.vreg.register_appobject_class(MyUser)
         self.failUnless(implements(CWUser, IWorkflowable))
         self.failUnless(implements(MyUser, IMileStone))
         self.failUnless(implements(MyUser, IWorkflowable))
@@ -290,7 +290,7 @@
         for etype in ('Company', 'Division', 'SubDivision'):
             class Foo(AnyEntity):
                 id = etype
-            self.vreg.register_vobject_class(Foo)
+            self.vreg.register_appobject_class(Foo)
             eclass = self.select_eclass('SubDivision')
             if etype == 'SubDivision':
                 self.failUnless(eclass is Foo)
--- a/etwist/server.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/etwist/server.py	Mon Aug 03 15:16:47 2009 +0200
@@ -330,7 +330,7 @@
 def _gc_debug():
     import gc
     from pprint import pprint
-    from cubicweb.vregistry import VObject
+    from cubicweb.appobject import AppObject
     gc.collect()
     count = 0
     acount = 0
@@ -338,7 +338,7 @@
     for obj in gc.get_objects():
         if isinstance(obj, CubicWebTwistedRequestAdapter):
             count += 1
-        elif isinstance(obj, VObject):
+        elif isinstance(obj, AppObject):
             acount += 1
         else:
             try:
--- a/etwist/twconfig.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/etwist/twconfig.py	Mon Aug 03 15:16:47 2009 +0200
@@ -87,8 +87,8 @@
         options = merge_options(TwistedConfiguration.options
                                 + ServerConfiguration.options)
 
-        cubicweb_vobject_path = TwistedConfiguration.cubicweb_vobject_path | ServerConfiguration.cubicweb_vobject_path
-        cube_vobject_path = TwistedConfiguration.cube_vobject_path | ServerConfiguration.cube_vobject_path
+        cubicweb_appobject_path = TwistedConfiguration.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
+        cube_appobject_path = TwistedConfiguration.cube_appobject_path | ServerConfiguration.cube_appobject_path
         def pyro_enabled(self):
             """tell if pyro is activated for the in memory repository"""
             return self['pyro-server']
--- a/goa/goaconfig.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/goa/goaconfig.py	Mon Aug 03 15:16:47 2009 +0200
@@ -81,9 +81,9 @@
     options = [(optname, optdict) for optname, optdict in options
                if not optname in UNSUPPORTED_OPTIONS]
 
-    cubicweb_vobject_path = WebConfiguration.cubicweb_vobject_path | ServerConfiguration.cubicweb_vobject_path
-    cubicweb_vobject_path = list(cubicweb_vobject_path) + ['goa/appobjects']
-    cube_vobject_path = WebConfiguration.cube_vobject_path | ServerConfiguration.cube_vobject_path
+    cubicweb_appobject_path = WebConfiguration.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
+    cubicweb_appobject_path = list(cubicweb_appobject_path) + ['goa/appobjects']
+    cube_appobject_path = WebConfiguration.cube_appobject_path | ServerConfiguration.cube_appobject_path
 
     # use file system schema
     bootstrap_schema = read_instance_schema = False
--- a/goa/goavreg.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/goa/goavreg.py	Mon Aug 03 15:16:47 2009 +0200
@@ -59,7 +59,7 @@
         self.load_module(obj)
 
     def _auto_load(self, path, loadschema, cube=None):
-        vobjpath = self.config.cube_vobject_path
+        vobjpath = self.config.cube_appobject_path
         for filename in listdir(path):
             if filename[-3:] == '.py' and filename[:-3] in vobjpath:
                 self._import(_pkg_name(cube, filename[:-3]))
--- a/selectors.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/selectors.py	Mon Aug 03 15:16:47 2009 +0200
@@ -53,8 +53,8 @@
 
 from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity,
                       role, typed_eid)
-from cubicweb.vregistry import (NoSelectableObject, Selector,
-                                chainall, objectify_selector)
+# even if not used, let yes here so it's importable through this module
+from cubicweb.appobject import Selector, objectify_selector, yes
 from cubicweb.cwconfig import CubicWebConfiguration
 from cubicweb.schema import split_expression
 
@@ -274,17 +274,6 @@
 
 # very basic selectors ########################################################
 
-class yes(Selector):
-    """return arbitrary score
-
-    default score of 0.5 so any other selector take precedence
-    """
-    def __init__(self, score=0.5):
-        self.score = score
-
-    def __call__(self, *args, **kwargs):
-        return self.score
-
 @objectify_selector
 @lltrace
 def none_rset(cls, req, rset=None, **kwargs):
@@ -975,6 +964,7 @@
 
 
 # XXX DEPRECATED ##############################################################
+from cubicweb.vregistry import chainall
 
 yes_selector = deprecated()(yes)
 norset_selector = deprecated()(none_rset)
@@ -1040,7 +1030,7 @@
 accept_selector = deprecated()(accept)
 
 accept_one = deprecated()(chainall(one_line_rset, accept,
-                                          name='accept_one'))
+                                   name='accept_one'))
 accept_one_selector = deprecated()(accept_one)
 
 
--- a/server/serverconfig.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/server/serverconfig.py	Mon Aug 03 15:16:47 2009 +0200
@@ -85,8 +85,8 @@
         SCHEMAS_LIB_DIR = '/usr/share/cubicweb/schemas/'
         BACKUP_DIR = '/var/lib/cubicweb/backup/'
 
-    cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['sobjects'])
-    cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['sobjects', 'hooks'])
+    cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['sobjects'])
+    cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['sobjects', 'hooks'])
 
     options = merge_options((
         # ctl configuration
--- a/test/unittest_rtags.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/test/unittest_rtags.py	Mon Aug 03 15:16:47 2009 +0200
@@ -39,7 +39,7 @@
 #             __rtags__ = {
 #                 ('evaluee', 'Note', 'subject') : set(('inlineview',)),
 #                 }
-#         self.vreg.register_vobject_class(Personne2)
+#         self.vreg.register_appobject_class(Personne2)
 #         rtags = Personne2.rtags
 #         self.assertEquals(rtags.rtag('evaluee', 'Note', 'subject'), set(('inlineview', 'link')))
 #         self.assertEquals(rtags.is_inlined('evaluee', 'Note', 'subject'), True)
--- a/test/unittest_selectors.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/test/unittest_selectors.py	Mon Aug 03 15:16:47 2009 +0200
@@ -9,7 +9,7 @@
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb.devtools.testlib import EnvBasedTC
-from cubicweb.vregistry import Selector, AndSelector, OrSelector
+from cubicweb.appobject import Selector, AndSelector, OrSelector
 from cubicweb.selectors import implements, match_user_groups
 from cubicweb.interfaces import IDownloadable
 from cubicweb.web import action
@@ -91,7 +91,7 @@
 class ImplementsSelectorTC(EnvBasedTC):
     def test_etype_priority(self):
         req = self.request()
-        cls = self.vreg.etype_class('File')
+        cls = self.vreg['etypes'].etype_class('File')
         anyscore = implements('Any').score_class(cls, req)
         idownscore = implements(IDownloadable).score_class(cls, req)
         self.failUnless(idownscore > anyscore, (idownscore, anyscore))
@@ -99,7 +99,7 @@
         self.failUnless(filescore > idownscore, (filescore, idownscore))
 
     def test_etype_inheritance_no_yams_inheritance(self):
-        cls = self.vreg.etype_class('Personne')
+        cls = self.vreg['etypes'].etype_class('Personne')
         self.failIf(implements('Societe').score_class(cls, self.request()))
 
 
@@ -111,7 +111,7 @@
             category = 'foo'
             __select__ = match_user_groups('owners')
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(SomeAction)
+        self.vreg.register_appobject_class(SomeAction)
         self.failUnless(SomeAction in self.vreg['actions']['yo'], self.vreg['actions'])
         try:
             # login as a simple user
--- a/test/unittest_vregistry.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/test/unittest_vregistry.py	Mon Aug 03 15:16:47 2009 +0200
@@ -10,7 +10,7 @@
 from os.path import join
 
 from cubicweb import CW_SOFTWARE_ROOT as BASE
-from cubicweb.vregistry import VObject
+from cubicweb.appobject import AppObject
 from cubicweb.cwvreg import CubicWebVRegistry, UnknownProperty
 from cubicweb.devtools import TestServerConfiguration
 from cubicweb.interfaces import IMileStone
@@ -43,7 +43,7 @@
     def test___selectors__compat(self):
         myselector1 = lambda *args: 1
         myselector2 = lambda *args: 1
-        class AnAppObject(VObject):
+        class AnAppObject(AppObject):
             __selectors__ = (myselector1, myselector2)
         AnAppObject.build___select__()
         self.assertEquals(AnAppObject.__select__(AnAppObject), 2)
@@ -53,7 +53,7 @@
         self.failUnless(self.vreg.property_info('system.version.cubicweb'))
         self.assertRaises(UnknownProperty, self.vreg.property_info, 'a.non.existent.key')
 
-    def test_load_subinterface_based_vobjects(self):
+    def test_load_subinterface_based_appobjects(self):
         self.vreg.reset()
         self.vreg.register_objects([join(BASE, 'web', 'views', 'iprogress.py')])
         # check progressbar was kicked
@@ -62,7 +62,7 @@
             __implements__ = (IMileStone,)
         self.vreg.reset()
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(MyCard)
+        self.vreg.register_appobject_class(MyCard)
         self.vreg.register_objects([join(BASE, 'entities', '__init__.py'),
                                     join(BASE, 'web', 'views', 'iprogress.py')])
         # check progressbar isn't kicked
--- a/utils.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/utils.py	Mon Aug 03 15:16:47 2009 +0200
@@ -321,7 +321,7 @@
 
 
 class AcceptMixIn(object):
-    """Mixin class for vobjects defining the 'accepts' attribute describing
+    """Mixin class for appobjects defining the 'accepts' attribute describing
     a set of supported entity type (Any by default).
     """
     # XXX deprecated, no more necessary
--- a/vregistry.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/vregistry.py	Mon Aug 03 15:16:47 2009 +0200
@@ -5,13 +5,13 @@
   according to a context
 
 * to interact with the vregistry, objects should inherit from the
-  VObject abstract class
+  AppObject abstract class
 
 * the selection procedure has been generalized by delegating to a
-  selector, which is responsible to score the vobject according to the
+  selector, which is responsible to score the appobject according to the
   current state (req, rset, row, col). At the end of the selection, if
-  a vobject class has been found, an instance of this class is
-  returned. The selector is instantiated at vobject registration
+  a appobject class has been found, an instance of this class is
+  returned. The selector is instantiated at appobject registration
 
 
 :organization: Logilab
@@ -22,17 +22,18 @@
 __docformat__ = "restructuredtext en"
 
 import sys
-import types
 from os import listdir, stat
 from os.path import dirname, join, realpath, split, isdir, exists
 from logging import getLogger
 from warnings import warn
 
-from logilab.common.deprecation import deprecated
+from logilab.common.deprecation import deprecated, class_moved
+from logilab.common.logging_ext import set_log_methods
 
-from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
+from cubicweb import CW_SOFTWARE_ROOT
 from cubicweb import (RegistryNotFound, ObjectNotFound, NoSelectableObject,
                       RegistryOutOfDate)
+from cubicweb.appobject import AppObject
 
 # XXX depending on cubicweb.web is ugly, we should deal with uicfg
 #     reset with a good old event / callback system
@@ -60,80 +61,6 @@
     return _toload
 
 
-class VObject(object):
-    """visual object, use to be handled somehow by the visual components
-    registry.
-
-    The following attributes should be set on concret vobject subclasses:
-
-    :__registry__:
-      name of the registry for this object (string like 'views',
-      'templates'...)
-    :id:
-      object's identifier in the registry (string like 'main',
-      'primary', 'folder_box')
-    :__select__:
-      class'selector
-
-    Moreover, the `__abstract__` attribute may be set to True to indicate
-    that a vobject is abstract and should not be registered
-    """
-    # necessary attributes to interact with the registry
-    id = None
-    __registry__ = None
-    __select__ = None
-
-    @classmethod
-    def registered(cls, registry):
-        """called by the registry when the vobject has been registered.
-
-        It must return the  object that will be actually registered (this
-        may be the right hook to create an instance for example). By
-        default the vobject is returned without any transformation.
-        """
-        cls.build___select__()
-        return cls
-
-    @classmethod
-    def selected(cls, *args, **kwargs):
-        """called by the registry when the vobject has been selected.
-
-        It must return the  object that will be actually returned by the
-        .select method (this may be the right hook to create an
-        instance for example). By default the selected object is
-        returned without any transformation.
-        """
-        return cls
-
-    @classmethod
-    def classid(cls):
-        """returns a unique identifier for the vobject"""
-        return '%s.%s' % (cls.__module__, cls.__name__)
-
-    # XXX bw compat code
-    @classmethod
-    def build___select__(cls):
-        for klass in cls.mro():
-            if klass.__name__ == 'AppObject':
-                continue # the bw compat __selector__ is there
-            klassdict = klass.__dict__
-            if ('__select__' in klassdict and '__selectors__' in klassdict
-                and '__selgenerated__' not in klassdict):
-                raise TypeError("__select__ and __selectors__ can't be used together on class %s" % cls)
-            if '__selectors__' in klassdict and '__selgenerated__' not in klassdict:
-                cls.__selgenerated__ = True
-                # case where __selectors__ is defined locally (but __select__
-                # is in a parent class)
-                selectors = klassdict['__selectors__']
-                if len(selectors) == 1:
-                    # micro optimization: don't bother with AndSelector if there's
-                    # only one selector
-                    select = _instantiate_selector(selectors[0])
-                else:
-                    select = AndSelector(*selectors)
-                cls.__select__ = select
-
-
 class Registry(dict):
 
     def __init__(self, config):
@@ -155,16 +82,16 @@
         oid = oid or obj.id
         assert oid
         if clear:
-            vobjects = self[oid] =  []
+            appobjects = self[oid] =  []
         else:
-            vobjects = self.setdefault(oid, [])
+            appobjects = self.setdefault(oid, [])
         # registered() is technically a classmethod but is not declared
         # as such because we need to compose registered in some cases
-        vobject = obj.registered.im_func(obj, self)
-        assert not vobject in vobjects, \
-               'object %s is already registered' % vobject
-        assert callable(vobject.__select__), vobject
-        vobjects.append(vobject)
+        appobject = obj.registered.im_func(obj, self)
+        assert not appobject in appobjects, \
+               'object %s is already registered' % appobject
+        assert callable(appobject.__select__), appobject
+        appobjects.append(appobject)
 
     def register_and_replace(self, obj, replaced):
         # XXXFIXME this is a duplication of unregister()
@@ -238,13 +165,13 @@
         """return an iterator on possible objects in this registry for the given
         context
         """
-        for vobjects in self.itervalues():
+        for appobjects in self.itervalues():
             try:
-                yield self.select_best(vobjects, *args, **kwargs)
+                yield self.select_best(appobjects, *args, **kwargs)
             except NoSelectableObject:
                 continue
 
-    def select_best(self, vobjects, *args, **kwargs):
+    def select_best(self, appobjects, *args, **kwargs):
         """return an instance of the most specific object according
         to parameters
 
@@ -254,16 +181,16 @@
             warn('only the request param can not be named when calling select',
                  DeprecationWarning, stacklevel=3)
         score, winners = 0, []
-        for vobject in vobjects:
-            vobjectscore = vobject.__select__(vobject, *args, **kwargs)
-            if vobjectscore > score:
-                score, winners = vobjectscore, [vobject]
-            elif vobjectscore > 0 and vobjectscore == score:
-                winners.append(vobject)
+        for appobject in appobjects:
+            appobjectscore = appobject.__select__(appobject, *args, **kwargs)
+            if appobjectscore > score:
+                score, winners = appobjectscore, [appobject]
+            elif appobjectscore > 0 and appobjectscore == score:
+                winners.append(appobject)
         if not winners:
             raise NoSelectableObject('args: %s\nkwargs: %s %s'
                                      % (args, kwargs.keys(),
-                                        [repr(v) for v in vobjects]))
+                                        [repr(v) for v in appobjects]))
         if len(winners) > 1:
             if self.config.mode == 'installed':
                 self.error('select ambiguity, args: %s\nkwargs: %s %s',
@@ -272,7 +199,7 @@
                 raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
                                 % (args, kwargs.keys(),
                                    [repr(v) for v in winners]))
-        # return the result of the .selected method of the vobject
+        # return the result of the .selected method of the appobject
         return winners[0].selected(*args, **kwargs)
 
 
@@ -379,7 +306,7 @@
             vname = obj.__name__
         except AttributeError:
             vname = obj.__class__.__name__
-        self.debug('registered vobject %s in registry %s with id %s',
+        self.debug('registered appobject %s in registry %s with id %s',
                    vname, registryname, oid)
         self._loadedmods[obj.__module__]['%s.%s' % (obj.__module__, oid)] = obj
 
@@ -473,7 +400,7 @@
             return
         # skip non registerable object
         try:
-            if not issubclass(obj, VObject):
+            if not issubclass(obj, AppObject):
                 return
         except TypeError:
             return
@@ -487,20 +414,20 @@
 
     def load_object(self, obj):
         try:
-            self.register_vobject_class(obj)
+            self.register_appobject_class(obj)
         except Exception, ex:
             if self.config.mode in ('test', 'dev'):
                 raise
-            self.exception('vobject %s registration failed: %s', obj, ex)
+            self.exception('appobject %s registration failed: %s', obj, ex)
 
     # old automatic registration XXX deprecated ###############################
 
-    def register_vobject_class(self, cls):
-        """handle vobject class registration
+    def register_appobject_class(self, cls):
+        """handle appobject class registration
 
-        vobject class with __abstract__ == True in their local dictionnary or
+        appobject class with __abstract__ == True in their local dictionnary or
         with a name starting starting by an underscore are not registered.
-        Also a vobject class needs to have __registry__ and id attributes set
+        Also a appobject class needs to have __registry__ and id attributes set
         to a non empty string to be registered.
         """
         if (cls.__dict__.get('__abstract__') or cls.__name__[0] == '_'
@@ -512,170 +439,19 @@
         self.register(cls)
 
 # init logging
-set_log_methods(VObject, getLogger('cubicweb.appobject'))
 set_log_methods(VRegistry, getLogger('cubicweb.vreg'))
 set_log_methods(Registry, getLogger('cubicweb.registry'))
 
 
-# selector base classes and operations ########################################
-
-class Selector(object):
-    """base class for selector classes providing implementation
-    for operators ``&`` and ``|``
-
-    This class is only here to give access to binary operators, the
-    selector logic itself should be implemented in the __call__ method
-
-
-    a selector is called to help choosing the correct object for a
-    particular context by returning a score (`int`) telling how well
-    the class given as first argument apply to the given context.
-
-    0 score means that the class doesn't apply.
-    """
-
-    @property
-    def func_name(self):
-        # backward compatibility
-        return self.__class__.__name__
-
-    def search_selector(self, selector):
-        """search for the given selector or selector instance in the selectors
-        tree. Return it of None if not found
-        """
-        if self is selector:
-            return self
-        if isinstance(selector, type) and isinstance(self, selector):
-            return self
-        return None
-
-    def __str__(self):
-        return self.__class__.__name__
-
-    def __and__(self, other):
-        return AndSelector(self, other)
-    def __rand__(self, other):
-        return AndSelector(other, self)
-
-    def __or__(self, other):
-        return OrSelector(self, other)
-    def __ror__(self, other):
-        return OrSelector(other, self)
-
-    def __invert__(self):
-        return NotSelector(self)
-
-    # XXX (function | function) or (function & function) not managed yet
-
-    def __call__(self, cls, *args, **kwargs):
-        return NotImplementedError("selector %s must implement its logic "
-                                   "in its __call__ method" % self.__class__)
-
-class MultiSelector(Selector):
-    """base class for compound selector classes"""
-
-    def __init__(self, *selectors):
-        self.selectors = self.merge_selectors(selectors)
-
-    def __str__(self):
-        return '%s(%s)' % (self.__class__.__name__,
-                           ','.join(str(s) for s in self.selectors))
-
-    @classmethod
-    def merge_selectors(cls, selectors):
-        """deal with selector instanciation when necessary and merge
-        multi-selectors if possible:
-
-        AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
-        ==> AndSelector(sel1, sel2, sel3, sel4)
-        """
-        merged_selectors = []
-        for selector in selectors:
-            try:
-                selector = _instantiate_selector(selector)
-            except:
-                pass
-            #assert isinstance(selector, Selector), selector
-            if isinstance(selector, cls):
-                merged_selectors += selector.selectors
-            else:
-                merged_selectors.append(selector)
-        return merged_selectors
-
-    def search_selector(self, selector):
-        """search for the given selector or selector instance in the selectors
-        tree. Return it of None if not found
-        """
-        for childselector in self.selectors:
-            if childselector is selector:
-                return childselector
-            found = childselector.search_selector(selector)
-            if found is not None:
-                return found
-        return None
-
-
-def objectify_selector(selector_func):
-    """convenience decorator for simple selectors where a class definition
-    would be overkill::
-
-        @objectify_selector
-        def yes(cls, *args, **kwargs):
-            return 1
-
-    """
-    return type(selector_func.__name__, (Selector,),
-                {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
-
-def _instantiate_selector(selector):
-    """ensures `selector` is a `Selector` instance
-
-    NOTE: This should only be used locally in build___select__()
-    XXX: then, why not do it ??
-    """
-    if isinstance(selector, types.FunctionType):
-        return objectify_selector(selector)()
-    if isinstance(selector, type) and issubclass(selector, Selector):
-        return selector()
-    return selector
-
-
-class AndSelector(MultiSelector):
-    """and-chained selectors (formerly known as chainall)"""
-    def __call__(self, cls, *args, **kwargs):
-        score = 0
-        for selector in self.selectors:
-            partscore = selector(cls, *args, **kwargs)
-            if not partscore:
-                return 0
-            score += partscore
-        return score
-
-
-class OrSelector(MultiSelector):
-    """or-chained selectors (formerly known as chainfirst)"""
-    def __call__(self, cls, *args, **kwargs):
-        for selector in self.selectors:
-            partscore = selector(cls, *args, **kwargs)
-            if partscore:
-                return partscore
-        return 0
-
-class NotSelector(Selector):
-    """negation selector"""
-    def __init__(self, selector):
-        self.selector = selector
-
-    def __call__(self, cls, *args, **kwargs):
-        score = self.selector(cls, *args, **kwargs)
-        return int(not score)
-
-    def __str__(self):
-        return 'NOT(%s)' % super(NotSelector, self).__str__()
-
-
 # XXX bw compat functions #####################################################
 
+from cubicweb.appobject import objectify_selector, AndSelector, OrSelector, Selector
+
+objectify_selector = deprecated('objectify_selector has been moved to appobject module')(objectify_selector)
+
+Selector = class_moved(Selector)
+
+@deprecated('use & operator (binary and)')
 def chainall(*selectors, **kwargs):
     """return a selector chaining given selectors. If one of
     the selectors fail, selection will fail, else the returned score
@@ -688,6 +464,7 @@
         selector.__name__ = kwargs['name']
     return selector
 
+@deprecated('use | operator (binary or)')
 def chainfirst(*selectors, **kwargs):
     """return a selector chaining given selectors. If all
     the selectors fail, selection will fail, else the returned score
--- a/web/test/test_views.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/test/test_views.py	Mon Aug 03 15:16:47 2009 +0200
@@ -52,7 +52,7 @@
 
     def test_js_added_only_once(self):
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(SomeView)
+        self.vreg.register_appobject_class(SomeView)
         rset = self.execute('CWUser X')
         source = self.view('someview', rset).source
         self.assertEquals(source.count('spam.js'), 1)
--- a/web/test/unittest_viewselector.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/test/unittest_viewselector.py	Mon Aug 03 15:16:47 2009 +0200
@@ -274,7 +274,7 @@
         class CWUserCreationForm(editforms.CreationFormView):
             __select__ = specified_etype_implements('CWUser')
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(CWUserCreationForm)
+        self.vreg.register_appobject_class(CWUserCreationForm)
         req.form['etype'] = 'CWUser'
         self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
                               CWUserCreationForm)
@@ -431,7 +431,7 @@
     def setUp(self):
         super(RQLActionTC, self).setUp()
         self.vreg._loadedmods[__name__] = {}
-        self.vreg.register_vobject_class(CWETypeRQLAction)
+        self.vreg.register_appobject_class(CWETypeRQLAction)
 
     def tearDown(self):
         super(RQLActionTC, self).tearDown()
--- a/web/views/actions.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/actions.py	Mon Aug 03 15:16:47 2009 +0200
@@ -8,7 +8,7 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
 from cubicweb.selectors import (EntitySelector,
     one_line_rset, two_lines_rset, one_etype_rset, relation_possible,
     nonempty_rset, non_final_entity,
--- a/web/views/basetemplates.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/basetemplates.py	Mon Aug 03 15:16:47 2009 +0200
@@ -10,7 +10,7 @@
 
 from logilab.mtconverter import xml_escape
 
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
 from cubicweb.selectors import match_kwargs
 from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW
 from cubicweb.utils import make_uid, UStringIO
--- a/web/views/facets.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/facets.py	Mon Aug 03 15:16:47 2009 +0200
@@ -11,7 +11,7 @@
 
 from logilab.mtconverter import xml_escape
 
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
 from cubicweb.selectors import (non_final_entity, two_lines_rset,
                                 match_context_prop, yes, relation_possible)
 from cubicweb.web.box import BoxTemplate
--- a/web/views/forms.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/forms.py	Mon Aug 03 15:16:47 2009 +0200
@@ -288,7 +288,8 @@
 
 class EntityFieldsForm(FieldsForm):
     id = 'base'
-    __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
+    __select__ = (match_kwargs('entity')
+                  | (one_line_rset() & non_final_entity()))
 
     internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
     domid = 'entityForm'
--- a/web/views/plots.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/plots.py	Mon Aug 03 15:16:47 2009 +0200
@@ -16,7 +16,7 @@
 from logilab.mtconverter import xml_escape
 
 from cubicweb.utils import make_uid, UStringIO, datetime2ticks
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
 from cubicweb.web.views import baseviews
 
 @objectify_selector
--- a/web/views/urlpublishing.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/views/urlpublishing.py	Mon Aug 03 15:16:47 2009 +0200
@@ -194,9 +194,9 @@
     def evaluate_path(self, req, parts):
         # uri <=> req._twreq.path or req._twreq.uri
         uri = req.url_unquote('/' + '/'.join(parts))
-        vobjects = sorted(self.vreg['urlrewriting'].all_objects(),
-                          key=lambda x: x.priority, reverse=True)
-        for rewritercls in vobjects:
+        evaluators = sorted(self.vreg['urlrewriting'].all_objects(),
+                            key=lambda x: x.priority, reverse=True)
+        for rewritercls in evaluators:
             rewriter = rewritercls()
             try:
                 # XXX we might want to chain url rewrites
--- a/web/webconfig.py	Mon Aug 03 14:14:07 2009 +0200
+++ b/web/webconfig.py	Mon Aug 03 15:16:47 2009 +0200
@@ -63,8 +63,8 @@
     """the WebConfiguration is a singleton object handling instance's
     configuration and preferences
     """
-    cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['web/views'])
-    cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['views'])
+    cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['web/views'])
+    cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['views'])
 
     options = merge_options(CubicWebConfiguration.options + (
         ('anonymous-user',