# HG changeset patch # User Adrien Di Mascio # Date 1234907039 -3600 # Node ID ce49e3885453a452c36983b0b719396514c444c4 # Parent f758b86cf484d9c70133a9e25e3e3a18997c40bf remove autoselectors metaclass, __select__ is built during registration diff -r f758b86cf484 -r ce49e3885453 entity.py --- 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 """ diff -r f758b86cf484 -r ce49e3885453 server/hooksmanager.py --- 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)) diff -r f758b86cf484 -r ce49e3885453 vregistry.py --- 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)""" diff -r f758b86cf484 -r ce49e3885453 web/views/urlrewrite.py --- 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