1 # -*- coding: utf-8 -*-
2 #modification pour python 3 : Laurent Mérat, 6x7 - mai 2020
5 #------------------------------------
6 # import des modules python
7 #------------------------------------
8 from collections.abc import MutableMapping
12 from _thread import get_ident
15 from _thread import get_ident
17 from _dummy_thread import get_ident
21 def recursive_repr(fillvalue='...'):
22 'Decorator to make a repr function return fillvalue for a recursive call'
24 def decorating_function(user_function):
28 key = id(self), get_ident()
29 if key in repr_running:
33 result = user_function(self)
35 repr_running.discard(key)
38 # Can't use functools.wraps() here because of bootstrap issues
39 wrapper.__module__ = getattr(user_function, '__module__')
40 wrapper.__doc__ = getattr(user_function, '__doc__')
41 wrapper.__name__ = getattr(user_function, '__name__')
42 wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
45 return decorating_function
47 # from collections 3.2.1
49 class _ChainMap(MutableMapping):
50 ''' A ChainMap groups multiple dicts (or other mappings) together
51 to create a single, updateable view.
53 The underlying mappings are stored in a list. That list is public and can
54 accessed or updated using the *maps* attribute. There is no other state.
56 Lookups search the underlying mappings successively until a key is found.
57 In contrast, writes, updates, and deletions only operate on the first
62 def __init__(self, *maps):
63 '''Initialize a ChainMap by setting *maps* to the given mappings.
64 If no mappings are provided, a single empty dictionary is used.
67 self.maps = list(maps) or [{}] # always at least one map
69 def __missing__(self, key):
72 def __getitem__(self, key):
73 for mapping in self.maps:
75 return mapping[key] # can't use 'key in mapping' with defaultdict
78 return self.__missing__(key) # support subclasses that define __missing__
80 def get(self, key, default=None):
81 return self[key] if key in self else default
84 return len(set().union(*self.maps)) # reuses stored hash values if possible
87 return iter(set().union(*self.maps))
89 def __contains__(self, key):
90 return any(key in m for m in self.maps)
94 return '{0.__class__.__name__}({1})'.format(
95 self, ', '.join(map(repr, self.maps)))
98 def fromkeys(cls, iterable, *args):
99 'Create a ChainMap with a single dict created from the iterable.'
100 return cls(dict.fromkeys(iterable, *args))
103 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
104 return self.__class__(self.maps[0].copy(), *self.maps[1:])
108 def new_child(self): # like Django's Context.push()
109 'New ChainMap with a new dict followed by all previous maps.'
110 return self.__class__({}, *self.maps)
113 def parents(self): # like Django's Context.pop()
114 'New ChainMap from maps[1:].'
115 return self.__class__(*self.maps[1:])
117 def __setitem__(self, key, value):
118 self.maps[0][key] = value
120 def __delitem__(self, key):
122 del self.maps[0][key]
124 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
127 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
129 return self.maps[0].popitem()
131 raise KeyError('No keys found in the first mapping.')
133 def pop(self, key, *args):
134 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
136 return self.maps[0].pop(key, *args)
138 raise KeyError('Key not found in the first mapping: {!r}'.format(key))
141 'Clear maps[0], leaving maps[1:] intact.'