merge tls-sprint
authorsylvain.thenault@logilab.fr
Tue, 17 Feb 2009 23:00:28 +0100
branchtls-sprint
changeset 714 39a2a6673171
parent 709 b21ee900c732 (current diff)
parent 713 5adb6d8e5fa7 (diff)
child 715 83228d379cbe
merge
appobject.py
entity.py
vregistry.py
web/views/actions.py
--- a/appobject.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/appobject.py	Tue Feb 17 23:00:28 2009 +0100
@@ -58,6 +58,7 @@
 
     @classmethod
     def registered(cls, vreg):
+        super(AppRsetObject, cls).registered(vregistry)
         cls.vreg = vreg
         cls.schema = vreg.schema
         cls.config = vreg.config
--- a/entities/__init__.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/entities/__init__.py	Tue Feb 17 23:00:28 2009 +0100
@@ -12,8 +12,8 @@
 from logilab.common.decorators import cached
 
 from cubicweb import Unauthorized, typed_eid
+from cubicweb.entity import Entity
 from cubicweb.common.utils import dump_class
-from cubicweb.common.entity import Entity
 from cubicweb.schema import FormatConstraint
 
 from cubicweb.interfaces import IBreadCrumbs, IFeed
--- a/entities/lib.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/entities/lib.py	Tue Feb 17 23:00:28 2009 +0100
@@ -11,7 +11,7 @@
 
 from logilab.common.decorators import cached
 
-from cubicweb.common.entity import _marker
+from cubicweb.entity import _marker
 from cubicweb.entities import AnyEntity, fetch_config
 
 def mangle_email(address):
--- a/entity.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/entity.py	Tue Feb 17 23:00:28 2009 +0100
@@ -14,7 +14,6 @@
 from rql.utils import rqlvar_maker
 
 from cubicweb import Unauthorized
-from cubicweb.vregistry import autoselectors
 from cubicweb.rset import ResultSet
 from cubicweb.selectors import yes
 from cubicweb.appobject import AppRsetObject
@@ -172,7 +171,7 @@
         return 'inlineview' in self.get_tags(rtype, targettype, role)
 
 
-class metaentity(autoselectors):
+class metaentity(type):
     """this metaclass sets the relation tags on the entity class
     and deals with the `widgets` attribute
     """
--- a/goa/db.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/goa/db.py	Tue Feb 17 23:00:28 2009 +0100
@@ -25,7 +25,7 @@
 * XXX ListProperty
 
 :organization: Logilab
-:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
@@ -37,7 +37,7 @@
 
 from cubicweb import RequestSessionMixIn, Binary, entities
 from cubicweb.rset import ResultSet
-from cubicweb.common.entity import metaentity
+from cubicweb.entity import metaentity
 from cubicweb.server.utils import crypt_password
 from cubicweb.goa import use_mx_for_dates, mx2datetime, MODE
 from cubicweb.goa.dbinit import init_relations
--- a/goa/goactl.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/goa/goactl.py	Tue Feb 17 23:00:28 2009 +0100
@@ -1,7 +1,7 @@
 """cubicweb on appengine plugins for cubicweb-ctl
 
 :organization: Logilab
-:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
@@ -50,6 +50,7 @@
     'dbapi.py',
     'cwvreg.py',
     'cwconfig.py',
+    'entity.py',
     'interfaces.py',
     'rset.py',
     'schema.py',
@@ -58,7 +59,6 @@
     'vregistry.py',
     
     'common/appobject.py',
-    'common/entity.py',
     'common/html4zope.py',
     'common/mail.py',
     'common/migration.py',
--- a/server/checkintegrity.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/server/checkintegrity.py	Tue Feb 17 23:00:28 2009 +0100
@@ -84,7 +84,7 @@
           ', '.join(sorted(str(e) for e in etypes))
     pb = ProgressBar(len(etypes) + 1)
     # first monkey patch Entity.check to disable validation
-    from cubicweb.common.entity import Entity
+    from cubicweb.entity import Entity
     _check = Entity.check
     Entity.check = lambda self, creation=False: True
     # clear fti table first
--- a/server/hooksmanager.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/server/hooksmanager.py	Tue Feb 17 23:00:28 2009 +0100
@@ -180,13 +180,13 @@
 #         self.register_hook(tidy_html_fields('before_add_entity'), 'before_add_entity', '')
 #         self.register_hook(tidy_html_fields('before_update_entity'), 'before_update_entity', '')
             
-from cubicweb.vregistry import autoselectors
 from cubicweb.selectors import yes
 from cubicweb.common.appobject import AppObject
 from cubicweb.common.registerers import yes_registerer
 
-class autoid(autoselectors):
+class autoid(type):
     """metaclass to create an unique 'id' attribute on the class using it"""
+    # XXX is this metaclass really necessary ?
     def __new__(mcs, name, bases, classdict):
         cls = super(autoid, mcs).__new__(mcs, name, bases, classdict)
         cls.id = str(id(cls))
--- a/vregistry.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/vregistry.py	Tue Feb 17 23:00:28 2009 +0100
@@ -29,6 +29,7 @@
 from os import listdir, stat
 from os.path import dirname, join, realpath, split, isdir
 from logging import getLogger
+import types
 
 from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
 from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
@@ -90,35 +91,6 @@
     raise NotImplementedError(cls)
 
 
-class autoselectors(type):
-    """implements __selectors__ / __select__ compatibility layer so that:
-
-    __select__ = chainall(classmethod(A, B, C))
-
-    can be replaced by something like:
-    
-    __selectors__ = (A, B, C)
-    """
-    def __new__(mcs, name, bases, classdict):
-        if '__select__' in classdict and '__selectors__' in classdict:
-            raise TypeError("__select__ and __selectors__ "
-                            "can't be used together")
-        if '__select__' not in classdict and '__selectors__' in classdict:
-            selectors = classdict['__selectors__']
-            if not isinstance(selectors, (tuple, list)):
-                selectors = (selectors,)
-            if len(selectors) > 1:
-                classdict['__select__'] = classmethod(chainall(*selectors))
-            else:
-                classdict['__select__'] = classmethod(selectors[0])
-        return super(autoselectors, mcs).__new__(mcs, name, bases, classdict)
-
-    def __setattr__(self, attr, value):
-        if attr == '__selectors__':
-            self.__select__ = classmethod(chainall(*value))
-        super(autoselectors, self).__setattr__(attr, value)
-            
-
 class VObject(object):
     """visual object, use to be handled somehow by the visual components
     registry.
@@ -142,7 +114,6 @@
     Moreover, the `__abstract__` attribute may be set to True to indicate
     that a vobject is abstract and should not be registered
     """
-    __metaclass__ = autoselectors
     # necessary attributes to interact with the registry
     id = None
     __registry__ = None
@@ -157,6 +128,7 @@
         may be the right hook to create an instance for example). By
         default the vobject is returned without any transformation.
         """
+        cls.__select__ = cls.build___select__()
         return cls
 
     @classmethod
@@ -175,6 +147,23 @@
         """returns a unique identifier for the vobject"""
         return '%s.%s' % (cls.__module__, cls.__name__)
 
+    @classmethod
+    def build___select__(cls):
+        classdict = cls.__dict__
+        if '__select__' in classdict and '__selectors__' in classdict:
+            raise TypeError("__select__ and __selectors__ can't be used together")
+        if '__selectors__' in classdict:
+            # case where __selectors__ is defined locally (but __select__
+            # is in a parent class)
+            selectors = classdict['__selectors__']
+            if len(selectors) == 1:
+                # micro optimization: don't bother with AndSelector if there's
+                # only one selector
+                return _instantiate_selector(selectors[0])
+            return AndSelector(_instantiate_selector(selector)
+                               for selector in selectors)
+        return cls.__select__
+
 
 class VRegistry(object):
     """class responsible to register, propose and select the various
@@ -578,7 +567,6 @@
 set_log_methods(registerer, getLogger('cubicweb.registration'))
 
 
-
 # selector base classes and operations ########################################
 
 class Selector(object):
@@ -589,6 +577,11 @@
     selector logic itself should be implemented in the __call__ method
     """
 
+    @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
@@ -662,6 +655,17 @@
     return type(selector_func.__name__, (Selector,),
                 {'__call__': lambda self, *args: selector_func(*args)})
 
+def _instantiate_selector(selector):
+    """ensures `selector` is a `Selector` instance
+    
+    NOTE: This should only be used locally in build___select__()
+    """
+    if isinstance(selector, types.FunctionType):
+        return objectify_selector(selector)()
+    if issubclass(selector, Selector):
+        return selector()
+    return selector
+
 
 class AndSelector(MultiSelector):
     """and-chained selectors (formerly known as chainall)"""
--- a/web/views/actions.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/web/views/actions.py	Tue Feb 17 23:00:28 2009 +0100
@@ -135,6 +135,7 @@
 
     @classmethod
     def registered(cls, vreg):
+        super(ManagePermissionsAction, cls).registered(vreg)
         if 'require_permission' in vreg.schema:
             cls.__select__ |= relation_possible('require_permission', 'subject', 'EPermission',
                                                 action='add')
--- a/web/views/ibreadcrumbs.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/web/views/ibreadcrumbs.py	Tue Feb 17 23:00:28 2009 +0100
@@ -8,12 +8,12 @@
 
 from logilab.mtconverter import html_escape
 
+# don't use AnyEntity since this may cause bug with isinstance() due to reloading
+from cubicweb.entity import Entity
 from cubicweb.interfaces import IBreadCrumbs
 from cubicweb.selectors import match_context_prop, one_line_rset, implements
 from cubicweb.common.view import EntityView
 from cubicweb.common.uilib import cut
-# don't use AnyEntity since this may cause bug with isinstance() due to reloading
-from cubicweb.common.entity import Entity
 from cubicweb.web.component import EntityVComponent
 
 _ = unicode
--- a/web/views/urlrewrite.py	Tue Feb 17 22:59:14 2009 +0100
+++ b/web/views/urlrewrite.py	Tue Feb 17 23:00:28 2009 +0100
@@ -6,8 +6,6 @@
 """
 import re
 
-from cubicweb.vregistry import autoselectors
-
 from cubicweb.common.registerers import accepts_registerer
 from cubicweb.common.appobject import AppObject
 
@@ -16,7 +14,7 @@
     """this is just a convenient shortcout to add the $ sign"""
     return re.compile(pattern+'$', flags)
 
-class metarewriter(autoselectors):
+class metarewriter(type):
     """auto-extend rules dictionnary"""
     def __new__(mcs, name, bases, classdict):
         # collect baseclass' rules