| 202 | |
| 203 | |
| 204 | class PendingConfiguration(UserDict, AttributeDictMixin): |
| 205 | # `app.conf` will be of this type before being explicitly configured, |
| 206 | # meaning the app can keep any configuration set directly |
| 207 | # on `app.conf` before the `app.config_from_object` call. |
| 208 | # |
| 209 | # accessing any key will finalize the configuration, |
| 210 | # replacing `app.conf` with a concrete settings object. |
| 211 | |
| 212 | callback = None |
| 213 | _data = None |
| 214 | |
| 215 | def __init__(self, conf, callback): |
| 216 | object.__setattr__(self, '_data', conf) |
| 217 | object.__setattr__(self, 'callback', callback) |
| 218 | |
| 219 | def __setitem__(self, key, value): |
| 220 | self._data[key] = value |
| 221 | |
| 222 | def clear(self): |
| 223 | self._data.clear() |
| 224 | |
| 225 | def update(self, *args, **kwargs): |
| 226 | self._data.update(*args, **kwargs) |
| 227 | |
| 228 | def setdefault(self, *args, **kwargs): |
| 229 | return self._data.setdefault(*args, **kwargs) |
| 230 | |
| 231 | def __contains__(self, key): |
| 232 | # XXX will not show finalized configuration |
| 233 | # setdefault will cause `key in d` to happen, |
| 234 | # so for setdefault to be lazy, so does contains. |
| 235 | return key in self._data |
| 236 | |
| 237 | def __len__(self): |
| 238 | return len(self.data) |
| 239 | |
| 240 | def __repr__(self): |
| 241 | return repr(self.data) |
| 242 | |
| 243 | @cached_property |
| 244 | def data(self): |
| 245 | return self.callback() |
| 246 | |
| 247 | |
| 248 | class Celery: |