# HG changeset patch
# User Nicolas Chauvat <nicolas.chauvat@logilab.fr>
# Date 1334665700 -7200
# Tue Apr 17 14:28:20 2012 +0200
# Node ID cc988839a8e5a01639146bf30d71569020b3095f
# Parent 910d5bc0b342db48d8a420871dbcaaca320cf196
[registry] make pylint happy! (closes #92191)
# User Nicolas Chauvat <nicolas.chauvat@logilab.fr>
# Date 1334665700 -7200
# Tue Apr 17 14:28:20 2012 +0200
# Node ID cc988839a8e5a01639146bf30d71569020b3095f
# Parent 910d5bc0b342db48d8a420871dbcaaca320cf196
[registry] make pylint happy! (closes #92191)
@@ -77,14 +77,13 @@
1 2 import sys 3 import types 4 import weakref 5 from os import listdir, stat 6 -from os.path import dirname, join, realpath, isdir, exists 7 +from os.path import join, isdir, exists 8 from logging import getLogger 9 10 -from logilab.common.decorators import classproperty 11 from logilab.common.logging_ext import set_log_methods 12 13 14 class RegistryException(Exception): 15 """Base class for registry exception."""
@@ -149,10 +148,11 @@
16 def classid(cls): 17 """returns a unique identifier for an object class""" 18 return '%s.%s' % (cls.__module__, cls.__name__) 19 20 def class_registries(cls, registryname): 21 + """return a tuple of registry names (see __registries__)""" 22 if registryname: 23 return (registryname,) 24 return cls.__registries__ 25 26
@@ -201,10 +201,12 @@
27 return super(Registry, self).__getitem__(name) 28 except KeyError: 29 raise ObjectNotFound(name), None, sys.exc_info()[-1] 30 31 def initialization_completed(self): 32 + """call method __registered__() on registered objects when the callback 33 + is defined""" 34 for objects in self.itervalues(): 35 for objectcls in objects: 36 registered = getattr(objectcls, '__registered__', None) 37 if registered: 38 registered(self)
@@ -224,10 +226,11 @@
39 assert not obj in objects, \ 40 'object %s is already registered' % obj 41 objects.append(obj) 42 43 def register_and_replace(self, obj, replaced): 44 + """remove <replaced> and register <obj>""" 45 # XXXFIXME this is a duplication of unregister() 46 # remove register_and_replace in favor of unregister + register 47 # or simplify by calling unregister then register here 48 if not isinstance(replaced, basestring): 49 replaced = classid(replaced)
@@ -237,15 +240,16 @@
50 for index, registered in enumerate(registered_objs): 51 if classid(registered) == replaced: 52 del registered_objs[index] 53 break 54 else: 55 - self.warning('trying to replace an unregistered view %s by %s', 56 + self.warning('trying to replace %s that is not registered with %s', 57 replaced, obj) 58 self.register(obj) 59 60 def unregister(self, obj): 61 + """remove object <obj> from this registry""" 62 clsid = classid(obj) 63 oid = obj.__regid__ 64 for registered in self.get(oid, ()): 65 # use classid() to compare classes because vreg will probably 66 # have its own version of the class, loaded through execfile
@@ -317,16 +321,16 @@
67 return None if not object apply (don't raise `NoSelectableObject` since 68 it's costly when searching objects using `possible_objects` 69 (e.g. searching for hooks). 70 """ 71 score, winners = 0, None 72 - for object in objects: 73 - objectscore = object.__select__(object, *args, **kwargs) 74 + for obj in objects: 75 + objectscore = obj.__select__(obj, *args, **kwargs) 76 if objectscore > score: 77 - score, winners = objectscore, [object] 78 + score, winners = objectscore, [obj] 79 elif objectscore > 0 and objectscore == score: 80 - winners.append(object) 81 + winners.append(obj) 82 if winners is None: 83 return None 84 if len(winners) > 1: 85 # log in production environement / test, error while debugging 86 msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)'
@@ -337,11 +341,11 @@
87 # return the result of calling the object 88 return winners[0](*args, **kwargs) 89 90 # these are overridden by set_log_methods below 91 # only defining here to prevent pylint from complaining 92 - info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None 93 + info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None 94 95 96 class RegistryStore(dict): 97 """This class is responsible for loading implementations and storing them 98 in their registry which are created on the fly as needed.
@@ -463,10 +467,11 @@
99 def __init__(self, debugmode=False): 100 super(RegistryStore, self).__init__() 101 self.debugmode = debugmode 102 103 def reset(self): 104 + """clear all registries managed by this store""" 105 # don't use self.clear, we want to keep existing subdictionaries 106 for subdict in self.itervalues(): 107 subdict.clear() 108 self._lastmodifs = {} 109
@@ -483,10 +488,12 @@
110 111 # default class, when no specific class set 112 REGISTRY_FACTORY = {None: Registry} 113 114 def registry_class(self, regid): 115 + """return existing registry named regid or use factory to create one and 116 + return it""" 117 try: 118 return self.REGISTRY_FACTORY[regid] 119 except KeyError: 120 return self.REGISTRY_FACTORY[None] 121
@@ -560,28 +567,34 @@
122 self[registryname].register_and_replace(obj, replaced) 123 124 # initialization methods ################################################### 125 126 def init_registration(self, path, extrapath=None): 127 + """reset registry and walk down path to return list of (path, name) 128 + file modules to be loaded""" 129 + # XXX make this private by renaming it to _init_registration ? 130 self.reset() 131 # compute list of all modules that have to be loaded 132 self._toloadmods, filemods = _toload_info(path, extrapath) 133 # XXX is _loadedmods still necessary ? It seems like it's useful 134 # to avoid loading same module twice, especially with the 135 # _load_ancestors_then_object logic but this needs to be checked 136 self._loadedmods = {} 137 return filemods 138 139 def register_objects(self, path, extrapath=None): 140 + """register all objects found walking down <path>""" 141 # load views from each directory in the instance's path 142 + # XXX inline init_registration ? 143 filemods = self.init_registration(path, extrapath) 144 for filepath, modname in filemods: 145 self.load_file(filepath, modname) 146 self.initialization_completed() 147 148 def initialization_completed(self): 149 - for regname, reg in self.iteritems(): 150 + """call initialization_completed() on all known registries""" 151 + for reg in self.itervalues(): 152 reg.initialization_completed() 153 154 def _mdate(self, filepath): 155 try: 156 return stat(filepath)[-2]
@@ -632,10 +645,12 @@
157 # load the module 158 module = load_module_from_name(modname) 159 self.load_module(module) 160 161 def load_module(self, module): 162 + """load objects from a module using registration_callback() when it exists 163 + """ 164 self.info('loading %s from %s', module.__name__, module.__file__) 165 if hasattr(module, 'registration_callback'): 166 module.registration_callback(self) 167 else: 168 for objname, obj in vars(module).items():
@@ -686,11 +701,11 @@
169 self.exception('object %s registration failed: %s', 170 objectcls, ex) 171 172 # these are overridden by set_log_methods below 173 # only defining here to prevent pylint from complaining 174 - info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None 175 + info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None 176 177 178 # init logging 179 set_log_methods(RegistryStore, getLogger('registry.store')) 180 set_log_methods(Registry, getLogger('registry'))
@@ -715,11 +730,11 @@
181 return ret 182 traced.__name__ = selector.__name__ 183 traced.__doc__ = selector.__doc__ 184 return traced 185 186 -class traced_selection(object): 187 +class traced_selection(object): # pylint: disable=C0103 188 """ 189 Typical usage is : 190 191 .. sourcecode:: python 192
@@ -940,11 +955,11 @@
193 194 def __str__(self): 195 return 'NOT(%s)' % self.selector 196 197 198 -class yes(Predicate): 199 +class yes(Predicate): # pylint: disable=C0103 200 """Return the score given as parameter, with a default score of 0.5 so any 201 other selector take precedence. 202 203 Usually used for objects which can be selected whatever the context, or 204 also sometimes to add arbitrary points to a score.