Changeset 267
- Timestamp:
- 07/20/05 20:07:04 (3 years ago)
- Files:
-
- pycrash/trunk/component.py (added)
- pycrash/trunk/crash (added)
- pycrash/trunk/DynamicLoader.py (modified) (1 diff)
- pycrash/trunk/Network.py (modified) (1 diff)
- pycrash/trunk/setup.py (added)
- pycrash/trunk/Singleton.py (modified) (2 diffs)
- pycrash/trunk/util.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pycrash/trunk/DynamicLoader.py
r266 r267 2 2 3 3 def load_module(modulePath): 4 try:5 aMod = sys.modules[modulePath]6 if not isinstance(aMod, types.ModuleType):7 raise KeyError8 except KeyError:9 # The last [''] is very important!10 aMod = __import__(modulePath, globals(), locals(), [''])11 sys.modules[modulePath] = aMod12 return aMod4 try: 5 aMod = sys.modules[modulePath] 6 if not isinstance(aMod, types.ModuleType): 7 raise KeyError 8 except KeyError: 9 # The last [''] is very important! 10 aMod = __import__(modulePath, globals(), locals(), ['']) 11 sys.modules[modulePath] = aMod 12 return aMod 13 13 14 14 def load_function(fullFuncName): 15 """Retrieve a function object from a full dotted-package name."""16 17 # Parse out the path, module, and function18 lastDot = fullFuncName.rfind(u".")19 funcName = fullFuncName[lastDot + 1:]20 modPath = fullFuncName[:lastDot]21 22 aMod = load_module(modPath)23 try:24 aFunc = getattr(aMod, funcName)25 except AttributeError:26 raise ImportError("no such function '" + funcName + "'")27 28 # Assert that the function is a *callable* attribute.29 assert callable(aFunc), u"%s is not callable." % fullFuncName30 31 # Return a reference to the function itself,32 # not the results of the function.33 return aFunc15 """Retrieve a function object from a full dotted-package name.""" 16 17 # Parse out the path, module, and function 18 lastDot = fullFuncName.rfind(u".") 19 funcName = fullFuncName[lastDot + 1:] 20 modPath = fullFuncName[:lastDot] 21 22 aMod = load_module(modPath) 23 try: 24 aFunc = getattr(aMod, funcName) 25 except AttributeError: 26 raise ImportError("no such function '" + funcName + "'") 27 28 # Assert that the function is a *callable* attribute. 29 assert callable(aFunc), u"%s is not callable." % fullFuncName 30 31 # Return a reference to the function itself, 32 # not the results of the function. 33 return aFunc 34 34 35 35 def load_class(fullClassName, parentClass=None): 36 """Load a module and retrieve a class (NOT an instance).37 38 If the parentClass is supplied, className must be of parentClass39 or a subclass of parentClass (or None is returned).40 """41 aClass = load_function(fullClassName)42 43 # Assert that the class is a subclass of parentClass.44 if parentClass is not None:45 if not issubclass(aClass, parentClass):46 raise TypeError(u"%s is not a subclass of %s" %47 (fullClassName, parentClass))48 49 # Return a reference to the class itself, not an instantiated object.50 return aClass36 """Load a module and retrieve a class (NOT an instance). 37 38 If the parentClass is supplied, className must be of parentClass 39 or a subclass of parentClass (or None is returned). 40 """ 41 aClass = load_function(fullClassName) 42 43 # Assert that the class is a subclass of parentClass. 44 if parentClass is not None: 45 if not issubclass(aClass, parentClass): 46 raise TypeError(u"%s is not a subclass of %s" % 47 (fullClassName, parentClass)) 48 49 # Return a reference to the class itself, not an instantiated object. 50 return aClass pycrash/trunk/Network.py
r266 r267 1 1 class Network: 2 """ Represents a network and netmask. Automatically detects input format3 and converts to a consistent internal representation. """2 """ Represents a network and netmask. Automatically detects input format 3 and converts to a consistent internal representation. """ 4 4 5 class Error(Exception): pass6 class ValueError(Error): pass5 class Error(Exception): pass 6 class ValueError(Error): pass 7 7 8 IP_PATTERN = r'''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'''9 PATTERN = r'''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(?:\d{1,2}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'''8 IP_PATTERN = r'''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}''' 9 PATTERN = r'''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(?:\d{1,2}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})''' 10 10 11 __cidr2int_map = {12 0 : 0L, 1 : 2147483648L, 2 : 3221225472L, 3 : 3758096384L,13 4 : 4026531840L, 5 : 4160749568L, 6 : 4227858432L, 7 : 4261412864L,14 8 : 4278190080L, 9 : 4286578688L, 10 : 4290772992L, 11 : 4292870144L,15 12 : 4293918720L, 13 : 4294443008L, 14 : 4294705152L, 15 : 4294836224L,16 16 : 4294901760L, 17 : 4294934528L, 18 : 4294950912L, 19 : 4294959104L,17 20 : 4294963200L, 21 : 4294965248L, 22 : 4294966272L, 23 : 4294966784L,18 24 : 4294967040L, 25 : 4294967168L, 26 : 4294967232L, 27 : 4294967264L,19 28 : 4294967280L, 29 : 4294967288L, 30 : 4294967292L, 31 : 4294967294L,20 32 : 4294967295L,21 }22 __int2cidr_map = dict([(y, x) for x, y in __cidr2int_map.iteritems()])11 __cidr2int_map = { 12 0 : 0L, 1 : 2147483648L, 2 : 3221225472L, 3 : 3758096384L, 13 4 : 4026531840L, 5 : 4160749568L, 6 : 4227858432L, 7 : 4261412864L, 14 8 : 4278190080L, 9 : 4286578688L, 10 : 4290772992L, 11 : 4292870144L, 15 12 : 4293918720L, 13 : 4294443008L, 14 : 4294705152L, 15 : 4294836224L, 16 16 : 4294901760L, 17 : 4294934528L, 18 : 4294950912L, 19 : 4294959104L, 17 20 : 4294963200L, 21 : 4294965248L, 22 : 4294966272L, 23 : 4294966784L, 18 24 : 4294967040L, 25 : 4294967168L, 26 : 4294967232L, 27 : 4294967264L, 19 28 : 4294967280L, 29 : 4294967288L, 30 : 4294967292L, 31 : 4294967294L, 20 32 : 4294967295L, 21 } 22 __int2cidr_map = dict([(y, x) for x, y in __cidr2int_map.iteritems()]) 23 23 24 def __init__(self, network, mask = None):25 try:26 network = long(network)27 except:28 pass24 def __init__(self, network, mask = None): 25 try: 26 network = long(network) 27 except: 28 pass 29 29 30 if not mask: mask = 32L30 if not mask: mask = 32L 31 31 32 if type(network) is not long:33 if type(network) is str:34 if '/' in network:35 network, mask = network.split('/')36 if '.' in network:37 network = Network.dq2int(network)38 else:39 try:40 network = long(network)41 except:42 raise Network.ValueError("couldn't determine format of network")43 elif type(network) is list or type(network) is tuple:44 network = Network.dq2int('.'.join(network))45 else:46 raise Network.ValueError('network "%s" must be a string, long or tuple, not "%s"' % (str(network), type(network)))32 if type(network) is not long: 33 if type(network) is str: 34 if '/' in network: 35 network, mask = network.split('/') 36 if '.' in network: 37 network = Network.dq2int(network) 38 else: 39 try: 40 network = long(network) 41 except: 42 raise Network.ValueError("couldn't determine format of network") 43 elif type(network) is list or type(network) is tuple: 44 network = Network.dq2int('.'.join(network)) 45 else: 46 raise Network.ValueError('network "%s" must be a string, long or tuple, not "%s"' % (str(network), type(network))) 47 47 48 try:49 mask = long(mask)50 except:51 pass48 try: 49 mask = long(mask) 50 except: 51 pass 52 52 53 if type(mask) is not long and type(mask) is not int:54 if type(mask) is str:55 mask = Network.dq2int(mask)56 elif type(mask) is list or type(mask) is tuple:57 mask = Network.cidr2int(Network.dq2cidr('.'.join(mask)))58 else:59 raise Network.ValueError('mask "%s" must be a string, int, long or tuple, not "%s"' % (str(mask), type(mask)))60 else:61 mask = Network.cidr2int(mask)53 if type(mask) is not long and type(mask) is not int: 54 if type(mask) is str: 55 mask = Network.dq2int(mask) 56 elif type(mask) is list or type(mask) is tuple: 57 mask = Network.cidr2int(Network.dq2cidr('.'.join(mask))) 58 else: 59 raise Network.ValueError('mask "%s" must be a string, int, long or tuple, not "%s"' % (str(mask), type(mask))) 60 else: 61 mask = Network.cidr2int(mask) 62 62 63 self.__network, self.__mask = network, mask63 self.__network, self.__mask = network, mask 64 64 65 @staticmethod66 def dq2int(dq):67 ip = long(0)68 octets = dq.split('.')69 for i, o in enumerate(reversed(octets)):70 ip += long(o) << (i * 8)71 return ip65 @staticmethod 66 def dq2int(dq): 67 ip = long(0) 68 octets = dq.split('.') 69 for i, o in enumerate(reversed(octets)): 70 ip += long(o) << (i * 8) 71 return ip 72 72 73 @staticmethod74 def dq2cidr(dq):75 try:76 return Network.__int2cidr_map[Network.dq2int(dq)]77 except:78 raise Network.ValueError("dotted quad %s is not a valid CIDR mask" % dq)73 @staticmethod 74 def dq2cidr(dq): 75 try: 76 return Network.__int2cidr_map[Network.dq2int(dq)] 77 except: 78 raise Network.ValueError("dotted quad %s is not a valid CIDR mask" % dq) 79 79 80 @staticmethod81 def cidr2dq(cidr):82 return Network.int2dq(Network.cidr2int(cidr))80 @staticmethod 81 def cidr2dq(cidr): 82 return Network.int2dq(Network.cidr2int(cidr)) 83 83 84 @staticmethod85 def cidr2int(cidr):86 try:87 return Network.__cidr2int_map[cidr]88 except:89 raise Network.ValueError("%i is not a valid CIDR mask" % cidr)84 @staticmethod 85 def cidr2int(cidr): 86 try: 87 return Network.__cidr2int_map[cidr] 88 except: 89 raise Network.ValueError("%i is not a valid CIDR mask" % cidr) 90 90 91 @staticmethod92 def int2cidr(value):93 return Network.dq2cidr(Network.int2dq(value))91 @staticmethod 92 def int2cidr(value): 93 return Network.dq2cidr(Network.int2dq(value)) 94 94 95 @staticmethod96 def int2dq(value):97 dq = []98 for i in range(0, 4):99 dq.append(str((value >> ((3 - i) * 8)) & 0xff))100 return '.'.join(dq)95 @staticmethod 96 def int2dq(value): 97 dq = [] 98 for i in range(0, 4): 99 dq.append(str((value >> ((3 - i) * 8)) & 0xff)) 100 return '.'.join(dq) 101 101 102 def network(self):103 return self.__network102 def network(self): 103 return self.__network 104 104 105 def mask(self):106 return self.__mask105 def mask(self): 106 return self.__mask 107 107 108 def cidr_mask(self):109 """ Return mask in CIDR format """110 return Network.int2cidr(self.__mask)108 def cidr_mask(self): 109 """ Return mask in CIDR format """ 110 return Network.int2cidr(self.__mask) 111 111 112 def mask_network(self):113 """ Return the current ip/mask with the IP converted to the network """114 return Network(self.__network & self.__mask, Network.int2cidr(self.__mask))112 def mask_network(self): 113 """ Return the current ip/mask with the IP converted to the network """ 114 return Network(self.__network & self.__mask, Network.int2cidr(self.__mask)) 115 115 116 def __str__(self):117 if self.__mask == 4294967295L:118 return Network.int2dq(self.__network)119 return Network.int2dq(self.__network) + '/' + str(Network.int2cidr(self.__mask))116 def __str__(self): 117 if self.__mask == 4294967295L: 118 return Network.int2dq(self.__network) 119 return Network.int2dq(self.__network) + '/' + str(Network.int2cidr(self.__mask)) 120 120 121 def __hash__(self):122 return hash('%li/%li' % (self.__network, self.__mask))121 def __hash__(self): 122 return hash('%li/%li' % (self.__network, self.__mask)) 123 123 124 124 class IP(Network): 125 def __init__(self, network):126 Network.__init__(network, 32)125 def __init__(self, network): 126 Network.__init__(network, 32) pycrash/trunk/Singleton.py
r266 r267 61 61 62 62 def __call__(cls, *lstArgs, **dictArgs): 63 return cls.getInstance(*lstArgs, **dictArgs)63 return cls.getInstance(*lstArgs, **dictArgs) 64 64 65 65 class Singleton(object): … … 114 114 115 115 if __name__ == '__main__': 116 class A(Singleton):117 def __init__(self):118 Singleton.__init__(self)119 print "A()"116 class A(Singleton): 117 def __init__(self): 118 Singleton.__init__(self) 119 print "A()" 120 120 121 a = A()122 b = A()123 print a, b121 a = A() 122 b = A() 123 print a, b pycrash/trunk/util.py
r266 r267 7 7 8 8 class ostream: 9 def __init__(self, file):10 self.file = file11 12 def __lshift__(self, obj):13 obj = str(obj)14 self.file.write(obj);15 if obj == '\n': self.file.flush()16 return self9 def __init__(self, file): 10 self.file = file 11 12 def __lshift__(self, obj): 13 obj = str(obj) 14 self.file.write(obj); 15 if obj == '\n': self.file.flush() 16 return self 17 17 18 18 cout = ostream(sys.stdout) … … 21 21 22 22 class DelayedAbstractException: 23 """ Raise an exception when an abstract function is called. """24 def __init__(self, exception, doc = "Raise an exception when this object is called as a function with any number of arguments."):25 if doc:26 self.__doc__ = doc + " [abstract function]"27 else:28 self.__doc__ = "[abstract function]"29 self.__exception = exception30 31 def __call__(self, *argl, **argd):32 raise self.__exception23 """ Raise an exception when an abstract function is called. """ 24 def __init__(self, exception, doc = "Raise an exception when this object is called as a function with any number of arguments."): 25 if doc: 26 self.__doc__ = doc + " [abstract function]" 27 else: 28 self.__doc__ = "[abstract function]" 29 self.__exception = exception 30 31 def __call__(self, *argl, **argd): 32 raise self.__exception 33 33 34 34 def abstract(func): 35 """ Decorator function for implementing Java style abstract methods. eg.\n\n@abstract\ndef foo(self): pass """36 #import inspect37 #caller = inspect.getouterframes(inspect.currentframe())[1][3]38 return DelayedAbstractException(NotImplementedError(func.__name__ + ' must be implemented in subclass'), func.__doc__)35 """ Decorator function for implementing Java style abstract methods. eg.\n\n@abstract\ndef foo(self): pass """ 36 #import inspect 37 #caller = inspect.getouterframes(inspect.currentframe())[1][3] 38 return DelayedAbstractException(NotImplementedError(func.__name__ + ' must be implemented in subclass'), func.__doc__) 39 39 40 40 def crc16(s): 41 """ Return 16 bit CRC of a string. """42 assert type(s) is str, "crc16() expects a string"43 crc = 044 for index1 in range(len(s)):45 crc = crc ^ (ord(s[index1]) << 8)46 for index2 in range(1, 9):47 if crc & 0x8000 != 0:48 crc = ((crc << 1) ^ 0x1021)49 else:50 crc = crc << 151 return crc & 0xFFFF41 """ Return 16 bit CRC of a string. """ 42 assert type(s) is str, "crc16() expects a string" 43 crc = 0 44 for index1 in range(len(s)): 45 crc = crc ^ (ord(s[index1]) << 8) 46 for index2 in range(1, 9): 47 if crc & 0x8000 != 0: 48 crc = ((crc << 1) ^ 0x1021) 49 else: 50 crc = crc << 1 51 return crc & 0xFFFF 52 52 53 53 def bit(bit): 54 """ Return integer with bit set. """55 return 1L << bit54 """ Return integer with bit set. """ 55 return 1L << bit 56 56 57 57 def bits(*args): 58 bits = 059 for b in args:60 bits |= 1L << b61 return bits58 bits = 0 59 for b in args: 60 bits |= 1L << b 61 return bits 62 62 63 63 # Compatibility with Python 2.2 and 2.3 … … 70 70 try: bool ## Introduced in 2.3 71 71 except NameError: 72 class bool(int):73 "Simple implementation of Booleans, as in PEP 285"74 def __init__(self, val): self.val = val75 def __int__(self): return self.val76 def __repr__(self): return ('False', 'True')[self.val]77 78 True, False = bool(1), bool(0)72 class bool(int): 73 "Simple implementation of Booleans, as in PEP 285" 74 def __init__(self, val): self.val = val 75 def __int__(self): return self.val 76 def __repr__(self): return ('False', 'True')[self.val] 77 78 True, False = bool(1), bool(0) 79 79 80 80 try: sum ## Introduced in 2.3 81 81 except NameError: 82 def sum(seq, start=0):83 """Sum the elements of seq.84 >>> sum([1, 2, 3])85 686 """87 return reduce(operator.add, seq, start)82 def sum(seq, start=0): 83 """Sum the elements of seq. 84 >>> sum([1, 2, 3]) 85 6 86 """ 87 return reduce(operator.add, seq, start) 88 88 89 89 try: enumerate ## Introduced in 2.3 90 90 except NameError: 91 def enumerate(collection):92 """Return an iterator that enumerates pairs of (i, c[i]). PEP 279.93 >>> list(enumerate('abc'))94 [(0, 'a'), (1, 'b'), (2, 'c')]95 """96 i = 097 it = iter(collection)98 while 1:99 yield (i, it.next())100 i += 191 def enumerate(collection): 92 """Return an iterator that enumerates pairs of (i, c[i]). PEP 279. 93 >>> list(enumerate('abc')) 94 [(0, 'a'), (1, 'b'), (2, 'c')] 95 """ 96 i = 0 97 it = iter(collection) 98 while 1: 99 yield (i, it.next()) 100 i += 1 101 101 102 102 103 103 try: reversed ## Introduced in 2.4 104 104 except NameError: 105 def reversed(seq):106 """Iterate over x in reverse order.107 >>> list(reversed([1,2,3]))108 [3, 2, 1]109 """110 if hasattr(seq, 'keys'):111 raise ValueError("mappings do not support reverse iteration")112 i = len(seq)113 while i > 0:114 i -= 1115 yield seq[i]105 def reversed(seq): 106 """Iterate over x in reverse order. 107 >>> list(reversed([1,2,3])) 108 [3, 2, 1] 109 """ 110 if hasattr(seq, 'keys'): 111 raise ValueError("mappings do not support reverse iteration") 112 i = len(seq) 113 while i > 0: 114 i -= 1 115 yield seq[i] 116 116 117 117 118 118 try: sorted ## Introduced in 2.4 119 119 except NameError: 120 def sorted(seq, cmp=None, key=None, reverse=False):121 """Copy seq and sort and return it.122 >>> sorted([3, 1, 2])123 [1, 2, 3]124 """125 seq2 = copy.copy(seq)126 seq2.sort(_make_cmp(cmp, key))127 if reverse:128 seq2.reverse()129 return seq2130 131 def _make_cmp(cmpfn=None, key=None):132 if not cmpfn and not key: return None133 elif cmpfn and not key: return cmpfn134 elif not cmpfn and key: return lambda x,y: cmp(key(x), key(y))135 else: return lambda x,y: cmpfn(key(x), key(y))120 def sorted(seq, cmp=None, key=None, reverse=False): 121 """Copy seq and sort and return it. 122 >>> sorted([3, 1, 2]) 123 [1, 2, 3] 124 """ 125 seq2 = copy.copy(seq) 126 seq2.sort(_make_cmp(cmp, key)) 127 if reverse: 128 seq2.reverse() 129 return seq2 130 131 def _make_cmp(cmpfn=None, key=None): 132 if not cmpfn and not key: return None 133 elif cmpfn and not key: return cmpfn 134 elif not cmpfn and key: return lambda x,y: cmp(key(x), key(y)) 135 else: return lambda x,y: cmpfn(key(x), key(y)) 136 136 137 137 try: 138 set, frozenset ## set builtin introduced in 2.4138 set, frozenset ## set builtin introduced in 2.4 139 139 except NameError: 140 try:141 import sets ## sets module introduced in 2.3142 set, frozenset = sets.Set, sets.ImmutableSet143 except (NameError, ImportError):144 class BaseSet:145 "set type (see http://docs.python.org/lib/types-set.html)"146 147 148 def __init__(self, elements=[]):149 self.dict = {}150 for e in elements:151 self.dict[e] = 1152 153 def __len__(self):154 return len(self.dict)155 156 def __iter__(self):157 for e in self.dict:158 yield e159 160 def __contains__(self, element):161 return element in self.dict162 163 def issubset(self, other):164 for e in self.dict.keys():165 if e not in other:166 return False167 return True168 169 def issuperset(self, other):170 for e in other:171 if e not in self:172 return False173 return True174 175 176 def union(self, other):177 return type(self)(list(self) + list(other))178 179 def intersection(self, other):180 return type(self)([e for e in self.dict if e in other])181 182 def difference(self, other):183 return type(self)([e for e in self.dict if e not in other])184 185 def symmetric_difference(self, other):186 return type(self)([e for e in self.dict if e not in other] +187 [e for e in other if e not in self.dict])188 189 def copy(self):190 return type(self)(self.dict)191 192 def __repr__(self):193 elements = ", ".join(map(str, self.dict))194 return "%s([%s])" % (type(self).__name__, elements)195 196 __le__ = issubset197 __ge__ = issuperset198 __or__ = union199 __and__ = intersection200 __sub__ = difference201 __xor__ = symmetric_difference202 203 class frozenset(BaseSet):204 "A frozenset is a BaseSet that has a hash value and is immutable."205 206 def __init__(self, elements=[]):207 BaseSet.__init__(elements)208 self.hash = 0209 for e in self:210 self.hash |= hash(e)211 212 def __hash__(self):213 return self.hash214 215 class set(BaseSet):216 "A set is a BaseSet that does not have a hash, but is mutable."217 218 def update(self, other):219 for e in other:220 self.add(e)221 return self222 223 def intersection_update(self, other):224 for e in self.dict.keys():225 if e not in other:226 self.remove(e)227 return self228 229 def difference_update(self, other):230 for e in self.dict.keys():231 if e in other:232 self.remove(e)233 return self234 235 def symmetric_difference_update(self, other):236 to_remove1 = [e for e in self.dict if e in other]237 to_remove2 = [e for e in other if e in self.dict]238 self.difference_update(to_remove1)239 self.difference_update(to_remove2)240 return self241 242 def add(self, element):243 self.dict[element] = 1244 245 def remove(self, element):246 del self.dict[element]247 248 def discard(self, element):249 if element in self.dict:250 del self.dict[element]251 252 def pop(self):253 key, val = self.dict.popitem()254 return key255 256 def clear(self):257 self.dict.clear()258 259 __ior__ = update260 __iand__ = intersection_update261 __isub__ = difference_update262 __ixor__ = symmetric_difference_update140 try: 141 import sets ## sets module introduced in 2.3 142 set, frozenset = sets.Set, sets.ImmutableSet 143 except (NameError, ImportError): 144 class BaseSet: 145 "set type (see http://docs.python.org/lib/types-set.html)" 146 147 148 def __init__(self, elements=[]): 149 self.dict = {} 150 for e in elements: 151 self.dict[e] = 1 152 153 def __len__(self): 154 return len(self.dict) 155 156 def __iter__(self): 157 for e in self.dict: 158 yield e 159 160 def __contains__(self, element): 161 return element in self.dict 162 163 def issubset(self, other): 164 for e in self.dict.keys(): 165 if e not in other: 166 return False 167 return True 168 169 def issuperset(self, other): 170 for e in other: 171 if e not in self: 172 return False 173 return True 174 175 176 def union(self, other): 177 return type(self)(list(self) + list(other)) 178 179 def intersection(self, other): 180 return type(self)([e for e in self.dict if e in other]) 181 182 def difference(self, other): 183 return type(self)([e for e in self.dict if e not in other]) 184 185 def symmetric_difference(self, other): 186 return type(self)([e for e in self.dict if e not in other] + 187 [e for e in other if e not in self.dict]) 188 189 def copy(self): 190 return type(self)(self.dict) 191 192 def __repr__(self): 193 elements = ", ".join(map(str, self.dict)) 194 return "%s([%s])" % (type(self).__name__, elements) 195 196 __le__ = issubset 197 __ge__ = issuperset 198 __or__ = union 199 __and__ = intersection 200 __sub__ = difference 201 __xor__ = symmetric_difference 202 203 class frozenset(BaseSet): 204 "A frozenset is a BaseSet that has a hash value and is immutable." 205 206 def __init__(self, elements=[]): 207 BaseSet.__init__(elements) 208 self.hash = 0 209 for e in self: 210 self.hash |= hash(e) 211 212 def __hash__(self): 213 return self.hash 214 215 class set(BaseSet): 216 "A set is a BaseSet that does not have a hash, but is mutable." 217 218 def update(self, other): 219 for e in other: 220 self.add(e) 221 return self 222 223 def intersection_update(self, other): 224 for e in self.dict.keys(): 225 if e not in other: 226 self.remove(e) 227 return self 228 229 def difference_update(self, other): 230 for e in self.dict.keys(): 231 if e in other: 232 self.remove(e) 233 return self 234 235 def symmetric_difference_update(self, other): 236 to_remove1 = [e for e in self.dict if e in other] 237 to_remove2 = [e for e in other if e in self.dict] 238 self.difference_update(to_remove1) 239 self.difference_update(to_remove2) 240 return self 241 242 def add(self, element): 243 self.dict[element] = 1 244 245 def remove(self, element): 246 del self.dict[element] 247 248 def discard(self, element): 249 if element in self.dict: 250 del self.dict[element] 251 252 def pop(self): 253 key, val = self.dict.popitem() 254 return key 255 256 def clear(self): 257 self.dict.clear() 258 259 __ior__ = update 260 __iand__ = intersection_update 261 __isub__ = difference_update 262 __ixor__ = symmetric_difference_update 263 263 264 264 … … 270 270 271 271 def Dict(**entries): 272 """Create a dict out of the argument=value arguments.273 >>> Dict(a=1, b=2, c=3)274 {'a': 1, 'c': 3, 'b': 2}275 """276 return entries272 """Create a dict out of the argument=value arguments. 273 >>> Dict(a=1, b=2, c=3) 274 {'a': 1, 'c': 3, 'b': 2} 275 """ 276 return entries 277 277 278 278 class DefaultDict(dict): 279 """Dictionary with a default value for unknown keys."""280 def __init__(self, default):281 self.default = default282 283 def __getitem__(self, key):284 if key in self: return self.get(key)285 return self.setdefault(key, copy.deepcopy(self.default))286 287 def __copy__(self):288 copy = DefaultDict(self.default)289 copy.update(self)290 return copy279 """Dictionary with a default value for unknown keys.""" 280 def __init__(self, default): 281 self.default = default 282 283 def __getitem__(self, key): 284 if key in self: return self.get(key) 285 return self.setdefault(key, copy.deepcopy(self.default)) 286 287 def __copy__(self): 288 copy = DefaultDict(self.default) 289 copy.update(self) 290 return copy 291 291 292 292 class struct: 293 """Create an instance with argument=value slots.294 This is for making a lightweight object whose class doesn't matter."""295
