/opt/imh-python/lib/python3.9/site-packages/IPython/utils
NameSizeModeActions
tests/-0755rm
__pycache__/-0755rm
capture.py51610644editdlrm
colorable.py7860644editdlrm
coloransi.py69720644editdlrm
contexts.py16190644editdlrm
daemonize.py2000644editdlrm
data.py10150644editdlrm
decorators.py26800644editdlrm
dir2.py22320644editdlrm
docs.py860644editdlrm
encoding.py28430644editdlrm
eventful.py1380644editdlrm
frame.py30480644editdlrm
generics.py7060644editdlrm
importstring.py10500644editdlrm
io.py46310644editdlrm
ipstruct.py118560644editdlrm
jsonutil.py1480644editdlrm
localinterfaces.py1690644editdlrm
log.py1230644editdlrm
module_paths.py23270644editdlrm
openpy.py34170644editdlrm
path.py119370644editdlrm
process.py18780644editdlrm
py3compat.py16020644editdlrm
PyColorize.py108750644editdlrm
sentinel.py4210644editdlrm
shimmodule.py26690644editdlrm
signatures.py4740644editdlrm
strdispatch.py18380644editdlrm
sysinfo.py43650644editdlrm
syspathcontext.py19520644editdlrm
tempdir.py18670644editdlrm
terminal.py32060644editdlrm
text.py244280644editdlrm
timing.py42750644editdlrm
tokenutil.py50830644editdlrm
traitlets.py1430644editdlrm
tz.py13800644editdlrm
ulinecache.py6840644editdlrm
version.py12230644editdlrm
wildcard.py46120644editdlrm
_process_cli.py20200644editdlrm
_process_common.py70030644editdlrm
_process_posix.py86660644editdlrm
_process_win32.py61320644editdlrm
_process_win32_controller.py213290644editdlrm
_sysinfo.py450644editdlrm
__init__.py00644editdlrm
Edit: /opt/imh-python/lib/python3.9/site-packages/IPython/utils/ipstruct.py (11856B)
# encoding: utf-8 """A dict subclass that supports attribute style access. Authors: * Fernando Perez (original) * Brian Granger (refactoring to a dict subclass) """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- __all__ = ['Struct'] #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class Struct(dict): """A dict subclass with attribute style access. This dict subclass has a a few extra features: * Attribute style access. * Protection of class members (like keys, items) when using attribute style access. * The ability to restrict assignment to only existing keys. * Intelligent merging. * Overloaded operators. """ _allownew = True def __init__(self, *args, **kw): """Initialize with a dictionary, another Struct, or data. Parameters ---------- *args : dict, Struct Initialize with one dict or Struct **kw : dict Initialize with key, value pairs. Examples -------- >>> s = Struct(a=10,b=30) >>> s.a 10 >>> s.b 30 >>> s2 = Struct(s,c=30) >>> sorted(s2.keys()) ['a', 'b', 'c'] """ object.__setattr__(self, '_allownew', True) dict.__init__(self, *args, **kw) def __setitem__(self, key, value): """Set an item with check for allownew. Examples -------- >>> s = Struct() >>> s['a'] = 10 >>> s.allow_new_attr(False) >>> s['a'] = 10 >>> s['a'] 10 >>> try: ... s['b'] = 20 ... except KeyError: ... print('this is not allowed') ... this is not allowed """ if not self._allownew and key not in self: raise KeyError( "can't create new attribute %s when allow_new_attr(False)" % key) dict.__setitem__(self, key, value) def __setattr__(self, key, value): """Set an attr with protection of class members. This calls :meth:`self.__setitem__` but convert :exc:`KeyError` to :exc:`AttributeError`. Examples -------- >>> s = Struct() >>> s.a = 10 >>> s.a 10 >>> try: ... s.get = 10 ... except AttributeError: ... print("you can't set a class member") ... you can't set a class member """ # If key is an str it might be a class member or instance var if isinstance(key, str): # I can't simply call hasattr here because it calls getattr, which # calls self.__getattr__, which returns True for keys in # self._data. But I only want keys in the class and in # self.__dict__ if key in self.__dict__ or hasattr(Struct, key): raise AttributeError( 'attr %s is a protected member of class Struct.' % key ) try: self.__setitem__(key, value) except KeyError as e: raise AttributeError(e) from e def __getattr__(self, key): """Get an attr by calling :meth:`dict.__getitem__`. Like :meth:`__setattr__`, this method converts :exc:`KeyError` to :exc:`AttributeError`. Examples -------- >>> s = Struct(a=10) >>> s.a 10 >>> type(s.get) <...method'> >>> try: ... s.b ... except AttributeError: ... print("I don't have that key") ... I don't have that key """ try: result = self[key] except KeyError as e: raise AttributeError(key) from e else: return result def __iadd__(self, other): """s += s2 is a shorthand for s.merge(s2). Examples -------- >>> s = Struct(a=10,b=30) >>> s2 = Struct(a=20,c=40) >>> s += s2 >>> sorted(s.keys()) ['a', 'b', 'c'] """ self.merge(other) return self def __add__(self,other): """s + s2 -> New Struct made from s.merge(s2). Examples -------- >>> s1 = Struct(a=10,b=30) >>> s2 = Struct(a=20,c=40) >>> s = s1 + s2 >>> sorted(s.keys()) ['a', 'b', 'c'] """ sout = self.copy() sout.merge(other) return sout def __sub__(self,other): """s1 - s2 -> remove keys in s2 from s1. Examples -------- >>> s1 = Struct(a=10,b=30) >>> s2 = Struct(a=40) >>> s = s1 - s2 >>> s {'b': 30} """ sout = self.copy() sout -= other return sout def __isub__(self,other): """Inplace remove keys from self that are in other. Examples -------- >>> s1 = Struct(a=10,b=30) >>> s2 = Struct(a=40) >>> s1 -= s2 >>> s1 {'b': 30} """ for k in other.keys(): if k in self: del self[k] return self def __dict_invert(self, data): """Helper function for merge. Takes a dictionary whose values are lists and returns a dict with the elements of each list as keys and the original keys as values. """ outdict = {} for k,lst in data.items(): if isinstance(lst, str): lst = lst.split() for entry in lst: outdict[entry] = k return outdict def dict(self): return self def copy(self): """Return a copy as a Struct. Examples -------- >>> s = Struct(a=10,b=30) >>> s2 = s.copy() >>> type(s2) is Struct True """ return Struct(dict.copy(self)) def hasattr(self, key): """hasattr function available as a method. Implemented like has_key. Examples -------- >>> s = Struct(a=10) >>> s.hasattr('a') True >>> s.hasattr('b') False >>> s.hasattr('get') False """ return key in self def allow_new_attr(self, allow = True): """Set whether new attributes can be created in this Struct. This can be used to catch typos by verifying that the attribute user tries to change already exists in this Struct. """ object.__setattr__(self, '_allownew', allow) def merge(self, __loc_data__=None, __conflict_solve=None, **kw): """Merge two Structs with customizable conflict resolution. This is similar to :meth:`update`, but much more flexible. First, a dict is made from data+key=value pairs. When merging this dict with the Struct S, the optional dictionary 'conflict' is used to decide what to do. If conflict is not given, the default behavior is to preserve any keys with their current value (the opposite of the :meth:`update` method's behavior). Parameters ---------- __loc_data__ : dict, Struct The data to merge into self __conflict_solve : dict The conflict policy dict. The keys are binary functions used to resolve the conflict and the values are lists of strings naming the keys the conflict resolution function applies to. Instead of a list of strings a space separated string can be used, like 'a b c'. **kw : dict Additional key, value pairs to merge in Notes ----- The `__conflict_solve` dict is a dictionary of binary functions which will be used to solve key conflicts. Here is an example:: __conflict_solve = dict( func1=['a','b','c'], func2=['d','e'] ) In this case, the function :func:`func1` will be used to resolve keys 'a', 'b' and 'c' and the function :func:`func2` will be used for keys 'd' and 'e'. This could also be written as:: __conflict_solve = dict(func1='a b c',func2='d e') These functions will be called for each key they apply to with the form:: func1(self['a'], other['a']) The return value is used as the final merged value. As a convenience, merge() provides five (the most commonly needed) pre-defined policies: preserve, update, add, add_flip and add_s. The easiest explanation is their implementation:: preserve = lambda old,new: old update = lambda old,new: new add = lambda old,new: old + new add_flip = lambda old,new: new + old # note change of order! add_s = lambda old,new: old + ' ' + new # only for str! You can use those four words (as strings) as keys instead of defining them as functions, and the merge method will substitute the appropriate functions for you. For more complicated conflict resolution policies, you still need to construct your own functions. Examples -------- This show the default policy: >>> s = Struct(a=10,b=30) >>> s2 = Struct(a=20,c=40) >>> s.merge(s2) >>> sorted(s.items()) [('a', 10), ('b', 30), ('c', 40)] Now, show how to specify a conflict dict: >>> s = Struct(a=10,b=30) >>> s2 = Struct(a=20,b=40) >>> conflict = {'update':'a','add':'b'} >>> s.merge(s2,conflict) >>> sorted(s.items()) [('a', 20), ('b', 70)] """ data_dict = dict(__loc_data__,**kw) # policies for conflict resolution: two argument functions which return # the value that will go in the new struct preserve = lambda old,new: old update = lambda old,new: new add = lambda old,new: old + new add_flip = lambda old,new: new + old # note change of order! add_s = lambda old,new: old + ' ' + new # default policy is to keep current keys when there's a conflict conflict_solve = dict.fromkeys(self, preserve) # the conflict_solve dictionary is given by the user 'inverted': we # need a name-function mapping, it comes as a function -> names # dict. Make a local copy (b/c we'll make changes), replace user # strings for the three builtin policies and invert it. if __conflict_solve: inv_conflict_solve_user = __conflict_solve.copy() for name, func in [('preserve',preserve), ('update',update), ('add',add), ('add_flip',add_flip), ('add_s',add_s)]: if name in inv_conflict_solve_user.keys(): inv_conflict_solve_user[func] = inv_conflict_solve_user[name] del inv_conflict_solve_user[name] conflict_solve.update(self.__dict_invert(inv_conflict_solve_user)) for key in data_dict: if key not in self: self[key] = data_dict[key] else: self[key] = conflict_solve[key](self[key],data_dict[key])