13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Classes to provide name-to-object registry-like support."""
19
from .pyutils import get_named_object
22
20
class _ObjectGetter(object):
23
21
"""Maintain a reference to an object, and return the object on request.
69
58
return the imported object.
71
60
if not self._imported:
72
self._obj = get_named_object(self._module_name, self._member_name)
74
62
return super(_LazyObjectGetter, self).get_obj()
77
return "<%s.%s object at %x, module=%r attribute=%r imported=%r>" % (
78
self.__class__.__module__, self.__class__.__name__, id(self),
79
self._module_name, self._member_name, self._imported)
65
obj = __import__(self._module_name, globals(), locals(),
68
obj = getattr(obj, self._member_name)
82
73
class Registry(object):
100
91
self._default_key = None
101
92
# Map from key => (is_lazy, info)
104
94
self._help_dict = {}
105
95
self._info_dict = {}
108
"""Return a set of the format names which are aliases."""
109
return dict(self._aliases.items())
113
for alias, target in self._aliases.items():
114
ret.setdefault(target, []).append(alias)
117
97
def register(self, key, obj, help=None, info=None,
118
98
override_existing=False):
119
99
"""Register a new object to a name.
122
102
:param obj: The object to register.
123
103
:param help: Help text for this entry. This may be a string or
124
104
a callable. If it is a callable, it should take two
125
parameters (registry, key): this registry and the key that
105
parameters (registry, key): this registry and the key that
126
106
the help was registered under.
127
107
:param info: More information for this entry. Registry.get_info()
128
108
can be used to get this information. Registry treats this as an
142
122
override_existing=False):
143
123
"""Register a new object to be loaded on request.
145
:param key: This is the key to use to request the object later.
146
125
:param module_name: The python path to the module. Such as 'os.path'.
147
:param member_name: The member of the module to return. If empty or
126
:param member_name: The member of the module to return. If empty or
148
127
None, get() will return the module itself.
149
128
:param help: Help text for this entry. This may be a string or
151
:param info: More information for this entry. Registry.get_info()
152
can be used to get this information. Registry treats this as an
153
opaque storage location (it is defined by the caller).
130
:param info: More information for this entry. Registry
154
131
:param override_existing: If True, replace the existing object
155
132
with the new one. If False, if there is already something
156
133
registered with the same key, raise a KeyError
161
138
self._dict[key] = _LazyObjectGetter(module_name, member_name)
162
139
self._add_help_and_info(key, help=help, info=info)
164
def register_alias(self, key, target, info=None):
165
"""Register an alias.
167
:param key: Alias name
168
:param target: Target key name
170
if key in self._dict and key not in self._aliases:
171
raise KeyError('Key %r already registered and not an alias' % key)
172
self._dict[key] = self._dict[target]
173
self._aliases[key] = target
175
info = self._info_dict[target]
176
self._add_help_and_info(key, help=self._help_dict[target], info=info)
178
141
def _add_help_and_info(self, key, help=None, info=None):
179
142
"""Add the help and information about this key"""
180
143
self._help_dict[key] = help
184
147
"""Return the object register()'ed to the given key.
186
149
May raise ImportError if the object was registered lazily and
187
there are any problems, or AttributeError if the module does not
150
there are any problems, or AttributeError if the module does not
188
151
have the supplied member.
190
153
:param key: The key to obtain the object for. If no object has been
200
163
return self._dict[self._get_key_or_default(key)].get_obj()
202
def _get_module(self, key):
203
"""Return the module the object will be or was loaded from.
205
:param key: The key to obtain the module for.
206
:return: The name of the module
208
return self._dict[key].get_module()
210
def get_prefix(self, fullname):
211
"""Return an object whose key is a prefix of the supplied value.
213
:fullname: The name to find a prefix for
214
:return: a tuple of (object, remainder), where the remainder is the
215
portion of the name that did not match the key.
217
for key in self.keys():
218
if fullname.startswith(key):
219
return self.get(key), fullname[len(key):]
221
165
def _get_key_or_default(self, key=None):
222
166
"""Return either 'key' or the default key if key is None"""
223
167
if key is not None:
252
196
"""Get a list of registered entries"""
253
return sorted(self._dict)
197
return sorted(self._dict.keys())
255
199
def iteritems(self):
256
for key in self._dict:
257
yield key, self._dict[key].get_obj()
260
# We should not use the iteritems() implementation below (see bug
262
return [(key, self._dict[key].get_obj()) for key in self.keys()]
200
for key, getter in self._dict.iteritems():
201
yield key, getter.get_obj()
264
203
def _set_default_key(self, key):
265
if key not in self._dict:
204
if not self._dict.has_key(key):
266
205
raise KeyError('No object registered under key %s.' % key)
268
207
self._default_key = key
271
210
return self._default_key
273
212
default_key = property(_get_default_key, _set_default_key,
274
doc="Current value of the default key."
275
" Can be set to any existing key.")
278
class FormatRegistry(Registry):
279
"""Registry specialised for handling formats."""
281
def __init__(self, other_registry=None):
282
Registry.__init__(self)
283
self._other_registry = other_registry
285
def register(self, key, obj, help=None, info=None,
286
override_existing=False):
287
Registry.register(self, key, obj, help=help, info=info,
288
override_existing=override_existing)
289
if self._other_registry is not None:
290
self._other_registry.register(key, obj, help=help,
291
info=info, override_existing=override_existing)
293
def register_lazy(self, key, module_name, member_name,
294
help=None, info=None,
295
override_existing=False):
296
# Overridden to allow capturing registrations to two seperate
297
# registries in a single call.
298
Registry.register_lazy(self, key, module_name, member_name,
299
help=help, info=info, override_existing=override_existing)
300
if self._other_registry is not None:
301
self._other_registry.register_lazy(key, module_name, member_name,
302
help=help, info=info, override_existing=override_existing)
304
def remove(self, key):
305
Registry.remove(self, key)
306
if self._other_registry is not None:
307
self._other_registry.remove(key)
309
def get(self, format_string):
310
r = Registry.get(self, format_string)
213
doc="Current value of the default key."
214
" Can be set to any existing key.")