Changeset 267

Show
Ignore:
Timestamp:
07/20/05 20:07:04 (3 years ago)
Author:
athomas
Message:
  • Added setup.py
  • Added component architecture from Trac
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pycrash/trunk/DynamicLoader.py

    r266 r267  
    22 
    33def load_module(modulePath): 
    4        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 
     4    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 
    1313 
    1414def load_function(fullFuncName): 
    15        """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 
     15    """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 
    3434 
    3535def 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 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 
     36    """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  
    11class Network: 
    2        """ Represents a network and netmask. Automatically detects input format 
    3                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. """ 
    44 
    5        class Error(Exception): pass 
    6        class ValueError(Error): pass 
     5    class Error(Exception): pass 
     6    class ValueError(Error): pass 
    77 
    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})''' 
    1010 
    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()]) 
    2323 
    24        def __init__(self, network, mask = None): 
    25                try: 
    26                        network = long(network) 
    27                except: 
    28                        pass 
     24    def __init__(self, network, mask = None): 
     25        try: 
     26            network = long(network) 
     27        except: 
     28            pass 
    2929 
    30                if not mask: mask = 32L 
     30        if not mask: mask = 32L 
    3131 
    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))) 
    4747 
    48                try: 
    49                        mask = long(mask) 
    50                except: 
    51                        pass 
     48        try: 
     49            mask = long(mask) 
     50        except: 
     51            pass 
    5252 
    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) 
    6262 
    63                self.__network, self.__mask = network, mask 
     63        self.__network, self.__mask = network, mask 
    6464 
    65        @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 
     65    @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 
    7272 
    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) 
     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) 
    7979 
    80        @staticmethod 
    81        def cidr2dq(cidr): 
    82                return Network.int2dq(Network.cidr2int(cidr)) 
     80    @staticmethod 
     81    def cidr2dq(cidr): 
     82        return Network.int2dq(Network.cidr2int(cidr)) 
    8383 
    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) 
     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) 
    9090 
    91        @staticmethod 
    92        def int2cidr(value): 
    93                return Network.dq2cidr(Network.int2dq(value)) 
     91    @staticmethod 
     92    def int2cidr(value): 
     93        return Network.dq2cidr(Network.int2dq(value)) 
    9494 
    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) 
     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) 
    101101 
    102        def network(self): 
    103                return self.__network 
     102    def network(self): 
     103        return self.__network 
    104104 
    105        def mask(self): 
    106                return self.__mask 
     105    def mask(self): 
     106        return self.__mask 
    107107 
    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) 
    111111 
    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)) 
    115115 
    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)) 
    120120 
    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)) 
    123123 
    124124class 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  
    6161         
    6262    def __call__(cls, *lstArgs, **dictArgs): 
    63                return cls.getInstance(*lstArgs, **dictArgs) 
     63        return cls.getInstance(*lstArgs, **dictArgs) 
    6464         
    6565class Singleton(object): 
     
    114114 
    115115if __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()" 
    120120 
    121        a = A() 
    122        b = A() 
    123        print a, b 
     121    a = A() 
     122    b = A() 
     123    print a, b 
  • pycrash/trunk/util.py

    r266 r267  
    77 
    88class ostream: 
    9        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 
     9    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 
    1717 
    1818cout = ostream(sys.stdout) 
     
    2121 
    2222class 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 = exception 
    30  
    31        def __call__(self, *argl, **argd): 
    32                raise self.__exception 
     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 = exception 
     30 
     31    def __call__(self, *argl, **argd): 
     32        raise self.__exception 
    3333 
    3434def abstract(func): 
    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__) 
     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__) 
    3939 
    4040def crc16(s): 
    41        """ 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 
     41    """ 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 
    5252 
    5353def bit(bit): 
    54        """ Return integer with bit set. """ 
    55        return 1L << bit 
     54    """ Return integer with bit set. """ 
     55    return 1L << bit 
    5656 
    5757def bits(*args): 
    58        bits = 0 
    59        for b in args: 
    60                bits |= 1L << b 
    61        return bits 
     58    bits = 0 
     59    for b in args: 
     60        bits |= 1L << b 
     61    return bits 
    6262 
    6363# Compatibility with Python 2.2 and 2.3 
     
    7070try: bool ## Introduced in 2.3 
    7171except NameError: 
    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) 
     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) 
    7979 
    8080try: sum ## Introduced in 2.3 
    8181except NameError: 
    82        def sum(seq, start=0): 
    83                """Sum the elements of seq. 
    84                >>> sum([1, 2, 3]) 
    85                
    86                """ 
    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       
     86        """ 
     87        return reduce(operator.add, seq, start) 
    8888 
    8989try: enumerate  ## Introduced in 2.3 
    9090except 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 = 0 
    97                it = iter(collection) 
    98                while 1: 
    99                        yield (i, it.next()) 
    100                        i += 1 
     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 = 0 
     97        it = iter(collection) 
     98        while 1: 
     99            yield (i, it.next()) 
     100            i += 1 
    101101 
    102102 
    103103try: reversed ## Introduced in 2.4 
    104104except 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 -= 1 
    115                        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] 
    116116 
    117117 
    118118try: sorted ## Introduced in 2.4 
    119119except 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 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)) 
     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)) 
    136136 
    137137try: 
    138        set, frozenset ## set builtin introduced in 2.4 
     138    set, frozenset ## set builtin introduced in 2.4 
    139139except NameError: 
    140        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 
     140    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 
    263263 
    264264 
     
    270270 
    271271def 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 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 entries 
    277277 
    278278class DefaultDict(dict): 
    279        """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 
     279    """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 
    291291 
    292292class struct: 
    293        """Create an instance with argument=value slots. 
    294        This is for making a lightweight object whose class doesn't matter.""" 
    295