]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Lib/copy_reg.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Lib / copy_reg.py
CommitLineData
3257aa99
DM
1"""Helper to provide extensibility for pickle/cPickle.\r
2\r
3This is only useful to add pickle support for extension types defined in\r
4C, not for instances of user-defined classes.\r
5"""\r
6\r
7from types import ClassType as _ClassType\r
8\r
9__all__ = ["pickle", "constructor",\r
10 "add_extension", "remove_extension", "clear_extension_cache"]\r
11\r
12dispatch_table = {}\r
13\r
14def pickle(ob_type, pickle_function, constructor_ob=None):\r
15 if type(ob_type) is _ClassType:\r
16 raise TypeError("copy_reg is not intended for use with classes")\r
17\r
18 if not hasattr(pickle_function, '__call__'):\r
19 raise TypeError("reduction functions must be callable")\r
20 dispatch_table[ob_type] = pickle_function\r
21\r
22 # The constructor_ob function is a vestige of safe for unpickling.\r
23 # There is no reason for the caller to pass it anymore.\r
24 if constructor_ob is not None:\r
25 constructor(constructor_ob)\r
26\r
27def constructor(object):\r
28 if not hasattr(object, '__call__'):\r
29 raise TypeError("constructors must be callable")\r
30\r
31# Example: provide pickling support for complex numbers.\r
32\r
33try:\r
34 complex\r
35except NameError:\r
36 pass\r
37else:\r
38\r
39 def pickle_complex(c):\r
40 return complex, (c.real, c.imag)\r
41\r
42 pickle(complex, pickle_complex, complex)\r
43\r
44# Support for pickling new-style objects\r
45\r
46def _reconstructor(cls, base, state):\r
47 if base is object:\r
48 obj = object.__new__(cls)\r
49 else:\r
50 obj = base.__new__(cls, state)\r
51 if base.__init__ != object.__init__:\r
52 base.__init__(obj, state)\r
53 return obj\r
54\r
55_HEAPTYPE = 1<<9\r
56\r
57# Python code for object.__reduce_ex__ for protocols 0 and 1\r
58\r
59def _reduce_ex(self, proto):\r
60 assert proto < 2\r
61 for base in self.__class__.__mro__:\r
62 if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:\r
63 break\r
64 else:\r
65 base = object # not really reachable\r
66 if base is object:\r
67 state = None\r
68 else:\r
69 if base is self.__class__:\r
70 raise TypeError, "can't pickle %s objects" % base.__name__\r
71 state = base(self)\r
72 args = (self.__class__, base, state)\r
73 try:\r
74 getstate = self.__getstate__\r
75 except AttributeError:\r
76 if getattr(self, "__slots__", None):\r
77 raise TypeError("a class that defines __slots__ without "\r
78 "defining __getstate__ cannot be pickled")\r
79 try:\r
80 dict = self.__dict__\r
81 except AttributeError:\r
82 dict = None\r
83 else:\r
84 dict = getstate()\r
85 if dict:\r
86 return _reconstructor, args, dict\r
87 else:\r
88 return _reconstructor, args\r
89\r
90# Helper for __reduce_ex__ protocol 2\r
91\r
92def __newobj__(cls, *args):\r
93 return cls.__new__(cls, *args)\r
94\r
95def _slotnames(cls):\r
96 """Return a list of slot names for a given class.\r
97\r
98 This needs to find slots defined by the class and its bases, so we\r
99 can't simply return the __slots__ attribute. We must walk down\r
100 the Method Resolution Order and concatenate the __slots__ of each\r
101 class found there. (This assumes classes don't modify their\r
102 __slots__ attribute to misrepresent their slots after the class is\r
103 defined.)\r
104 """\r
105\r
106 # Get the value from a cache in the class if possible\r
107 names = cls.__dict__.get("__slotnames__")\r
108 if names is not None:\r
109 return names\r
110\r
111 # Not cached -- calculate the value\r
112 names = []\r
113 if not hasattr(cls, "__slots__"):\r
114 # This class has no slots\r
115 pass\r
116 else:\r
117 # Slots found -- gather slot names from all base classes\r
118 for c in cls.__mro__:\r
119 if "__slots__" in c.__dict__:\r
120 slots = c.__dict__['__slots__']\r
121 # if class has a single slot, it can be given as a string\r
122 if isinstance(slots, basestring):\r
123 slots = (slots,)\r
124 for name in slots:\r
125 # special descriptors\r
126 if name in ("__dict__", "__weakref__"):\r
127 continue\r
128 # mangled names\r
129 elif name.startswith('__') and not name.endswith('__'):\r
130 names.append('_%s%s' % (c.__name__, name))\r
131 else:\r
132 names.append(name)\r
133\r
134 # Cache the outcome in the class if at all possible\r
135 try:\r
136 cls.__slotnames__ = names\r
137 except:\r
138 pass # But don't die if we can't\r
139\r
140 return names\r
141\r
142# A registry of extension codes. This is an ad-hoc compression\r
143# mechanism. Whenever a global reference to <module>, <name> is about\r
144# to be pickled, the (<module>, <name>) tuple is looked up here to see\r
145# if it is a registered extension code for it. Extension codes are\r
146# universal, so that the meaning of a pickle does not depend on\r
147# context. (There are also some codes reserved for local use that\r
148# don't have this restriction.) Codes are positive ints; 0 is\r
149# reserved.\r
150\r
151_extension_registry = {} # key -> code\r
152_inverted_registry = {} # code -> key\r
153_extension_cache = {} # code -> object\r
154# Don't ever rebind those names: cPickle grabs a reference to them when\r
155# it's initialized, and won't see a rebinding.\r
156\r
157def add_extension(module, name, code):\r
158 """Register an extension code."""\r
159 code = int(code)\r
160 if not 1 <= code <= 0x7fffffff:\r
161 raise ValueError, "code out of range"\r
162 key = (module, name)\r
163 if (_extension_registry.get(key) == code and\r
164 _inverted_registry.get(code) == key):\r
165 return # Redundant registrations are benign\r
166 if key in _extension_registry:\r
167 raise ValueError("key %s is already registered with code %s" %\r
168 (key, _extension_registry[key]))\r
169 if code in _inverted_registry:\r
170 raise ValueError("code %s is already in use for key %s" %\r
171 (code, _inverted_registry[code]))\r
172 _extension_registry[key] = code\r
173 _inverted_registry[code] = key\r
174\r
175def remove_extension(module, name, code):\r
176 """Unregister an extension code. For testing only."""\r
177 key = (module, name)\r
178 if (_extension_registry.get(key) != code or\r
179 _inverted_registry.get(code) != key):\r
180 raise ValueError("key %s is not registered with code %s" %\r
181 (key, code))\r
182 del _extension_registry[key]\r
183 del _inverted_registry[code]\r
184 if code in _extension_cache:\r
185 del _extension_cache[code]\r
186\r
187def clear_extension_cache():\r
188 _extension_cache.clear()\r
189\r
190# Standard extension code assignments\r
191\r
192# Reserved ranges\r
193\r
194# First Last Count Purpose\r
195# 1 127 127 Reserved for Python standard library\r
196# 128 191 64 Reserved for Zope\r
197# 192 239 48 Reserved for 3rd parties\r
198# 240 255 16 Reserved for private use (will never be assigned)\r
199# 256 Inf Inf Reserved for future assignment\r
200\r
201# Extension codes are assigned by the Python Software Foundation.\r