--- a/entity.py Tue Feb 17 22:25:16 2009 +0100
+++ b/entity.py Tue Feb 17 22:43:59 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.common.appobject import AppRsetObject
@@ -167,7 +166,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/server/hooksmanager.py Tue Feb 17 22:25:16 2009 +0100
+++ b/server/hooksmanager.py Tue Feb 17 22:43:59 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:25:16 2009 +0100
+++ b/vregistry.py Tue Feb 17 22:43:59 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
@@ -665,6 +654,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/urlrewrite.py Tue Feb 17 22:25:16 2009 +0100
+++ b/web/views/urlrewrite.py Tue Feb 17 22:43:59 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