[appobject selection process] drop the need for the .selected method
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 03 Aug 2009 15:42:47 +0200
changeset 2658 5535857eeaa5
parent 2657 de974465d381
child 2659 b6f6964bddd3
[appobject selection process] drop the need for the .selected method
appobject.py
cwvreg.py
entities/__init__.py
entity.py
vregistry.py
web/facet.py
--- a/appobject.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/appobject.py	Mon Aug 03 15:42:47 2009 +0200
@@ -302,18 +302,6 @@
     def vreg_initialization_completed(cls):
         pass
 
-    @classmethod
-    def selected(cls, *args, **kwargs):
-        """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)
-
     # Eproperties definition:
     # key: id of the property (the actual CWProperty key is build using
     #      <registry name>.<obj id>.<property id>
--- a/cwvreg.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/cwvreg.py	Mon Aug 03 15:42:47 2009 +0200
@@ -16,6 +16,7 @@
 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid,
                       ObjectNotFound, NoSelectableObject, RegistryNotFound,
                       RegistryOutOfDate)
+from cubicweb.utils import dump_class
 from cubicweb.vregistry import VRegistry, Registry
 from cubicweb.rtags import RTAGS
 
@@ -88,6 +89,8 @@
 class ETypeRegistry(CWRegistry):
 
     def initialization_completed(self):
+        """on registration completed, clear etype_class internal cache
+        """
         super(ETypeRegistry, self).initialization_completed()
         # clear etype cache if you don't want to run into deep weirdness
         clear_cache(self, 'etype_class')
@@ -104,30 +107,43 @@
     @cached
     def etype_class(self, etype):
         """return an entity class for the given entity type.
-        Try to find out a specific class for this kind of entity or
-        default to a dump of the class registered for 'Any'
+
+        Try to find out a specific class for this kind of entity or default to a
+        dump of the nearest parent class (in yams inheritance) registered.
+
+        Fall back to 'Any' if not yams parent class found.
         """
         etype = str(etype)
         if etype == 'Any':
             return self.select('Any', 'Any')
         eschema = self.schema.eschema(etype)
         baseschemas = [eschema] + eschema.ancestors()
-        # browse ancestors from most specific to most generic and
-        # try to find an associated custom entity class
+        # browse ancestors from most specific to most generic and try to find an
+        # associated custom entity class
         for baseschema in baseschemas:
             try:
                 btype = ETYPE_NAME_MAP[baseschema]
             except KeyError:
                 btype = str(baseschema)
             try:
-                cls = self.select(btype, etype)
+                objects = self[btype]
+                assert len(objects) == 1, objects
+                cls = objects[0]
                 break
             except ObjectNotFound:
                 pass
         else:
             # no entity class for any of the ancestors, fallback to the default
             # one
-            cls = self.select('Any', etype)
+            objects = self['Any']
+            assert len(objects) == 1, objects
+            cls = objects[0]
+        if cls.id == etype:
+            cls.__initialize__()
+            return cls
+        cls = dump_class(cls, etype)
+        cls.id = etype
+        cls.__initialize__()
         return cls
 
 VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry
--- a/entities/__init__.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/entities/__init__.py	Mon Aug 03 15:42:47 2009 +0200
@@ -14,7 +14,6 @@
 
 from cubicweb import Unauthorized, typed_eid
 from cubicweb.entity import Entity
-from cubicweb.utils import dump_class
 
 from cubicweb.interfaces import IBreadCrumbs, IFeed
 
@@ -26,19 +25,6 @@
     id = 'Any'
     __implements__ = (IBreadCrumbs, IFeed)
 
-    @classmethod
-    def selected(cls, etype):
-        """the special Any entity is used as the default factory, so
-        the actual class has to be constructed at selection time once we
-        have an actual entity'type
-        """
-        if cls.id == etype:
-            return cls
-        usercls = dump_class(cls, etype)
-        usercls.id = etype
-        usercls.__initialize__()
-        return usercls
-
     fetch_attrs = ('modification_date',)
     @classmethod
     def fetch_order(cls, attr, var):
--- a/entity.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/entity.py	Mon Aug 03 15:42:47 2009 +0200
@@ -167,15 +167,6 @@
     # class attributes set automatically at registration time
     e_schema = None
 
-    @classmethod
-    def registered(cls, registry):
-        """build class using descriptor at registration time"""
-        assert cls.id is not None
-        super(Entity, cls).registered(registry)
-        if cls.id != 'Any':
-            cls.__initialize__()
-        return cls
-
     MODE_TAGS = set(('link', 'create'))
     CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
     @classmethod
--- a/vregistry.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/vregistry.py	Mon Aug 03 15:42:47 2009 +0200
@@ -141,7 +141,7 @@
         """
         objects = self[oid]
         assert len(objects) == 1, objects
-        return objects[0].selected(*args, **kwargs)
+        return objects[0](*args, **kwargs)
 
     def select(self, oid, *args, **kwargs):
         """return the most specific object among those with the given oid
@@ -199,8 +199,8 @@
                 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 appobject
-        return winners[0].selected(*args, **kwargs)
+        # return the result of calling the appobject
+        return winners[0](*args, **kwargs)
 
 
 class VRegistry(dict):
--- a/web/facet.py	Mon Aug 03 15:16:47 2009 +0200
+++ b/web/facet.py	Mon Aug 03 15:42:47 2009 +0200
@@ -259,22 +259,18 @@
     needs_update = False
     start_unfolded = True
 
-    @classmethod
-    def selected(cls, req, rset=None, rqlst=None, context=None,
-                 filtered_variable=None):
+    def __init__(self, req, rset=None, rqlst=None, filtered_variable=None,
+                 **kwargs):
+        super(AbstractFacet, self).__init__(req, rset, **kwargs)
         assert rset is not None or rqlst is not None
         assert filtered_variable
-        instance = super(AbstractFacet, cls).selected(req, rset)
-        #instance = AppObject.selected(req, rset)
-        #instance.__class__ = cls
         # facet retreived using `object_by_id` from an ajax call
         if rset is None:
-            instance.init_from_form(rqlst=rqlst)
+            self.init_from_form(rqlst=rqlst)
         # facet retreived from `select` using the result set to filter
         else:
-            instance.init_from_rset()
-        instance.filtered_variable = filtered_variable
-        return instance
+            self.init_from_rset()
+        self.filtered_variable = filtered_variable
 
     def init_from_rset(self):
         self.rqlst = self.rset.syntax_tree().children[0]