diff options
| author | Raphael Collet <rco@odoo.com> | 2018-01-18 12:15:15 +0100 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2018-01-23 16:41:45 +0100 |
| commit | f1d60d2e528284c4d4401d40e362f1b45ac32211 (patch) | |
| tree | 572031ea4a6997928ada1f5a519fae590798e405 /odoo/tools/misc.py | |
| parent | 74801feb0cfd26d09e767878c18dfffaa220ab51 (diff) | |
[IMP] api: make the implementation of field protection more robust
Diffstat (limited to 'odoo/tools/misc.py')
| -rw-r--r-- | odoo/tools/misc.py | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py index ac3a56b3825..a9b66117f03 100644 --- a/odoo/tools/misc.py +++ b/odoo/tools/misc.py @@ -25,8 +25,7 @@ import types import unicodedata import werkzeug.utils import zipfile - -from collections import defaultdict, Iterable, Mapping, MutableSet, OrderedDict +from collections import defaultdict, Iterable, Mapping, MutableMapping, MutableSet, OrderedDict from itertools import islice, groupby, repeat from lxml import etree @@ -998,6 +997,49 @@ class Collector(Mapping): def __len__(self): return len(self._map) + +@pycompat.implements_to_string +class StackMap(MutableMapping): + """ A stack of mappings behaving as a single mapping, and used to implement + nested scopes. The lookups search the stack from top to bottom, and + returns the first value found. Mutable operations modify the topmost + mapping only. + """ + __slots__ = ['_maps'] + + def __init__(self, m=None): + self._maps = [] if m is None else [m] + + def __getitem__(self, key): + for mapping in reversed(self._maps): + try: + return mapping[key] + except KeyError: + pass + raise KeyError(key) + + def __setitem__(self, key, val): + self._maps[-1][key] = val + + def __delitem__(self, key): + del self._maps[-1][key] + + def __iter__(self): + return iter({key for mapping in self._maps for key in mapping}) + + def __len__(self): + return sum(1 for key in self) + + def __str__(self): + return u"<StackMap %s>" % self._maps + + def pushmap(self, m=None): + self._maps.append({} if m is None else m) + + def popmap(self): + return self._maps.pop() + + class OrderedSet(MutableSet): """ A set collection that remembers the elements first insertion order. """ __slots__ = ['_map'] |
