Mercurial > piecrust2
diff piecrust/configuration.py @ 440:32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
* Make use of `collections.abc.Mapping` to better identify things that are
supposed to look like dictionaries.
* Instead of handling "overlay" of data in a dict tree in each different data
object, make all objects `Mapping`s and handle merging at a higher level
with the new `MergedMapping` object.
* Since this new object is read-only, remove the need for deep-copying of
app and page configurations.
* Split data classes into separate modules.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 28 Jun 2015 08:22:39 -0700 |
parents | bdeeee777f85 |
children | 1359b2b0cc73 |
line wrap: on
line diff
--- a/piecrust/configuration.py Sat Jun 27 22:28:32 2015 -0700 +++ b/piecrust/configuration.py Sun Jun 28 08:22:39 2015 -0700 @@ -1,7 +1,6 @@ import re -import copy import logging -import collections +import collections.abc import yaml from yaml.constructor import ConstructorError @@ -15,51 +14,28 @@ pass -class Configuration(object): +class Configuration(collections.abc.MutableMapping): def __init__(self, values=None, validate=True): if values is not None: - self.setAll(values, validate) + self.setAll(values, validate=validate) else: self._values = None - def __contains__(self, key): - return self.has(key) - def __getitem__(self, key): - value = self.get(key) - if value is None: - raise KeyError() - return value + self._ensureLoaded() + bits = key.split('/') + cur = self._values + for b in bits: + try: + cur = cur[b] + except KeyError: + raise KeyError("No such item: %s" % key) + return cur def __setitem__(self, key, value): - return self.set(key, value) - - def setAll(self, values, validate=True): - if validate: - self._validateAll(values) - self._values = values - - def getDeepcopy(self, validate_types=False): - if validate_types: - self.validateTypes() - return copy.deepcopy(self.get()) - - def get(self, key_path=None, default_value=None): self._ensureLoaded() - if key_path is None: - return self._values - bits = key_path.split('/') - cur = self._values - for b in bits: - cur = cur.get(b) - if cur is None: - return default_value - return cur - - def set(self, key_path, value): - self._ensureLoaded() - value = self._validateValue(key_path, value) - bits = key_path.split('/') + value = self._validateValue(key, value) + bits = key.split('/') bitslen = len(bits) cur = self._values for i, b in enumerate(bits): @@ -70,15 +46,31 @@ cur[b] = {} cur = cur[b] - def has(self, key_path): + def __delitem__(self, key): + raise NotImplementedError() + + def __iter__(self): + self._ensureLoaded() + return iter(self._values) + + def __len__(self): self._ensureLoaded() - bits = key_path.split('/') - cur = self._values - for b in bits: - cur = cur.get(b) - if cur is None: - return False - return True + return len(self._values) + + def has(self, key): + return key in self + + def set(self, key, value): + self[key] = value + + def setAll(self, values, validate=False): + if validate: + self._validateAll(values) + self._values = values + + def getAll(self): + self._ensureLoaded() + return self._values def merge(self, other): self._ensureLoaded()