/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/registry.py

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2008 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""Classes to provide name-to-object registry-like support."""
18
18
 
 
19
from .pyutils import get_named_object
 
20
 
19
21
 
20
22
class _ObjectGetter(object):
21
23
    """Maintain a reference to an object, and return the object on request.
32
34
    def __init__(self, obj):
33
35
        self._obj = obj
34
36
 
 
37
    def get_module(self):
 
38
        """Get the module the object was loaded from."""
 
39
        return self._obj.__module__
 
40
 
35
41
    def get_obj(self):
36
42
        """Get the object that was saved at creation time"""
37
43
        return self._obj
51
57
        self._imported = False
52
58
        super(_LazyObjectGetter, self).__init__(None)
53
59
 
 
60
    def get_module(self):
 
61
        """Get the module the referenced object will be loaded from.
 
62
        """
 
63
        return self._module_name
 
64
 
54
65
    def get_obj(self):
55
66
        """Get the referenced object.
56
67
 
58
69
        return the imported object.
59
70
        """
60
71
        if not self._imported:
61
 
            self._do_import()
 
72
            self._obj = get_named_object(self._module_name, self._member_name)
 
73
            self._imported = True
62
74
        return super(_LazyObjectGetter, self).get_obj()
63
75
 
64
 
    def _do_import(self):
65
 
        if self._member_name:
66
 
            segments = self._member_name.split('.')
67
 
            names = segments[0:1]
68
 
        else:
69
 
            names = [self._member_name]
70
 
        obj = __import__(self._module_name, globals(), locals(), names)
71
 
        if self._member_name:
72
 
            for segment in segments:
73
 
                obj = getattr(obj, segment)
74
 
        self._obj = obj
75
 
        self._imported = True
76
 
 
77
76
    def __repr__(self):
78
 
        return "<%s.%s object at %x, module=%r attribute=%r>" % (
 
77
        return "<%s.%s object at %x, module=%r attribute=%r imported=%r>" % (
79
78
            self.__class__.__module__, self.__class__.__name__, id(self),
80
 
            self._module_name, self._member_name)
 
79
            self._module_name, self._member_name, self._imported)
81
80
 
82
81
 
83
82
class Registry(object):
101
100
        self._default_key = None
102
101
        # Map from key => (is_lazy, info)
103
102
        self._dict = {}
 
103
        self._aliases = {}
104
104
        self._help_dict = {}
105
105
        self._info_dict = {}
106
106
 
 
107
    def aliases(self):
 
108
        """Return a set of the format names which are aliases."""
 
109
        return dict(self._aliases.items())
 
110
 
 
111
    def alias_map(self):
 
112
        ret = {}
 
113
        for alias, target in self._aliases.items():
 
114
            ret.setdefault(target, []).append(alias)
 
115
        return ret
 
116
 
107
117
    def register(self, key, obj, help=None, info=None,
108
118
                 override_existing=False):
109
119
        """Register a new object to a name.
132
142
                      override_existing=False):
133
143
        """Register a new object to be loaded on request.
134
144
 
 
145
        :param key: This is the key to use to request the object later.
135
146
        :param module_name: The python path to the module. Such as 'os.path'.
136
147
        :param member_name: The member of the module to return.  If empty or
137
148
                None, get() will return the module itself.
138
149
        :param help: Help text for this entry. This may be a string or
139
150
                a callable.
140
 
        :param info: More information for this entry. Registry
 
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).
141
154
        :param override_existing: If True, replace the existing object
142
155
                with the new one. If False, if there is already something
143
156
                registered with the same key, raise a KeyError
148
161
        self._dict[key] = _LazyObjectGetter(module_name, member_name)
149
162
        self._add_help_and_info(key, help=help, info=info)
150
163
 
 
164
    def register_alias(self, key, target, info=None):
 
165
        """Register an alias.
 
166
 
 
167
        :param key: Alias name
 
168
        :param target: Target key name
 
169
        """
 
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
 
174
        if info is None:
 
175
            info = self._info_dict[target]
 
176
        self._add_help_and_info(key, help=self._help_dict[target], info=info)
 
177
 
151
178
    def _add_help_and_info(self, key, help=None, info=None):
152
179
        """Add the help and information about this key"""
153
180
        self._help_dict[key] = help
172
199
        """
173
200
        return self._dict[self._get_key_or_default(key)].get_obj()
174
201
 
 
202
    def _get_module(self, key):
 
203
        """Return the module the object will be or was loaded from.
 
204
 
 
205
        :param key: The key to obtain the module for.
 
206
        :return: The name of the module
 
207
        """
 
208
        return self._dict[key].get_module()
 
209
 
175
210
    def get_prefix(self, fullname):
176
211
        """Return an object whose key is a prefix of the supplied value.
177
212
 
215
250
 
216
251
    def keys(self):
217
252
        """Get a list of registered entries"""
218
 
        return sorted(self._dict.keys())
 
253
        return sorted(self._dict)
219
254
 
220
255
    def iteritems(self):
221
 
        for key, getter in self._dict.iteritems():
222
 
            yield key, getter.get_obj()
 
256
        for key in self._dict:
 
257
            yield key, self._dict[key].get_obj()
223
258
 
224
259
    def items(self):
225
260
        # We should not use the iteritems() implementation below (see bug
226
261
        # #430510)
227
 
        return sorted([(key, getter.get_obj())
228
 
                       for key, getter in self._dict.items()])
 
262
        return [(key, self._dict[key].get_obj()) for key in self.keys()]
229
263
 
230
264
    def _set_default_key(self, key):
231
 
        if not self._dict.has_key(key):
 
265
        if key not in self._dict:
232
266
            raise KeyError('No object registered under key %s.' % key)
233
267
        else:
234
268
            self._default_key = key
237
271
        return self._default_key
238
272
 
239
273
    default_key = property(_get_default_key, _set_default_key,
240
 
                            doc="Current value of the default key."
241
 
                                " Can be set to any existing key.")
 
274
                           doc="Current value of the default key."
 
275
                           " Can be set to any existing key.")
242
276
 
243
277
 
244
278
class FormatRegistry(Registry):
248
282
        Registry.__init__(self)
249
283
        self._other_registry = other_registry
250
284
 
 
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)
 
292
 
251
293
    def register_lazy(self, key, module_name, member_name,
252
294
                      help=None, info=None,
253
295
                      override_existing=False):
254
296
        # Overridden to allow capturing registrations to two seperate
255
297
        # registries in a single call.
256
298
        Registry.register_lazy(self, key, module_name, member_name,
257
 
                help=help, info=info, override_existing=override_existing)
 
299
                               help=help, info=info, override_existing=override_existing)
258
300
        if self._other_registry is not None:
259
301
            self._other_registry.register_lazy(key, module_name, member_name,
260
 
                help=help, info=info, override_existing=override_existing)
 
302
                                               help=help, info=info, override_existing=override_existing)
 
303
 
 
304
    def remove(self, key):
 
305
        Registry.remove(self, key)
 
306
        if self._other_registry is not None:
 
307
            self._other_registry.remove(key)
261
308
 
262
309
    def get(self, format_string):
263
310
        r = Registry.get(self, format_string)
264
311
        if callable(r):
265
312
            r = r()
266
313
        return r
267
 
 
268