~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/registry.py

  • Committer: John Arbash Meinel
  • Date: 2006-09-09 16:52:26 UTC
  • mto: This revision was merged to the branch mainline in revision 2074.
  • Revision ID: john@arbash-meinel.com-20060909165226-205b4911cc273230
Make a Registry look more like a dict, and allow anyone to register stuff lazily.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
        """
29
29
        self._first_is_default = first_is_default
30
30
        self._default_key = None
 
31
        # Map from key => (is_lazy, info)
31
32
        self._dict = {}
32
33
 
33
34
    def register(self, key, object):
38
39
        """
39
40
        if self._first_is_default and not self._dict:
40
41
            self._default_key = key
41
 
        self._dict[key] = object
 
42
        self._dict[key] = (False, object)
 
43
 
 
44
    __setitem__ = register
 
45
 
 
46
    def register_lazy(self, key, module_name, member_name):
 
47
        """Register a new object to be loaded on request.
 
48
 
 
49
        :param module_name: The python path to the module. Such as 'os.path'.
 
50
        :param member_name: The member of the module to return, if empty or 
 
51
                None get() will return the module itself.
 
52
        """
 
53
        if self._first_is_default and not self._dict:
 
54
            self._default_key = key
 
55
        self._dict[key] = (True, (module_name, member_name))
42
56
 
43
57
    def get(self, key=None):
44
58
        """Return the object register()'ed to the given key.
45
59
 
 
60
        May raise ImportError if the object was registered lazily and
 
61
        there are any problems, or AttributeError if the module does not 
 
62
        have the supplied member.
 
63
 
46
64
        :param key: The key to obtain the object for. If no object has been
47
65
            registered to that key, the object registered for self.default_key
48
66
            will be returned instead, if it exists. Otherwise KeyError will be
49
67
            raised.
50
68
        :return: The previously registered object.
51
69
        """
52
 
        try:
53
 
            return self._dict[key]
54
 
        except KeyError:
55
 
            if self.default_key is not None:
56
 
                return self._dict[self.default_key]
 
70
        if key is None:
 
71
            if self.default_key is None:
 
72
                raise KeyError('Key is None, and no default key is set')
57
73
            else:
58
 
                raise
 
74
                key = self.default_key
 
75
        return self._get_one(key)
 
76
 
 
77
    __getitem__ = get
 
78
 
 
79
    def _get_one(self, key):
 
80
        """Attempt to return a single entry.
 
81
 
 
82
        This will import the entry if it is lazy, and replace the registry
 
83
        with the imported object.
 
84
 
 
85
        This may raise KeyError if the given key doesn't exist, or ImportError
 
86
        or AttributeError.
 
87
        """
 
88
        is_lazy, info_or_object = self._dict[key]
 
89
        if not is_lazy:
 
90
            # We have a real object to return
 
91
            return info_or_object
 
92
 
 
93
        module_name, member_name = info_or_object
 
94
        obj = __import__(module_name, globals(), locals(), [member_name])
 
95
        if member_name:
 
96
            obj = getattr(obj, member_name)
 
97
        self._dict[key] = (False, obj)
 
98
        return obj
 
99
 
 
100
    def remove(self, key):
 
101
        """Remove a registered entry.
 
102
 
 
103
        This is mostly for the test suite, but it can be used by others
 
104
        """
 
105
        del self._dict[key]
 
106
 
 
107
    __delitem__ = remove
 
108
 
 
109
    def __contains__(self, key):
 
110
        return key in self._dict
 
111
 
 
112
    def __len__(self):
 
113
        return len(self._dict)
59
114
 
60
115
    def keys(self):
61
116
        """Get a list of registered entries"""
62
117
        return sorted(self._dict.keys())
63
118
 
 
119
    def iterkeys(self):
 
120
        return self._dict.iterkeys()
 
121
 
 
122
    def iteritems(self):
 
123
        for key in self._dict.iterkeys():
 
124
            yield key, self._get_one(key)
 
125
 
 
126
    def items(self):
 
127
        return list(self.iteritems())
 
128
 
 
129
    def itervalues(self):
 
130
        for key in self._dict.iterkeys():
 
131
            yield self._get_one(key)
 
132
 
 
133
    def values(self):
 
134
        return list(self.itervalues())
 
135
 
64
136
    def _set_default_key(self, key):
65
137
        if not self._dict.has_key(key):
66
138
            raise KeyError('No object registered under key %s.' % key)
70
142
    def _get_default_key(self):
71
143
        return self._default_key
72
144
 
73
 
    default_key = property(_get_default_key, _set_default_key)
74
 
    """Current value of the default key. Can be set to any existing key."""
75
 
 
76
 
 
77
 
class LazyImportRegistry(Registry):
78
 
    """A class to register modules/members to be loaded on request."""
79
 
 
80
 
    def register(self, key, module_name, member_name):
81
 
        """Register a new object to be loaded on request.
82
 
 
83
 
        :param module_name: The python path to the module. Such as 'os.path'.
84
 
        :param member_name: The member of the module to return, if empty or None
85
 
            get() will return the module itself.
86
 
        """
87
 
        Registry.register(self, key, (module_name, member_name))
88
 
 
89
 
    def get(self, key=None):
90
 
        """Load the module and return the object specified by the given key.
91
 
 
92
 
        May raise ImportError if there are any problems, or AttributeError if
93
 
        the module does not have the supplied member.
94
 
        """
95
 
        module_name, member_name = Registry.get(self, key)
96
 
        module = __import__(module_name, globals(), locals(), [member_name])
97
 
        if member_name:
98
 
            return getattr(module, member_name)
99
 
        return module
 
145
    default_key = property(_get_default_key, _set_default_key,
 
146
                            doc="Current value of the default key."
 
147
                                "Can be set to any existing key.")