# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1234908028 -3600 # Node ID 39a2a66731715e6118cf98d0f217d21ff62a8c7e # Parent b21ee900c732a62e098f6af7fc91491db4651102# Parent 5adb6d8e5fa7698925adb44276a479234b700542 merge diff -r b21ee900c732 -r 39a2a6673171 appobject.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 diff -r b21ee900c732 -r 39a2a6673171 entities/__init__.py --- 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 diff -r b21ee900c732 -r 39a2a6673171 entities/lib.py --- 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): diff -r b21ee900c732 -r 39a2a6673171 entity.py --- 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 """ diff -r b21ee900c732 -r 39a2a6673171 goa/db.py --- 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 diff -r b21ee900c732 -r 39a2a6673171 goa/goactl.py --- 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', diff -r b21ee900c732 -r 39a2a6673171 server/checkintegrity.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 diff -r b21ee900c732 -r 39a2a6673171 server/hooksmanager.py --- 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)) diff -r b21ee900c732 -r 39a2a6673171 vregistry.py --- 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)""" diff -r b21ee900c732 -r 39a2a6673171 web/views/actions.py --- 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') diff -r b21ee900c732 -r 39a2a6673171 web/views/ibreadcrumbs.py --- 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 diff -r b21ee900c732 -r 39a2a6673171 web/views/urlrewrite.py --- 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