class ChainSet(object): """ Base class for various methods to rename chains Contains _chains, which maps from the renamed chain to a tuple with the original (object,state,chain). All dict-like accessors work on ChainSets, e.g. chain_set["A"] -> ("obj",1,"A") """ def __init__(self): # Use an OrderedDict in Python >= 1.7 for better printing if _orderedDict: self._chains = OrderedDict() else: self._chains = dict() def map_chain(self, obj, state, origChain): """ map_chain(string obj,int state, string chain]]) -> string Maps a chain letter to a unique chainID. Results are unique within each instance, and can be used as keys on this chain set. """ raise NotImplementedError("Base class") # delegate most methods to _chains def __getattr__(self, at): if at in "pop popitem update setdefault".split(): raise AttributeError("type object '%s' has no attribute '%s'" % (type(self), at)) return getattr(self._chains, at) def __cmp__(self, other): return self._chains.__cmp__(other) def __eq__(self, other): return self._chains.__eq__(other) def __ge__(self, other): return self._chains.__ge__(other) def __gt__(self, other): return self._chains.__gt__(other) def __le__(self, other): return self._chains.__le__(other) def __lt__(self, other): return self._chains.__lt__(other) def __ne__(self, other): return self._chains.__ne__(other) def __len__(self): return self._chains.__len__() def __contains__(self, key): return self._chains.__contains__(key) def __getitem__(self, key): return self._chains.__getitem__(key) def __iter__(self): return self._chains.__iter__() def __str__(self): return str(self._chains) @staticmethod def _int_to_chain(i, base=_default_base): """ _int_to_chain(int,int) -> str Converts a positive integer to a chain ID. Chain IDs include uppercase characters, numbers, and optionally lowercase letters. i = a positive integer to convert base = the alphabet size to include. Typically 36 or 62. """ if i < 0: raise ValueError("positive integers only") if base < 0 or 62 < base: raise ValueError("Invalid base") quot = int(i) // base rem = i % base if rem < 26: letter = chr(ord("A") + rem) elif rem < 36: letter = str(rem - 26) else: letter = chr(ord("a") + rem - 36) if quot == 0: return letter else: return ChainSet._int_to_chain(quot - 1, base) + letter
class DotMap(OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] if args: d = args[0] if isinstance(d, dict): for k,v in self.__call_items(d): if type(v) is dict: v = DotMap(v, _dynamic=self._dynamic) if type(v) is list: l = [] for i in v: n = i if type(i) is dict: n = DotMap(i, _dynamic=self._dynamic) l.append(n) v = l self._map[k] = v if kwargs: for k,v in self.__call_items(kwargs): if k is not '_dynamic': self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k in {'_map','_dynamic', '_ipython_canary_method_should_not_exist_'}: super(DotMap, self).__setattr__(k,v) else: self[k] = v def __getattr__(self, k): if k == {'_map','_dynamic','_ipython_canary_method_should_not_exist_'}: super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k,v in self.__call_items(self._map): # bizarre recursive assignment situation (why someone would do this is beyond me) if id(v) == id(self): items.append('{0}=DotMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) out = 'DotMap({0})'.format(', '.join(items)) return out def __repr__(self): return str(self) def toDict(self): d = {} for k,v in self.items(): if type(v) is DotMap: # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.toDict() elif type(v) is list: l = [] for i in v: n = i if type(i) is DotMap: n = i.toDict() l.append(n) v = l d[k] = v return d def pprint(self): pprint(self.toDict()) def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return DotMap(self.toDict()) def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d)
class DotMap(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] if args: d = args[0] if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): v = DotMap(v, _dynamic=self._dynamic) if type(v) is list: l = [] for i in v: n = i if type(i) is dict: n = DotMap(i, _dynamic=self._dynamic) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): if k is not '_dynamic': self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(DotMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): # bizarre recursive assignment situation (why someone would do this is beyond me) if id(v) == id(self): items.append('{0}=DotMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) joined = ', '.join(items) out = '{0}({1})'.format(self.__class__.__name__, joined) return out def __repr__(self): return str(self) def toDict(self): d = {} for k, v in self.items(): if type(v) is DotMap: # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.toDict() elif type(v) in (list, tuple): l = [] for i in v: n = i if type(i) is DotMap: n = i.toDict() l.append(n) if type(v) is tuple: v = tuple(l) else: v = l d[k] = v return d def pprint(self, pformat='dict'): if pformat == 'json': print(dumps(self.toDict(), indent=4, sort_keys=True)) else: pprint(self.toDict()) def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return DotMap(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) # bannerStr def _getListStr(self, items): out = '[' mid = '' for i in items: mid += ' {}\n'.format(i) if mid != '': mid = '\n' + mid out += mid out += ']' return out def _getValueStr(self, k, v): outV = v multiLine = len(str(v).split('\n')) > 1 if multiLine: # push to next line outV = '\n' + v if type(v) is list: outV = self._getListStr(v) out = '{} {}'.format(k, outV) return out def _getSubMapDotList(self, pre, name, subMap): outList = [] if pre == '': pre = name else: pre = '{}.{}'.format(pre, name) def stamp(pre, k, v): valStr = self._getValueStr(k, v) return '{}.{}'.format(pre, valStr) for k, v in subMap.items(): if isinstance(v, DotMap) and v != DotMap(): subList = self._getSubMapDotList(pre, k, v) outList.extend(subList) else: outList.append(stamp(pre, k, v)) return outList def _getSubMapStr(self, name, subMap): outList = ['== {} =='.format(name)] for k, v in subMap.items(): if isinstance(v, DotMap) and v != DotMap(): # break down to dots subList = self._getSubMapDotList('', k, v) # add the divit # subList = ['> {}'.format(i) for i in subList] outList.extend(subList) else: out = self._getValueStr(k, v) # out = '> {}'.format(out) out = '{}'.format(out) outList.append(out) finalOut = '\n'.join(outList) return finalOut def bannerStr(self): lines = [] previous = None for k, v in self.items(): if previous == 'DotMap': lines.append('-') out = '' if isinstance(v, DotMap): name = k subMap = v out = self._getSubMapStr(name, subMap) lines.append(out) previous = 'DotMap' else: out = self._getValueStr(k, v) lines.append(out) previous = 'other' lines.append('--') s = '\n'.join(lines) return s
class ChainSet(object): """ Base class for various methods to rename chains Contains _chains, which maps from the renamed chain to a tuple with the original (object,state,chain). All dict-like accessors work on ChainSets, e.g. chain_set["A"] -> ("obj",1,"A") """ def __init__(self): # Use an OrderedDict in Python >= 1.7 for better printing if _orderedDict: self._chains = OrderedDict() else: self._chains = dict() def map_chain(self, obj, state, origChain ): """ map_chain(string obj,int state, string chain]]) -> string Maps a chain letter to a unique chainID. Results are unique within each instance, and can be used as keys on this chain set. """ raise NotImplementedError("Base class") # delegate most methods to _chains def __getattr__(self,at): if at in "pop popitem update setdefault".split(): raise AttributeError("type object '%s' has no attribute '%s'"%(type(self),at)) return getattr(self._chains,at) def __cmp__(self,other): return self._chains.__cmp__(other) def __eq__(self,other): return self._chains.__eq__(other) def __ge__(self,other): return self._chains.__ge__(other) def __gt__(self,other): return self._chains.__gt__(other) def __le__(self,other): return self._chains.__le__(other) def __lt__(self,other): return self._chains.__lt__(other) def __ne__(self,other): return self._chains.__ne__(other) def __len__(self): return self._chains.__len__() def __contains__(self,key): return self._chains.__contains__(key) def __getitem__(self,key): return self._chains.__getitem__(key) def __iter__(self): return self._chains.__iter__() def __str__(self): return str(self._chains) @staticmethod def _int_to_chain(i,base=_default_base): """ _int_to_chain(int,int) -> str Converts a positive integer to a chain ID. Chain IDs include uppercase characters, numbers, and optionally lowercase letters. i = a positive integer to convert base = the alphabet size to include. Typically 36 or 62. """ if i < 0: raise ValueError("positive integers only") if base < 0 or 62 < base: raise ValueError("Invalid base") quot = int(i)//base rem = i%base if rem < 26: letter = chr( ord("A") + rem) elif rem < 36: letter = str( rem-26) else: letter = chr( ord("a") + rem - 36) if quot == 0: return letter else: return ChainSet._int_to_chain(quot-1,base) + letter
class DotMap(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True if kwargs: if "_dynamic" in kwargs: self._dynamic = kwargs["_dynamic"] if args: d = args[0] # for recursive assignment handling trackedIDs = {id(d): self} if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): if id(v) in trackedIDs: v = trackedIDs[id(v)] else: v = self.__class__(v, _dynamic=self._dynamic) trackedIDs[id(v)] = v if type(v) is list: l = [] for i in v: n = i if isinstance(i, dict): n = self.__class__(i, _dynamic=self._dynamic) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): if k is not "_dynamic": self._map[k] = v def __call_items(self, obj): if hasattr(obj, "iteritems") and ismethod(getattr(obj, "iteritems")): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): return self._map[k] def __setattr__(self, k, v): if k in { "_map", "_dynamic", "_ipython_canary_method_should_not_exist_", }: super(DotMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k in { "_map", "_dynamic", "_ipython_canary_method_should_not_exist_", }: return super(DotMap, self).__getattr__(k) try: v = super(self.__class__, self).__getattribute__(k) return v except AttributeError: pass return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __add__(self, other): if self.empty(): return other else: self_type = type(self).__name__ other_type = type(other).__name__ msg = "unsupported operand type(s) for +: '{}' and '{}'" raise TypeError(msg.format(self_type, other_type)) def __str__(self): items = [] for k, v in self.__call_items(self._map): # recursive assignment case if id(v) == id(self): items.append("{0}={1}(...)".format(k, self.__class__.__name__)) else: seperator = "\n" if isinstance(v, DotMap) else " " attr_str = f"{k}:{seperator}{v}" attr_str = self._indent(attr_str, 2) items.append(attr_str) joined = "\n".join(items) return joined def __repr__(self): return str(self) def toDict(self): d = {} for k, v in self.items(): if issubclass(type(v), DotMap): # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.toDict() elif type(v) in (list, tuple): l = [] for i in v: n = i if issubclass(type(i), DotMap): n = i.toDict() l.append(n) if type(v) is tuple: v = tuple(l) else: v = l d[k] = v return d def pprint(self, pformat="dict"): if pformat == "json": print(dumps(self.toDict(), indent=4, sort_keys=True)) else: pprint(self.toDict()) def empty(self): return not any(self) # proper dict subclassing def values(self): return self._map.values() # # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if issubclass(type(other), DotMap): return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return self.__class__(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): return self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = cls() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) # bannerStr def _getListStr(self, items): out = "[" mid = "" for i in items: mid += " {}\n".format(i) if mid != "": mid = "\n" + mid out += mid out += "]" return out def _getValueStr(self, k, v): outV = v multiLine = len(str(v).split("\n")) > 1 if multiLine: # push to next line outV = "\n" + v if type(v) is list: outV = self._getListStr(v) out = "{} {}".format(k, outV) return out def _getSubMapDotList(self, pre, name, subMap): outList = [] if pre == "": pre = name else: pre = "{}.{}".format(pre, name) def stamp(pre, k, v): valStr = self._getValueStr(k, v) return "{}.{}".format(pre, valStr) for k, v in subMap.items(): if isinstance(v, DotMap) and v != DotMap(): subList = self._getSubMapDotList(pre, k, v) outList.extend(subList) else: outList.append(stamp(pre, k, v)) return outList def _getSubMapStr(self, name, subMap): outList = ["== {} ==".format(name)] for k, v in subMap.items(): if isinstance(v, self.__class__) and v != self.__class__(): # break down to dots subList = self._getSubMapDotList("", k, v) # add the divit # subList = ['> {}'.format(i) for i in subList] outList.extend(subList) else: out = self._getValueStr(k, v) # out = '> {}'.format(out) out = "{}".format(out) outList.append(out) finalOut = "\n".join(outList) return finalOut def bannerStr(self): lines = [] previous = None for k, v in self.items(): if previous == self.__class__.__name__: lines.append("-") out = "" if isinstance(v, self.__class__): name = k subMap = v out = self._getSubMapStr(name, subMap) lines.append(out) previous = self.__class__.__name__ else: out = self._getValueStr(k, v) lines.append(out) previous = "other" lines.append("--") s = "\n".join(lines) return s def _indent(self, s_, num_spaces): s = s_.split("\n") if len(s) == 1: return s_ first = s.pop(0) s = [(num_spaces * " ") + line for line in s] s = "\n".join(s) s = first + "\n" + s return s
class Store(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] if args: d = args[0] if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): v = Store(v, _dynamic=self._dynamic) if type(v) is list: ele = [] for i in v: n = i if type(i) is dict: n = Store(i, _dynamic=self._dynamic) ele.append(n) v = ele self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): if k is not '_dynamic': self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and \ self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new Store self[k] = Store() return self._map[k] def __setattr__(self, k, v): if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(Store, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k == { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(Store, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): if id(v) == id(self): items.append('{0}=Store(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) joined = ', '.join(items) out = '{0}({1})'.format(self.__class__.__name__, joined) return out def __repr__(self): return str(self) def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is Store: return other._map else: return other def __cmp__(self, other): other = Store.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = Store.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = Store.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = Store.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = Store.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = Store.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = Store.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return Store(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) @classmethod def fromkeys(cls, seq, value=None): d = Store() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d)
class Maps(MutableMapping): """ Converts a dictionary of key:value pairs into a dotted representation of those keys. Normal string representation of keys is still accessible via normal dictionary indexing. Note: If a key contains non-alphanumeric characters (!@#$%, etc, including spaces), they will be replaced with an underscore (_). Examples: >>> # Normal usage >>> test = {"hello": "world"} >>> print(Maps(test)) Output: Maps(hello="world") >>> test = {"hello": "world"} >>> maps = Maps(test) >>> print(maps.hello) Output: "world" >>> test = {"hello": "world"} >>> maps = Maps(test) >>> print(maps["hello"]) Output: "world" >>> # If a dictionary key has non-alphanumeric characters >>> # Notice how a series of special characters is replaced >>> # by only a single underscore >>> test = {"hello joh*&^n": "hi computer"} >>> maps = Maps(test) >>> print(maps) Output: Maps(hello_joh_n="hi computer") Raises: ValueError: An argument is of a legal type but is, or contains, an illegal value. """ # Class-level variables _dynamic: bool _map: OrderedDict def __init__(self, *args, **kwargs) -> None: super().__init__() self._dynamic = True self._map = OrderedDict() if kwargs: for key, value in self._get_items(kwargs): key = re.sub('[^0-9a-zA-Z]+', '_', key) if key != '_dynamic': self._map[key] = value else: self._dynamic = value if args: dictionary = args[0] if not isinstance(dictionary, dict): raise ValueError( "object passed to constructor must be of type 'dict': " f"'{type(dictionary).__name__}'") # Recursive handling tracked_ids = {id(dictionary): self} for key, value in self._get_items(dictionary): if isinstance(key, str): key = re.sub('[^0-9a-zA-Z]+', '_', key) value_id = id(value) if isinstance(value, dict): if value_id in tracked_ids: value = tracked_ids[value_id] else: value = self.__class__(value, _dynamic=self._dynamic) tracked_ids[value_id] = value if isinstance(value, list): listed_items = [] for item in value: temp_item = item if isinstance(item, dict): temp_item = self.__class__(item, _dynamic=self._dynamic) listed_items.append(temp_item) value = listed_items try: self._map[key] = ast.literal_eval(value) except NameError: if value.lower() == "false": self._map[key] = False elif value.lower() == "true": self._map[key] = True else: self._map[key] = value except (SyntaxError, ValueError): # Cannot eval this value self._map[key] = value # Dunder methods def __add__(self, value: object) -> Union[Any, NoReturn]: if self.empty(): return value else: self_type = type(self).__name__ value_type = type(value).__name__ raise TypeError( f"unsupported operand type(s) for +: '{self_type}' and '{value_type}'" ) def __cmp__(self, value: object) -> Any: value = Maps.parse_value(value) return self._map.__cmp__(value) def __contains__(self, name: str) -> bool: return self._map.__contains__(name) def __copy__(self) -> Maps: return self.__class__(self) def __deepcopy__(self) -> Maps: return self.copy() def __delitem__( self, key: str, dict_delitem: Optional[Callable[..., Any]] = dict.__delitem__) -> Any: return self._map.__delitem__(key, dict_delitem=dict_delitem) def __dir__(self) -> Iterable: return self.keys() def __eq__(self, value: Any) -> bool: value = Maps.parse_value(value) if not isinstance(value, dict): return False return self._map.__eq__(value) def __ge__(self, value: Any) -> bool: value = Maps.parse_value(value) return self._map.__ge__(value) def __gt__(self, value: Any) -> bool: value = Maps.parse_value(value) return self._map.__gt__(value) def __iter__(self) -> Iterable: return self._map.__iter__() def __le__(self, value: Any) -> bool: value = Maps.parse_value(value) return self._map.__le__(value) def __len__(self) -> int: return self._map.__len__() def __lt__(self, value: Any) -> bool: value = Maps.parse_value(value) return self._map.__lt__(value) def __ne__(self, value: Any) -> bool: value = Maps.parse_value(value) return self._map.__ne__(value) def __repr__(self) -> str: return str(self) def __str__(self) -> str: items = [] for key, value in self._get_items(self._map): # Recursive assignment case if id(value) == id(self): items.append("{0}={1}(...)".format(key, self.__class__.__name__)) else: items.append("{0}={1}".format(key, repr(value))) joined = ", ".join(items) return "{0}({1})".format(self.__class__.__name__, joined) def __delattr__(self, name: str) -> None: self._map.__delitem__(name) def __getattr__(self, name: str) -> Any: if name in ('_map', '_dynamic', "_ipython_canary_method_should_not_exist_"): return super().__getattr__(name) try: return super(self.__class__, self).__getattribute__(name) except AttributeError: pass return self[name] def __setattr__(self, name: str, value: Any) -> None: if name in ('_map', '_dynamic', "_ipython_canary_method_should_not_exist_"): super().__setattr__(name, value) else: self[name] = value def __getitem__(self, name: str) -> Union[Any, Maps]: if (name not in self._map and self._dynamic and name != "_ipython_canary_method_should_not_exist_"): self[name] = self.__class__() return self._map[name] def __setitem__(self, name: str, value: Any) -> None: self._map[name] = value def __getstate__(self) -> dict: return self.__dict__ def __setstate__(self, value: dict) -> None: self.__dict__.update(value) # Internal methods def _get_items(self, item: Any) -> Iterable: if hasattr(item, 'iteritems') and ismethod(getattr(item, 'iteritems')): return item.iteritems() else: return item.items() # Public methods def clear(self) -> None: """Remove all items from the Maps object.""" self._map.clear() def copy(self) -> Maps: """Makes a copy of the Maps object in memory.""" return self.__copy__() def empty(self) -> bool: """Returns whether the Maps object is empty.""" return (not any(self)) @classmethod def fromkeys(cls, iterable: Iterable, value: Optional[Any] = None) -> Iterable: """Returns a new :obj:`Maps` object with keys supplied from an iterable setting each key in the object with :term:`value`. Args: iterable (:obj:`Iterable`): Any iterable. value (:obj:`obj`, optional): The value to set for the keys. Default is :obj:`None`. Returns: Maps: The :obj:`Maps` object. """ maps = cls() maps.map = OrderedDict.fromkeys(iterable, value) return maps def get(self, key: str, default: Optional[Any] = None) -> Any: """ Returns the value of 'key'. If :term:`key` does not exist, :term:default` is returned instead. Args: key (:obj:`str`): The key to get the value needed from the dict. default (:obj:`obj`, optional): The value to return if :term:`key` does not exist. Returns: Any: The value at :term:`key` or :term:default`. """ return self._map.get(key, default) def has_key(self, key: str) -> bool: return key in self._map def items(self) -> Generator[Tuple[str, Any]]: """Returns a generator yielding a (key, value) pair.""" return self._get_items(self._map) def iteritems(self) -> Iterator: """ Returns an iterator over the Maps oject's (key, value) pairs. """ return self.items() def iterkeys(self) -> Iterator: """Returns an iterator over the Maps object's keys.""" return self._map.iterkeys() def itervalues(self) -> Iterator: """Returns an iterator over the Maps object's values.""" return self._map.itervalues() def keys(self) -> Iterable: """Returns the keys of the Maps object.""" return self._map.keys() def next(self) -> str: """Returns the next key in the dictionary.""" return self._map.next() @classmethod def parse_ini(cls, ini_dict: ConfigParser, to_maps=False) -> Union[dict, Maps]: """ Converts the values from an INI file from all strings to their actual Python base-types (i.e. int, float, bool, etc). If the value cannot be converted, it is kept as a string. If a value of the key:value pairs is not a string, its type is maintained. Note: Any meant-to-be-bool values in the key:value pairs that are not exactly 'False' or 'True', but are similar like 'false' or 'tRue' for example, will be converted to bools. Args: ini_dict (:obj:`ConfigParser`): The dictionary returned by configparser when an INI file is loaded. to_maps (:obj:`bool`): Return a :obj:`Maps` object instead of a :obj:`dict`. Returns: dict or Maps: A dictionary maintaining the same key:value pairs as the input dictionary; however, the values are their Python base-types. If :obj:`to_maps` is :obj:`True`, return a :obj:`Maps` object. Raises: TypeError: An argument is of an illegal type. """ # Check for dict because of recursion; ini_dict is only meant # to be a dict when the function recursively converts the values # from a ConfigParser if not isinstance(ini_dict, (dict, ConfigParser)): raise TypeError( "argument 'ini_dict' must be of type 'ConfigParser': " f"{type(ini_dict).__name__}") if isinstance(ini_dict, ConfigParser): ini_dict_ = {} for section in ini_dict.sections(): ini_dict_[section] = {} for option in ini_dict.options(section): # Parse using configparser option_value = ini_dict.get(section, option) # Parse using os environ matches = [(m.start(0), m.end(0)) for m in re.finditer("&", option_value)] if len(matches) > 0 and len(matches) % 2 == 0: i = 0 while True: try: index_end = matches.pop(i + 1)[1] index_start = matches.pop(i)[0] sub = option_value[index_start:index_end] sub_replace = os.environ[sub[1:-1]] option_value = option_value.replace( sub, sub_replace) except IndexError: break except KeyError: pass ini_dict_[section][option] = option_value ini_dict = ini_dict_ for key, value in ini_dict.items(): if isinstance(value, dict): # Recursively parse dict ini_dict[key] = Maps.parse_ini(value, to_maps=to_maps) else: if not isinstance(value, str): continue try: ini_dict[key] = ast.literal_eval(value) except NameError: if value.lower() == "false": ini_dict[key] = False elif value.lower() == "true": ini_dict[key] = True else: ini_dict[key] = value except (SyntaxError, ValueError): # Cannot eval this value ini_dict[key] = value return Maps(ini_dict) if to_maps else ini_dict @classmethod def parse_value(cls, value: Any) -> Any: """ Checks if :term:`value` subclasses :obj:`Maps`. If so, it returns the :obj:`Maps` object; otherwise the :term:`value` itself. Args: value (:obj:`Any`): The value to parse. Returns: Any: :obj:`OrderedDict` if :term:`value` subclasses :obj:`Maps`, otherwise :term:`value`. """ if issubclass(type(value), Maps): return value.map else: return value def pop(self, key: str, default: Optional[Any] = None) -> Union[Any, NoReturn]: """ Removes and returns the value in the Maps object at 'key'. If 'key' does not exist, then 'default' is returned. Args: key (:obj:`str`): The key to use to remove a value from the Maps object. default (:obj:`obj`, optional): The value to return if :term:`key` does not exist in the :obj:`Maps` object. Returns: Any: The value at :term:`key`, otherwise :term:`default`. """ return self._map.pop() def popitem(self) -> Any: """Removes and returns an arbitrary (key, value) pair from the :obj:`Maps` object. Returns: Any: The arbitrary (key, value) pair. Raises: KeyError: The :obj:`Maps` object is empty. """ return self._map.popitem() def setdefault(self, key: str, default=None) -> Any: """ Returns a value of the 'key' in the Maps object. If 'key' is not found, then 'default' is inserted at 'key' into the Maps object and then returns that value. Args: key: The key to return the value of. default (:obj:`obj`, optional): The value to insert if 'key' does not exist. Defaults to none. Returns: object: The object at 'key' in the Maps object, default' otherwise. """ return self._map.setdefault(key, default) def to_dict(self) -> Union[dict, NoReturn]: """Converts the :obj:`Maps` object to a stdlib dictionary. Returns: dict: The converted :obj:`Maps` object as a dictionary. """ new_dict = {} for key, value in self.items(): if issubclass(type(value), Maps): if id(value) == id(self): value = new_dict else: value = value.to_dict() elif isinstance(value, (tuple, list)): new_list = [] for item in value: temp_item = item if issubclass(type(item), Maps): temp_item = item.to_dict() new_list.append(temp_item) if isinstance(value, tuple): value = tuple(new_list) else: value = new_list new_dict[key] = value return new_dict def update(self, *args, **kwargs) -> None: """Adds or changes existing values using a dictionary or iterator of key:value pairs.""" if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def values(self) -> Any: """Returns the values of the :obj:`Maps` object.""" return self._map.values() def viewitems(self) -> Any: """Returns a new view of the :obj:`Maps` object's items (key:value pairs).""" return self._map.viewitems() def viewkeys(self) -> Any: """Returns a new view of the :obj:`Maps` object's keys.""" return self._map.viewkeys() def viewvalues(self) -> Any: """Returns a new view of the :obj:`Maps` object's values.""" return self._map.viewvalues()
class DotMap(OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True # mettendo False non funzionano più i test di default. E' normale in quanto si aspettano la creazione dinamica dei figli # =================================== if LORETO: global MY_DICT_TYPES # global var per la classe self._dynamic = False # mettendo False non funzionano più i test di default. E' normale in quanto si aspettano la creazione dinamica dei figli MY_DICT_TYPES = [dict, DotMap] # by Loreto (DEFAULT dictionary) # =================================== if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] if args: d = args[0] if isinstance(d, dict): for k,v in self.__call_items(d): if type(v) is dict: v = DotMap(v, _dynamic=self._dynamic) if type(v) is list: l = [] for i in v: n = i if type(i) is dict: n = DotMap(i, _dynamic=self._dynamic) l.append(n) v = l self._map[k] = v if kwargs: for k,v in self.__call_items(kwargs): if k is not '_dynamic': self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k in {'_map','_dynamic', '_ipython_canary_method_should_not_exist_'}: super(DotMap, self).__setattr__(k,v) else: self[k] = v def __getattr__(self, k): if k == {'_map','_dynamic','_ipython_canary_method_should_not_exist_'}: super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k,v in self.__call_items(self._map): # bizarre recursive assignment situation (why someone would do this is beyond me) if id(v) == id(self): items.append('{0}=DotMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) out = 'DotMap({0})'.format(', '.join(items)) return out def __repr__(self): return str(self) def toDict(self): d = {} for k,v in self.items(): if type(v) is DotMap: # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.toDict() elif type(v) is list: l = [] for i in v: n = i if type(i) is DotMap: n = i.toDict() l.append(n) v = l d[k] = v return d def pprint(self): pprint(self.toDict()) # =================================== if LORETO: # MY_DICT_TYPES = [dict, DotMap] def Ptr(self, listOfQualifiers, create=False): ptr = self for item in listOfQualifiers: if item in ptr: ptr = ptr[item] else: if create: ptr[item] = DotMap() ptr = ptr[item] else: return None return ptr def KeyTree(self, fPRINT=False): return DictToList.KeyTree(self, myDictTYPES=MY_DICT_TYPES, fPRINT=fPRINT) def KeyList(self): return DictToList.KeyList(self, myDictTYPES=MY_DICT_TYPES) def PrintTree(self, fEXIT=False, MaxLevel=10, header=None, printTYPE='LTKV', stackLevel=1): PrintDictionaryTree.PrintDictionary(self, myDictTYPES=MY_DICT_TYPES, printTYPE=printTYPE, fEXIT=fEXIT, MaxLevel=MaxLevel, header=header, stackLevel=stackLevel+1) printDict = PrintTree printTree = PrintTree def GetValue(self, listOfQualifiers=[], fPRINT=False): return DictToList.getValue(self, listOfQualifiers=listOfQualifiers, myDictTYPES=MY_DICT_TYPES, fPRINT=fPRINT) # =================================== def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return DotMap(self.toDict()) def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d)
class DotMap(OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() if args: d = args[0] if type(d) is dict: for k,v in self.__call_items(d): if type(v) is dict: v = DotMap(v) self._map[k] = v if kwargs: for k,v in self.__call_items(kwargs): self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map: # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k == '_map': super(DotMap, self).__setattr__(k,v) else: self[k] = v def __getattr__(self, k): if k == '_map': super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k,v in self.__call_items(self._map): items.append('{0}={1}'.format(k, repr(v))) out = 'DotMap({0})'.format(', '.join(items)) return out def __repr__(self): return str(self) def toDict(self): d = {} for k,v in self.items(): if type(v) is DotMap: v = v.toDict() d[k] = v return d def pprint(self): pprint(self.toDict()) # proper dict subclassing def values(self): return self._map.values() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return self def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d
class DotMap(OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() if args: d = args[0] if type(d) is dict: for k, v in self.__call_items(d): if type(v) is dict: v = DotMap(v) self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map: # DON'T automatically extend to new DotMap # self[k] = DotMap() raise AttributeError('%s is not defined in DotMap' % k) return self._map[k] def __setattr__(self, k, v): if k == '_map': super(DotMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k == '_map': super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): items.append('{0}={1}'.format(k, repr(v))) out = 'DotMap({0})'.format(', '.join(items)) return out def __repr__(self): return str(self) def toDict(self): d = {} for k, v in self.items(): if type(v) is DotMap: v = v.toDict() d[k] = v return d def pprint(self): pprint(self.toDict()) # proper dict subclassing def values(self): return self._map.values() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return self def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d
class ConfigMap(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() # todo: simplify self._dynamic = True if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] del kwargs['_dynamic'] self._evaluate = True if kwargs: if '_evaluate' in kwargs: self._evaluate = kwargs['_evaluate'] del kwargs['_evaluate'] self._evaluated = False if kwargs: if '_evaluated' in kwargs: self._evaluated = kwargs['_evaluated'] del kwargs['_evaluated'] if args: d = args[0] if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): v = ConfigMap(v, _dynamic=self._dynamic, _evaluate=self._evaluate, _evaluated=self._evaluated) if type(v) is list: l = [] for i in v: n = i if type(i) is dict: n = ConfigMap(i, _dynamic=self._dynamic, _evaluate=self._evaluate, _evaluated=self._evaluated) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k, evaluate=None): if evaluate is None: evaluate = self._evaluate if k not in self._map: if k == '_ipython_canary_method_should_not_exist_': raise KeyError if self._dynamic: # automatically extend to new ConfigMap self[k] = ConfigMap() else: # todo: display full recursive path? raise KeyError("'%s' does not exist" % k) var = self._map[k] if evaluate: if isinstance(var, ConfigMethod): var = var.evaluate() # todo: return instead to avoid second config map eval? if isinstance(var, ConfigMap): var = var.evaluate() return var def __setattr__(self, k, v): if k in ['_map', '_dynamic', '_ipython_canary_method_should_not_exist_', '_evaluate', '_evaluated']: super(ConfigMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k in ['_map', '_dynamic', '_ipython_canary_method_should_not_exist_', '_evaluate', '_evaluated']: return self.__getattribute__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): # bizarre recursive assignment situation (why someone would do this is beyond me) if id(v) == id(self): items.append('{0}=ConfigMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) joined = ', '.join(items) out = '{0}({1})'.format(self.__class__.__name__, joined) return out def __repr__(self): return str(self) def toDict(self, evaluate=None, with_hidden=True): if evaluate is None: evaluate = bool(self._evaluate) d = {} for k, v in self.items(): if evaluate and isinstance(v, ConfigMethod): v = v.evaluate() if isinstance(v, ConfigMap): v = v.toDict(evaluate=evaluate, with_hidden=with_hidden) if id(v) != id(self) else d elif isinstance(v, list): v = [i.toDict(evaluate=evaluate, with_hidden=with_hidden) if isinstance(i, ConfigMap) else i for i in v] elif isinstance(v, tuple): v = (i.toDict(evaluate=evaluate, with_hidden=with_hidden) if isinstance(i, ConfigMap) else i for i in v) if with_hidden is False \ and (isinstance(k, str) and ((k.startswith('_') and not k.endswith('_')) or k.startswith('~'))): continue d[k] = v return d def evaluate(self): if self._evaluated: return self # TODO: case where config method access a key of the config that is just being evaluated. # shouldn't give an endless loop # todo: make more efficient return ConfigMap(self.toDict(evaluate=True), _dynamic=False, _evaluated=True) def pprint(self, pformat='json'): if pformat == 'json': print(dumps(self.toDict(), indent=4, sort_keys=True, default=str)) else: pprint(self.toDict()) def empty(self): return not any(self) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is ConfigMap: return other._map else: return other def __cmp__(self, other): other = ConfigMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = ConfigMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = ConfigMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = ConfigMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = ConfigMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = ConfigMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = ConfigMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return ConfigMap(self, _dynamic=self._dynamic, _evaluate=self._evaluate, _evaluated=self._evaluated) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = ConfigMap(_dynamic=False) d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) # bannerStr def _getListStr(self, items): out = '[' mid = '' for i in items: mid += ' {}\n'.format(i) if mid != '': mid = '\n' + mid out += mid out += ']' return out def _getValueStr(self, k, v): outV = v multiLine = len(str(v).split('\n')) > 1 if multiLine: # push to next line outV = '\n' + v if type(v) is list: outV = self._getListStr(v) out = '{} {}'.format(k, outV) return out def _getSubMapDotList(self, pre, name, subMap): outList = [] if pre == '': pre = name else: pre = '{}.{}'.format(pre, name) def stamp(pre, k, v): valStr = self._getValueStr(k, v) return '{}.{}'.format(pre, valStr) for k, v in subMap.items(): if isinstance(v, ConfigMap) and v != ConfigMap(): subList = self._getSubMapDotList(pre, k, v) outList.extend(subList) else: outList.append(stamp(pre, k, v)) return outList def _getSubMapStr(self, name, subMap): outList = ['== {} =='.format(name)] for k, v in subMap.items(): if isinstance(v, ConfigMap) and v != ConfigMap(): # break down to dots subList = self._getSubMapDotList('', k, v) # add the divit # subList = ['> {}'.format(i) for i in subList] outList.extend(subList) else: out = self._getValueStr(k, v) # out = '> {}'.format(out) out = '{}'.format(out) outList.append(out) finalOut = '\n'.join(outList) return finalOut def bannerStr(self): lines = [] previous = None for k, v in self.items(): if previous == 'ConfigMap': lines.append('-') out = '' if isinstance(v, ConfigMap): name = k subMap = v out = self._getSubMapStr(name, subMap) lines.append(out) previous = 'ConfigMap' else: out = self._getValueStr(k, v) lines.append(out) previous = 'other' lines.append('--') s = '\n'.join(lines) return s
class Dictionary(): def __init__(self): self.__dictionary = OrderedDict() def clear(self): self.__dictionary.clear() def get_json(self): return json.dumps(self.__dictionary) def set_item(self, key, value): self.__dictionary.__setitem__(key, value) return self def values(self): return [value for value in self.__dictionary.values().__iter__()] def items(self): return self.__dictionary.items() def copy(self): self.__dictionary def constain(self, key): return key in self.get_list_of_key() def get(self, key): return self.__dictionary.get(key) def clear(self, key, default): self.__dictionary.pop(key, default) def format(self, *args, **kwargs): return self.__dictionary.__format__(*args, **kwargs) def ne(self, *args, **kwargs): return self.__dictionary.__ne__(*args, **kwargs) def repr(self, *args, **kwargs): return self.__dictionary.__repr__(*args, **kwargs) def ge(self, *args, **kwargs): return self.dictionary__ge__(*args, **kwargs) def __sizeof__(self): return self.__dictionary.__sizeof__() def setattr(self, *args, **kwargs): return self.__dictionary.__setattr__(*args, **kwargs) def dir(self): return self.__dictionary.__dir__() def le(self, *args, **kwargs): return self.__dictionary.__le__(*args, **kwargs) def delattr(self, *args, **kwargs): return self.__dictionary.__delattr__(*args, **kwargs) def hash(self, *args, **kwargs): return self.__dictionary.__hash__(*args, **kwargs) def gt(self, *args, **kwargs): return self.__dictionary.__gt__(*args, **kwargs) def eq(self, *args, **kwargs): return self.__dictionary.__eq__(*args, **kwargs) def getattribute(self, *args, **kwargs): return self.__dictionary.__getattribute__(*args, **kwargs) def str(self, *args, **kwargs): return self.__dictionary.__str__(*args, **kwargs) def reduce(self, *args, **kwargs): return self.__dictionary.__reduce__(*args, **kwargs) def reduce_ex(self, *args, **kwargs): return self.__dictionary.__reduce_ex__(*args, **kwargs) def lt(self, *args, **kwargs): return self.__dictionary.__lt__(*args, **kwargs) def keys(self): return self.get_list_of_key() def get_list_of_key(self): return [key for key in self.__dictionary.keys().__iter__()]
class DotMap(OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = True # mettendo False non funzionano più i test di default. E' normale in quanto si aspettano la creazione dinamica dei figli # =================================== if LORETO: global MY_DICT_TYPES # global var per la classe self._dynamic = False # mettendo False non funzionano più i test di default. E' normale in quanto si aspettano la creazione dinamica dei figli MY_DICT_TYPES = [dict, DotMap, OrderedDict] # by Loreto (DEFAULT dictionary) # =================================== if kwargs: if '_dynamic' in kwargs: self._dynamic = kwargs['_dynamic'] if args: d = args[0] if isinstance(d, dict): for k, v in self.__call_items(d): if type(v) is dict: v = DotMap(v, _dynamic=self._dynamic) if type(v) is list: l = [] for i in v: n = i if type(i) is dict: n = DotMap(i, _dynamic=self._dynamic) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): if k is not '_dynamic': self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(DotMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k == { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): # bizarre recursive assignment situation (why someone would do this is beyond me) if id(v) == id(self): items.append('{0}=DotMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) out = 'DotMap({0})'.format(', '.join(items)) return out def __repr__(self): return str(self) def toDict(self): d = {} for k, v in self.items(): if type(v) is DotMap: # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.toDict() elif type(v) is list: l = [] for i in v: n = i if type(i) is DotMap: n = i.toDict() l.append(n) v = l d[k] = v return d def pprint(self): pprint(self.toDict()) # =================================== if LORETO: # MY_DICT_TYPES = [dict, DotMap] def Ptr(self, listOfQualifiers, create=False): ptr = self for item in listOfQualifiers: if item in ptr: ptr = ptr[item] else: if create: ptr[item] = DotMap() ptr = ptr[item] else: return None return ptr def KeyTree(self, fPRINT=False): return DictToList.KeyTree(self, myDictTYPES=MY_DICT_TYPES, fPRINT=fPRINT) def KeyList(self): return DictToList.KeyList(self, myDictTYPES=MY_DICT_TYPES) def PrintTree(self, fEXIT=False, maxDepth=10, header=None, whatPrint='LTKV', stackLevel=1): PrintDictionaryTree.PrintDictionary(self, myDictTYPES=MY_DICT_TYPES, whatPrint=whatPrint, fEXIT=fEXIT, maxDepth=maxDepth, header=header, stackLevel=stackLevel + 1) printDict = PrintTree printTree = PrintTree def GetValue(self, listOfQualifiers=[], fPRINT=False): return DictToList.getValue(self, listOfQualifiers=listOfQualifiers, myDictTYPES=MY_DICT_TYPES, fPRINT=fPRINT) # =================================== def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if type(other) is DotMap: return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return DotMap(self.toDict()) def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d)
class DotMap(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() if args: assert len(args) == 1 d = args[0] if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): v = DotMap(v) if isinstance(v, list): l = [] for i in v: n = i if isinstance(i, dict): n = DotMap(i) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and k != IPYTHON_CANNARY: # automatically extend to new DotMap self[k] = DotMap() return self._map[k] def __setattr__(self, k, v): if k in {'_map', IPYTHON_CANNARY}: super(DotMap, self).__setattr__(k, v) else: self[k] = v def __getattr__(self, k): if k == {'_map', IPYTHON_CANNARY}: super(DotMap, self).__getattr__(k) else: return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __str__(self): items = [] for k, v in self.__call_items(self._map): if id(v) == id(self): items.append('{0}=DotMap(...)'.format(k)) else: items.append('{0}={1}'.format(k, repr(v))) joined = ', '.join(items) out = '{0}({1})'.format(self.__class__.__name__, joined) return out __repr__ = __str__ def toDict(self): d = {} for k, v in self.items(): if isinstance(v, DotMap): if id(v) == id(self): v = d else: v = v.toDict() elif isinstance(v, (list, tuple)): l = [] for i in v: n = i if type(i) is DotMap: n = i.toDict() l.append(n) if isinstance(v, tuple): v = tuple(l) else: v = l d[k] = v return d def empty(self): return (not any(self)) def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parse_other(cls, other): if isinstance(other, DotMap): return other._map return other def __cmp__(self, other): other = DotMap.parse_other(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parse_other(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parse_other(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parse_other(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parse_other(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parse_other(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parse_other(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return DotMap(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = DotMap() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d)
class Config(MutableMapping, OrderedDict): @classmethod def load(cls, file_path): with open(file_path) as f: params = yaml.load(f.read(), Loader=yaml.FullLoader) # We expand ~ in those yaml entries with `path` # on their keys for making # config files more platform-independent params = { key: (os.path.expanduser(value) if "path" in key and value is not None else value) for key, value in params.items() } return cls(params) def dump(self, file_path): with open(file_path, "w") as f: d = self.to_dict() f.write(yaml.dump(d)) def __init__(self, *args, **kwargs): self._map = OrderedDict() if args: d = args[0] # for recursive assignment handling trackedIDs = {id(d): self} if isinstance(d, dict): for k, v in self.__call_items(d): if isinstance(v, dict): if id(v) in trackedIDs: v = trackedIDs[id(v)] else: v = self.__class__(v) trackedIDs[id(v)] = v if type(v) is list: l = [] for i in v: n = i if isinstance(i, dict): n = self.__class__(i) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): self._map[k] = v _path_state = list() def __call_items(self, obj): if hasattr(obj, "iteritems") and ismethod(getattr(obj, "iteritems")): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): # print('Called __setitem__') if (k in self._map and not self._map[k] is None and not isinstance(v, type(self._map[k]))): if v is not None: raise ValueError( f"Updating existing value {type(self._map[k])} " f"with different type ({type(v)}).") split_path = k.split(".") current_option = self._map for p in split_path[:-1]: current_option = current_option[p] current_option[split_path[-1]] = v def __getitem__(self, k): split_path = k.split(".") current_option = self._map for p in split_path: if p not in current_option: raise KeyError(p) current_option = current_option[p] return current_option def __setattr__(self, k, v): if k in {"_map", "_ipython_canary_method_should_not_exist_"}: super(Config, self).__setattr__(k, v) else: self[k].update(v) def __getattr__(self, k): if k in {"_map", "_ipython_canary_method_should_not_exist_"}: return super(Config, self).__getattr__(k) try: v = super(self.__class__, self).__getattribute__(k) return v except AttributeError: self._path_state.append(k) pass return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __add__(self, other): if self.empty(): return other else: self_type = type(self).__name__ other_type = type(other).__name__ msg = "unsupported operand type(s) for +: '{}' and '{}'" raise TypeError(msg.format(self_type, other_type)) def __str__(self): items = [] for k, v in self.__call_items(self._map): # recursive assignment case if id(v) == id(self): items.append("{0}={1}(...)".format(k, self.__class__.__name__)) else: items.append("{0}={1}".format(k, repr(v))) joined = ", ".join(items) out = "{0}({1})".format(self.__class__.__name__, joined) return out def __repr__(self): return str(self) def to_dict(self, flatten=False, parent_key="", sep="."): d = {} for k, v in self.items(): if issubclass(type(v), Config): # bizarre recursive assignment support if id(v) == id(self): v = d else: v = v.to_dict() elif type(v) in (list, tuple): l = [] for i in v: n = i if issubclass(type(i), Config): n = i.to_dict() l.append(n) if type(v) is tuple: v = tuple(l) else: v = l d[k] = v if flatten: d = flatten_dict(d, parent_key=parent_key, sep=sep) return d def pprint(self, ): pprint(self.to_dict()) def empty(self): return not any(self) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return list(self.keys()) def _ipython_key_completions_(self): return list(self.keys()) @classmethod def parseOther(cls, other): if issubclass(type(other), Config): return other._map else: return other def __cmp__(self, other): other = Config.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = Config.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = Config.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = Config.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = Config.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = Config.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = Config.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return self.__class__(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) == 1: for key, value in args[0].items(): if key in self and isinstance(self[key], dict): if value is None: self[key] = value else: self[key].update(value) else: pass raise ValueError() elif len(args) > 1: raise NotImplementedError # self._map.update(*args) else: raise NotImplementedError def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = cls() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) # bannerStr def _getListStr(self, items): out = "[" mid = "" for i in items: mid += " {}\n".format(i) if mid != "": mid = "\n" + mid out += mid out += "]" return out def _getValueStr(self, k, v): outV = v multiLine = len(str(v).split("\n")) > 1 if multiLine: # push to next line outV = "\n" + v if type(v) is list: outV = self._getListStr(v) out = "{} {}".format(k, outV) return out def _getSubMapDotList(self, pre, name, subMap): outList = [] if pre == "": pre = name else: pre = "{}.{}".format(pre, name) def stamp(pre, k, v): valStr = self._getValueStr(k, v) return "{}.{}".format(pre, valStr) for k, v in subMap.items(): if isinstance(v, Config) and v != Config(): subList = self._getSubMapDotList(pre, k, v) outList.extend(subList) else: outList.append(stamp(pre, k, v)) return outList def _getSubMapStr(self, name, subMap): outList = ["== {} ==".format(name)] for k, v in subMap.items(): if isinstance(v, self.__class__) and v != self.__class__(): # break down to dots subList = self._getSubMapDotList("", k, v) # add the divit # subList = ['> {}'.format(i) for i in subList] outList.extend(subList) else: out = self._getValueStr(k, v) # out = '> {}'.format(out) out = "{}".format(out) outList.append(out) finalOut = "\n".join(outList) return finalOut def bannerStr(self): lines = [] previous = None for k, v in self.items(): if previous == self.__class__.__name__: lines.append("-") out = "" if isinstance(v, self.__class__): name = k subMap = v out = self._getSubMapStr(name, subMap) lines.append(out) previous = self.__class__.__name__ else: out = self._getValueStr(k, v) lines.append(out) previous = "other" lines.append("--") s = "\n".join(lines) return s
class DotMap(MutableMapping, OrderedDict): def __init__(self, *args, **kwargs): self._map = OrderedDict() self._dynamic = kwargs.pop('_dynamic', True) self._prevent_method_masking = kwargs.pop('_prevent_method_masking', False) trackedIDs = kwargs.pop('_trackedIDs', {}) if args: d = args[0] # for recursive assignment handling trackedIDs[id(d)] = self src = [] if isinstance(d, MutableMapping): src = self.__call_items(d) elif isinstance(d, Iterable): src = d for k, v in src: if self._prevent_method_masking and k in reserved_keys: raise KeyError('"{}" is reserved'.format(k)) if isinstance(v, dict): idv = id(v) if idv in trackedIDs: v = trackedIDs[idv] else: trackedIDs[idv] = v v = self.__class__(v, _dynamic=self._dynamic, _prevent_method_masking=self. _prevent_method_masking, _trackedIDs=trackedIDs) if type(v) is list: l = [] for i in v: n = i if isinstance(i, dict): idi = id(i) if idi in trackedIDs: n = trackedIDs[idi] else: trackedIDs[idi] = i n = self.__class__( i, _dynamic=self._dynamic, _prevent_method_masking=self. _prevent_method_masking) l.append(n) v = l self._map[k] = v if kwargs: for k, v in self.__call_items(kwargs): if self._prevent_method_masking and k in reserved_keys: raise KeyError('"{}" is reserved'.format(k)) self._map[k] = v def __call_items(self, obj): if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')): return obj.iteritems() else: return obj.items() def items(self): return self.iteritems() def iteritems(self): return self.__call_items(self._map) def __iter__(self): return self._map.__iter__() def next(self): return self._map.next() def __setitem__(self, k, v): self._map[k] = v def __getitem__(self, k): if k not in self._map and self._dynamic and k != '_ipython_canary_method_should_not_exist_': # automatically extend to new DotMap self[k] = self.__class__() return self._map[k] def __setattr__(self, k, v): if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_', '_prevent_method_masking' }: super(DotMap, self).__setattr__(k, v) elif self._prevent_method_masking and k in reserved_keys: raise KeyError('"{}" is reserved'.format(k)) else: self[k] = v def __getattr__(self, k): if k.startswith('__') and k.endswith('__'): raise AttributeError(k) if k in { '_map', '_dynamic', '_ipython_canary_method_should_not_exist_' }: return super(DotMap, self).__getattr__(k) try: v = super(self.__class__, self).__getattribute__(k) return v except AttributeError: pass return self[k] def __delattr__(self, key): return self._map.__delitem__(key) def __contains__(self, k): return self._map.__contains__(k) def __add__(self, other): if self.empty(): return other else: self_type = type(self).__name__ other_type = type(other).__name__ msg = "unsupported operand type(s) for +: '{}' and '{}'" raise TypeError(msg.format(self_type, other_type)) def __str__(self, seen=None): items = [] seen = {id(self)} if seen is None else seen for k, v in self.__call_items(self._map): # circular assignment case if isinstance(v, self.__class__): if id(v) in seen: items.append('{0}={1}(...)'.format( k, self.__class__.__name__)) else: seen.add(id(v)) items.append('{0}={1}'.format(k, v.__str__(seen))) else: items.append('{0}={1}'.format(k, repr(v))) joined = ', '.join(items) out = '{0}({1})'.format(self.__class__.__name__, joined) return out def __repr__(self): return str(self) def toDict(self, seen=None): if seen is None: seen = {} d = {} seen[id(self)] = d for k, v in self.items(): if issubclass(type(v), DotMap): idv = id(v) if idv in seen: v = seen[idv] else: v = v.toDict(seen=seen) elif type(v) in (list, tuple): l = [] for i in v: n = i if issubclass(type(i), DotMap): idv = id(n) if idv in seen: n = seen[idv] else: n = i.toDict(seen=seen) l.append(n) if type(v) is tuple: v = tuple(l) else: v = l d[k] = v return d def pprint(self, pformat='dict'): if pformat == 'json': print(dumps(self.toDict(), indent=4, sort_keys=True)) else: pprint(self.toDict()) def empty(self): return (not any(self)) # proper dict subclassing def values(self): return self._map.values() # ipython support def __dir__(self): return self.keys() @classmethod def parseOther(self, other): if issubclass(type(other), DotMap): return other._map else: return other def __cmp__(self, other): other = DotMap.parseOther(other) return self._map.__cmp__(other) def __eq__(self, other): other = DotMap.parseOther(other) if not isinstance(other, dict): return False return self._map.__eq__(other) def __ge__(self, other): other = DotMap.parseOther(other) return self._map.__ge__(other) def __gt__(self, other): other = DotMap.parseOther(other) return self._map.__gt__(other) def __le__(self, other): other = DotMap.parseOther(other) return self._map.__le__(other) def __lt__(self, other): other = DotMap.parseOther(other) return self._map.__lt__(other) def __ne__(self, other): other = DotMap.parseOther(other) return self._map.__ne__(other) def __delitem__(self, key): return self._map.__delitem__(key) def __len__(self): return self._map.__len__() def clear(self): self._map.clear() def copy(self): return self.__class__(self) def __copy__(self): return self.copy() def __deepcopy__(self, memo=None): return self.copy() def get(self, key, default=None): return self._map.get(key, default) def has_key(self, key): return key in self._map def iterkeys(self): return self._map.iterkeys() def itervalues(self): return self._map.itervalues() def keys(self): return self._map.keys() def pop(self, key, default=None): return self._map.pop(key, default) def popitem(self): return self._map.popitem() def setdefault(self, key, default=None): return self._map.setdefault(key, default) def update(self, *args, **kwargs): if len(args) != 0: self._map.update(*args) self._map.update(kwargs) def viewitems(self): return self._map.viewitems() def viewkeys(self): return self._map.viewkeys() def viewvalues(self): return self._map.viewvalues() @classmethod def fromkeys(cls, seq, value=None): d = cls() d._map = OrderedDict.fromkeys(seq, value) return d def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__.update(d) # bannerStr def _getListStr(self, items): out = '[' mid = '' for i in items: mid += ' {}\n'.format(i) if mid != '': mid = '\n' + mid out += mid out += ']' return out def _getValueStr(self, k, v): outV = v multiLine = len(str(v).split('\n')) > 1 if multiLine: # push to next line outV = '\n' + v if type(v) is list: outV = self._getListStr(v) out = '{} {}'.format(k, outV) return out def _getSubMapDotList(self, pre, name, subMap): outList = [] if pre == '': pre = name else: pre = '{}.{}'.format(pre, name) def stamp(pre, k, v): valStr = self._getValueStr(k, v) return '{}.{}'.format(pre, valStr) for k, v in subMap.items(): if isinstance(v, DotMap) and v != DotMap(): subList = self._getSubMapDotList(pre, k, v) outList.extend(subList) else: outList.append(stamp(pre, k, v)) return outList def _getSubMapStr(self, name, subMap): outList = ['== {} =='.format(name)] for k, v in subMap.items(): if isinstance(v, self.__class__) and v != self.__class__(): # break down to dots subList = self._getSubMapDotList('', k, v) # add the divit # subList = ['> {}'.format(i) for i in subList] outList.extend(subList) else: out = self._getValueStr(k, v) # out = '> {}'.format(out) out = '{}'.format(out) outList.append(out) finalOut = '\n'.join(outList) return finalOut def bannerStr(self): lines = [] previous = None for k, v in self.items(): if previous == self.__class__.__name__: lines.append('-') out = '' if isinstance(v, self.__class__): name = k subMap = v out = self._getSubMapStr(name, subMap) lines.append(out) previous = self.__class__.__name__ else: out = self._getValueStr(k, v) lines.append(out) previous = 'other' lines.append('--') s = '\n'.join(lines) return s