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: |