copy_reg.py (4271B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\copy_reg.py 2 from types import ClassType as _ClassType 3 __all__ = ['pickle', 4 'constructor', 5 'add_extension', 6 'remove_extension', 7 'clear_extension_cache'] 8 dispatch_table = {} 9 10 def pickle(ob_type, pickle_function, constructor_ob = None): 11 if type(ob_type) is _ClassType: 12 raise TypeError('copy_reg is not intended for use with classes') 13 if not hasattr(pickle_function, '__call__'): 14 raise TypeError('reduction functions must be callable') 15 dispatch_table[ob_type] = pickle_function 16 if constructor_ob is not None: 17 constructor(constructor_ob) 18 19 20 def constructor(object): 21 if not hasattr(object, '__call__'): 22 raise TypeError('constructors must be callable') 23 24 25 try: 26 complex 27 except NameError: 28 pass 29 else: 30 31 def pickle_complex(c): 32 return (complex, (c.real, c.imag)) 33 34 35 pickle(complex, pickle_complex, complex) 36 37 def _reconstructor(cls, base, state): 38 if base is object: 39 obj = object.__new__(cls) 40 else: 41 obj = base.__new__(cls, state) 42 if base.__init__ != object.__init__: 43 base.__init__(obj, state) 44 return obj 45 46 47 _HEAPTYPE = 512 48 49 def _reduce_ex(self, proto): 50 for base in self.__class__.__mro__: 51 if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE: 52 break 53 else: 54 base = object 55 56 if base is object: 57 state = None 58 else: 59 if base is self.__class__: 60 raise TypeError, "can't pickle %s objects" % base.__name__ 61 reducer = dispatch_table.get(base) 62 if reducer and reducer.__module__ == 'stackless._wrap': 63 base = reducer(self)[0] 64 state = base(self) 65 args = (self.__class__, base, state) 66 try: 67 getstate = self.__getstate__ 68 except AttributeError: 69 if getattr(self, '__slots__', None): 70 raise TypeError('a class that defines __slots__ without defining __getstate__ cannot be pickled') 71 try: 72 dict = self.__dict__ 73 except AttributeError: 74 dict = None 75 76 else: 77 dict = getstate() 78 79 if dict: 80 return (_reconstructor, args, dict) 81 else: 82 return (_reconstructor, args) 83 84 85 def __newobj__(cls, *args): 86 return cls.__new__(cls, *args) 87 88 89 def _slotnames(cls): 90 names = cls.__dict__.get('__slotnames__') 91 if names is not None: 92 return names 93 names = [] 94 if not hasattr(cls, '__slots__'): 95 pass 96 else: 97 for c in cls.__mro__: 98 if '__slots__' in c.__dict__: 99 slots = c.__dict__['__slots__'] 100 if isinstance(slots, basestring): 101 slots = (slots,) 102 for name in slots: 103 if name in ('__dict__', '__weakref__'): 104 continue 105 elif name.startswith('__') and not name.endswith('__'): 106 names.append('_%s%s' % (c.__name__, name)) 107 else: 108 names.append(name) 109 110 try: 111 cls.__slotnames__ = names 112 except: 113 pass 114 115 return names 116 117 118 _extension_registry = {} 119 _inverted_registry = {} 120 _extension_cache = {} 121 122 def add_extension(module, name, code): 123 code = int(code) 124 if not 1 <= code <= 2147483647: 125 raise ValueError, 'code out of range' 126 key = (module, name) 127 if _extension_registry.get(key) == code and _inverted_registry.get(code) == key: 128 return 129 if key in _extension_registry: 130 raise ValueError('key %s is already registered with code %s' % (key, _extension_registry[key])) 131 if code in _inverted_registry: 132 raise ValueError('code %s is already in use for key %s' % (code, _inverted_registry[code])) 133 _extension_registry[key] = code 134 _inverted_registry[code] = key 135 136 137 def remove_extension(module, name, code): 138 key = (module, name) 139 if _extension_registry.get(key) != code or _inverted_registry.get(code) != key: 140 raise ValueError('key %s is not registered with code %s' % (key, code)) 141 del _extension_registry[key] 142 del _inverted_registry[code] 143 if code in _extension_cache: 144 del _extension_cache[code] 145 146 147 def clear_extension_cache(): 148 _extension_cache.clear()