vregistry.py
changeset 5121 a63d7886fcf5
parent 5103 2b242604fc42
child 5143 43afbdd5c8b4
equal deleted inserted replaced
5082:d6fd82a5a4e8 5121:a63d7886fcf5
    80         cls.__regid__ = cls.id
    80         cls.__regid__ = cls.id
    81     if hasattr(cls, 'id') and not isinstance(cls.id, property):
    81     if hasattr(cls, 'id') and not isinstance(cls.id, property):
    82         return cls.id
    82         return cls.id
    83     return cls.__regid__
    83     return cls.__regid__
    84 
    84 
       
    85 def class_registries(cls, registryname):
       
    86     if registryname:
       
    87         return (registryname,)
       
    88     return cls.__registries__
       
    89 
    85 
    90 
    86 class Registry(dict):
    91 class Registry(dict):
    87 
    92 
    88     def __init__(self, config):
    93     def __init__(self, config):
    89         super(Registry, self).__init__()
    94         super(Registry, self).__init__()
   203         raise `NoSelectableObject` if not object apply
   208         raise `NoSelectableObject` if not object apply
   204         """
   209         """
   205         if len(args) > 1:
   210         if len(args) > 1:
   206             warn('[3.5] only the request param can not be named when calling select*',
   211             warn('[3.5] only the request param can not be named when calling select*',
   207                  DeprecationWarning, stacklevel=3)
   212                  DeprecationWarning, stacklevel=3)
   208         score, winners = 0, []
   213         score, winners = 0, None
   209         for appobject in appobjects:
   214         for appobject in appobjects:
   210             appobjectscore = appobject.__select__(appobject, *args, **kwargs)
   215             appobjectscore = appobject.__select__(appobject, *args, **kwargs)
   211             if appobjectscore > score:
   216             if appobjectscore > score:
   212                 score, winners = appobjectscore, [appobject]
   217                 score, winners = appobjectscore, [appobject]
   213             elif appobjectscore > 0 and appobjectscore == score:
   218             elif appobjectscore > 0 and appobjectscore == score:
   214                 winners.append(appobject)
   219                 winners.append(appobject)
   215         if not winners:
   220         if winners is None:
   216             raise NoSelectableObject('args: %s\nkwargs: %s %s'
   221             raise NoSelectableObject('args: %s\nkwargs: %s %s'
   217                                      % (args, kwargs.keys(),
   222                                      % (args, kwargs.keys(),
   218                                         [repr(v) for v in appobjects]))
   223                                         [repr(v) for v in appobjects]))
   219         if len(winners) > 1:
   224         if len(winners) > 1:
       
   225             # log in production environement, error while debugging
   220             if self.config.debugmode:
   226             if self.config.debugmode:
   221                 self.error('select ambiguity, args: %s\nkwargs: %s %s',
       
   222                            args, kwargs.keys(), [repr(v) for v in winners])
       
   223             else:
       
   224                 raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
   227                 raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
   225                                 % (args, kwargs.keys(),
   228                                 % (args, kwargs.keys(),
   226                                    [repr(v) for v in winners]))
   229                                    [repr(v) for v in winners]))
       
   230             self.error('select ambiguity, args: %s\nkwargs: %s %s',
       
   231                        args, kwargs.keys(), [repr(v) for v in winners])
   227         # return the result of calling the appobject
   232         # return the result of calling the appobject
   228         return winners[0](*args, **kwargs)
   233         return winners[0](*args, **kwargs)
   229 
   234 
   230     select_best = deprecated('[3.6] select_best is now private')(_select_best)
   235     select_best = deprecated('[3.6] select_best is now private')(_select_best)
   231 
   236 
   316         for obj in objects:
   321         for obj in objects:
   317             try:
   322             try:
   318                 if obj.__module__ != modname or obj in butclasses:
   323                 if obj.__module__ != modname or obj in butclasses:
   319                     continue
   324                     continue
   320                 oid = class_regid(obj)
   325                 oid = class_regid(obj)
   321                 registryname = obj.__registry__
       
   322             except AttributeError:
   326             except AttributeError:
   323                 continue
   327                 continue
   324             if oid and not '__abstract__' in obj.__dict__:
   328             if oid and not '__abstract__' in obj.__dict__:
   325                 self.register(obj, registryname)
   329                 self.register(obj, oid=oid)
   326 
   330 
   327     def register(self, obj, registryname=None, oid=None, clear=False):
   331     def register(self, obj, registryname=None, oid=None, clear=False):
   328         """base method to add an object in the registry"""
   332         """base method to add an object in the registry"""
   329         assert not '__abstract__' in obj.__dict__
   333         assert not '__abstract__' in obj.__dict__
   330         registryname = registryname or obj.__registry__
       
   331         registry = self.setdefault(registryname)
       
   332         registry.register(obj, oid=oid, clear=clear)
       
   333         try:
   334         try:
   334             vname = obj.__name__
   335             vname = obj.__name__
   335         except AttributeError:
   336         except AttributeError:
       
   337             # XXX may occurs?
   336             vname = obj.__class__.__name__
   338             vname = obj.__class__.__name__
   337         self.debug('registered appobject %s in registry %s with id %s',
   339         for registryname in class_registries(obj, registryname):
   338                    vname, registryname, oid or class_regid(obj))
   340             registry = self.setdefault(registryname)
       
   341             registry.register(obj, oid=oid, clear=clear)
       
   342             self.debug('registered appobject %s in registry %s with id %s',
       
   343                        vname, registryname, oid or class_regid(obj))
   339         self._loadedmods[obj.__module__][classid(obj)] = obj
   344         self._loadedmods[obj.__module__][classid(obj)] = obj
   340 
   345 
   341     def unregister(self, obj, registryname=None):
   346     def unregister(self, obj, registryname=None):
   342         self[registryname or obj.__registry__].unregister(obj)
   347         for registryname in class_registries(obj, registryname):
       
   348             self[registryname].unregister(obj)
   343 
   349 
   344     def register_and_replace(self, obj, replaced, registryname=None):
   350     def register_and_replace(self, obj, replaced, registryname=None):
   345         self[registryname or obj.__registry__].register_and_replace(obj, replaced)
   351         for registryname in class_registries(obj, registryname):
       
   352             self[registryname].register_and_replace(obj, replaced)
   346 
   353 
   347     # initialization methods ###################################################
   354     # initialization methods ###################################################
   348 
   355 
   349     def init_registration(self, path, extrapath=None):
   356     def init_registration(self, path, extrapath=None):
   350         # compute list of all modules that have to be loaded
   357         # compute list of all modules that have to be loaded
   449         self._loadedmods[modname][clsid] = appobjectcls
   456         self._loadedmods[modname][clsid] = appobjectcls
   450         for parent in appobjectcls.__bases__:
   457         for parent in appobjectcls.__bases__:
   451             self._load_ancestors_then_object(modname, parent)
   458             self._load_ancestors_then_object(modname, parent)
   452         if (appobjectcls.__dict__.get('__abstract__')
   459         if (appobjectcls.__dict__.get('__abstract__')
   453             or appobjectcls.__name__[0] == '_'
   460             or appobjectcls.__name__[0] == '_'
   454             or not appobjectcls.__registry__
   461             or not appobjectcls.__registries__
   455             or not class_regid(appobjectcls)):
   462             or not class_regid(appobjectcls)):
   456             return
   463             return
   457         try:
   464         try:
   458             self.register(appobjectcls)
   465             self.register(appobjectcls)
   459         except Exception, ex:
   466         except Exception, ex: