diff --git a/odoo/models.py b/odoo/models.py index 1f78c213b75..0f63b683e03 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -139,7 +139,7 @@ def trigger_tree_merge(node1, node2): """ Merge two trigger trees. """ for key, val in node2.items(): if key is None: - node1.setdefault(None, set()) + node1.setdefault(None, OrderedSet()) node1[None].update(val) else: node1.setdefault(key, {}) @@ -3924,9 +3924,9 @@ Fields: quote = '"{}"'.format # insert rows - ids = [] # ids of created records - other_fields = set() # non-column fields - translated_fields = set() # translated fields + ids = [] # ids of created records + other_fields = OrderedSet() # non-column fields + translated_fields = OrderedSet() # translated fields for data in data_list: # determine column values diff --git a/odoo/modules/registry.py b/odoo/modules/registry.py index e794abfd053..e469661d95a 100644 --- a/odoo/modules/registry.py +++ b/odoo/modules/registry.py @@ -312,7 +312,7 @@ class Registry(Mapping): # dependencies of custom fields may not exist; ignore that case exceptions = (Exception,) if field.base_field.manual else () with ignore(*exceptions): - dependencies[field] = set(field.resolve_depends(self)) + dependencies[field] = OrderedSet(field.resolve_depends(self)) # determine transitive dependencies def transitive_dependencies(field, seen=[]): @@ -339,7 +339,7 @@ class Registry(Mapping): tree = triggers for label in reversed(path): tree = tree.setdefault(label, {}) - tree.setdefault(None, set()).add(field) + tree.setdefault(None, OrderedSet()).add(field) return triggers diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py index 5ba87c2dcea..1ddbf2188d5 100644 --- a/odoo/tools/misc.py +++ b/odoo/tools/misc.py @@ -11,6 +11,7 @@ import datetime import hmac as hmac_lib import hashlib import io +import itertools import os import pickle as pickle_ import re @@ -1013,19 +1014,35 @@ class StackMap(MutableMapping): class OrderedSet(MutableSet): """ A set collection that remembers the elements first insertion order. """ __slots__ = ['_map'] + def __init__(self, elems=()): - self._map = OrderedDict((elem, None) for elem in elems) + self._map = dict.fromkeys(elems) + def __contains__(self, elem): return elem in self._map + def __iter__(self): return iter(self._map) + def __len__(self): return len(self._map) + def add(self, elem): self._map[elem] = None + def discard(self, elem): self._map.pop(elem, None) + def update(self, elems): + self._map.update(zip(elems, itertools.repeat(None))) + + def difference_update(self, elems): + for elem in elems: + self.discard(elem) + + def __repr__(self): + return f'{type(self).__name__}({list(self)!r})' + class LastOrderedSet(OrderedSet): """ A set collection that remembers the elements last insertion order. """