406 if objname.startswith('_'): |
406 if objname.startswith('_'): |
407 continue |
407 continue |
408 self._load_ancestors_then_object(module.__name__, obj) |
408 self._load_ancestors_then_object(module.__name__, obj) |
409 self.debug('loaded %s', module) |
409 self.debug('loaded %s', module) |
410 |
410 |
411 def _load_ancestors_then_object(self, modname, obj): |
411 def _load_ancestors_then_object(self, modname, appobjectcls): |
|
412 """handle automatic appobject class registration: |
|
413 |
|
414 - first ensure parent classes are already registered |
|
415 |
|
416 - class with __abstract__ == True in their local dictionnary or |
|
417 with a name starting starting by an underscore are not registered |
|
418 |
|
419 - appobject class needs to have __registry__ and __regid__ attributes |
|
420 set to a non empty string to be registered. |
|
421 """ |
412 # imported classes |
422 # imported classes |
413 objmodname = getattr(obj, '__module__', None) |
423 objmodname = getattr(appobjectcls, '__module__', None) |
414 if objmodname != modname: |
424 if objmodname != modname: |
415 if objmodname in self._toloadmods: |
425 if objmodname in self._toloadmods: |
416 self.load_file(self._toloadmods[objmodname], objmodname) |
426 self.load_file(self._toloadmods[objmodname], objmodname) |
417 return |
427 return |
418 # skip non registerable object |
428 # skip non registerable object |
419 try: |
429 try: |
420 if not issubclass(obj, AppObject): |
430 if not issubclass(appobjectcls, AppObject): |
421 return |
431 return |
422 except TypeError: |
432 except TypeError: |
423 return |
433 return |
424 clsid = classid(obj) |
434 clsid = classid(appobjectcls) |
425 if clsid in self._loadedmods[modname]: |
435 if clsid in self._loadedmods[modname]: |
426 return |
436 return |
427 self._loadedmods[modname][clsid] = obj |
437 self._loadedmods[modname][clsid] = appobjectcls |
428 for parent in obj.__bases__: |
438 for parent in appobjectcls.__bases__: |
429 self._load_ancestors_then_object(modname, parent) |
439 self._load_ancestors_then_object(modname, parent) |
430 self.load_object(obj) |
440 if (appobjectcls.__dict__.get('__abstract__') |
431 |
441 or appobjectcls.__name__[0] == '_' |
432 def load_object(self, obj): |
442 or not appobjectcls.__registry__ |
433 try: |
443 or not class_regid(appobjectcls)): |
434 self.register_appobject_class(obj) |
444 return |
|
445 try: |
|
446 self.register(appobjectcls) |
435 except Exception, ex: |
447 except Exception, ex: |
436 if self.config.mode in ('test', 'dev'): |
448 if self.config.mode in ('test', 'dev'): |
437 raise |
449 raise |
438 self.exception('appobject %s registration failed: %s', obj, ex) |
450 self.exception('appobject %s registration failed: %s', |
439 |
451 appobjectcls, ex) |
440 # old automatic registration XXX deprecated ############################### |
452 |
441 |
|
442 def register_appobject_class(self, cls): |
|
443 """handle appobject class registration |
|
444 |
|
445 appobject class with __abstract__ == True in their local dictionnary or |
|
446 with a name starting starting by an underscore are not registered. |
|
447 Also a appobject class needs to have __registry__ and id attributes set |
|
448 to a non empty string to be registered. |
|
449 """ |
|
450 if (cls.__dict__.get('__abstract__') or cls.__name__[0] == '_' |
|
451 or not cls.__registry__ or not class_regid(cls)): |
|
452 return |
|
453 regname = cls.__registry__ |
|
454 if '%s.%s' % (regname, class_regid(cls)) in self.config['disable-appobjects']: |
|
455 return |
|
456 self.register(cls) |
|
457 |
453 |
458 # init logging |
454 # init logging |
459 set_log_methods(VRegistry, getLogger('cubicweb.vreg')) |
455 set_log_methods(VRegistry, getLogger('cubicweb.vreg')) |
460 set_log_methods(Registry, getLogger('cubicweb.registry')) |
456 set_log_methods(Registry, getLogger('cubicweb.registry')) |
461 |
457 |