1""" 2 :codeauthor: Pedro Algarvio (pedro@algarvio.me) 3 4 5 salt.utils.immutabletypes 6 ~~~~~~~~~~~~~~~~~~~~~~~~~ 7 8 Immutable types 9""" 10 11import copy 12from collections.abc import Mapping, Sequence, Set 13 14 15class ImmutableDict(Mapping): 16 """ 17 An immutable dictionary implementation 18 """ 19 20 def __init__(self, obj): 21 self.__obj = obj 22 23 def __len__(self): 24 return len(self.__obj) 25 26 def __iter__(self): 27 return iter(self.__obj) 28 29 def __getitem__(self, key): 30 return freeze(self.__obj[key]) 31 32 def __repr__(self): 33 return "<{} {}>".format(self.__class__.__name__, repr(self.__obj)) 34 35 def __deepcopy__(self, memo): 36 return copy.deepcopy(self.__obj) 37 38 def copy(self): 39 """ 40 Return an un-frozen copy of self 41 """ 42 return copy.deepcopy(self.__obj) 43 44 45class ImmutableList(Sequence): 46 """ 47 An immutable list implementation 48 """ 49 50 def __init__(self, obj): 51 self.__obj = obj 52 53 def __len__(self): 54 return len(self.__obj) 55 56 def __iter__(self): 57 return iter(self.__obj) 58 59 def __add__(self, other): 60 return self.__obj + other 61 62 def __radd__(self, other): 63 return other + self.__obj 64 65 def __getitem__(self, key): 66 return freeze(self.__obj[key]) 67 68 def __repr__(self): 69 return "<{} {}>".format(self.__class__.__name__, repr(self.__obj)) 70 71 def __deepcopy__(self, memo): 72 return copy.deepcopy(self.__obj) 73 74 def copy(self): 75 """ 76 Return an un-frozen copy of self 77 """ 78 return copy.deepcopy(self.__obj) 79 80 81class ImmutableSet(Set): 82 """ 83 An immutable set implementation 84 """ 85 86 def __init__(self, obj): 87 self.__obj = obj 88 89 def __len__(self): 90 return len(self.__obj) 91 92 def __iter__(self): 93 return iter(self.__obj) 94 95 def __contains__(self, key): 96 return key in self.__obj 97 98 def __repr__(self): 99 return "<{} {}>".format(self.__class__.__name__, repr(self.__obj)) 100 101 def __deepcopy__(self, memo): 102 return copy.deepcopy(self.__obj) 103 104 def copy(self): 105 """ 106 Return an un-frozen copy of self 107 """ 108 return copy.deepcopy(self.__obj) 109 110 111def freeze(obj): 112 """ 113 Freeze python types by turning them into immutable structures. 114 """ 115 if isinstance(obj, dict): 116 return ImmutableDict(obj) 117 if isinstance(obj, list): 118 return ImmutableList(obj) 119 if isinstance(obj, set): 120 return ImmutableSet(obj) 121 return obj 122