blob: 0477bcb541bd99109c20b8f2a6da9b770b75ad86 [file] [log] [blame]
Fred Drake78a6a362000-10-11 22:16:45 +00001"""Helper to provide extensibility for pickle/cPickle.
2
3This is only useful to add pickle support for extension types defined in
4C, not for instances of user-defined classes.
5"""
6
7from types import ClassType as _ClassType
Guido van Rossum72be3061997-05-20 18:03:22 +00008
Guido van Rossumcf356fd2003-01-31 20:34:07 +00009__all__ = ["pickle", "constructor",
10 "add_extension", "remove_extension", "clear_extension_cache"]
Skip Montanaroe99d5ea2001-01-20 19:54:20 +000011
Guido van Rossum47065621997-04-09 17:44:11 +000012dispatch_table = {}
Guido van Rossum47065621997-04-09 17:44:11 +000013
Fred Drake78a6a362000-10-11 22:16:45 +000014def pickle(ob_type, pickle_function, constructor_ob=None):
15 if type(ob_type) is _ClassType:
16 raise TypeError("copy_reg is not intended for use with classes")
17
18 if not callable(pickle_function):
19 raise TypeError("reduction functions must be callable")
Guido van Rossum47065621997-04-09 17:44:11 +000020 dispatch_table[ob_type] = pickle_function
21
Guido van Rossum72be3061997-05-20 18:03:22 +000022 if constructor_ob is not None:
Guido van Rossum47065621997-04-09 17:44:11 +000023 constructor(constructor_ob)
24
25def constructor(object):
Fred Drake78a6a362000-10-11 22:16:45 +000026 if not callable(object):
27 raise TypeError("constructors must be callable")
Guido van Rossum47065621997-04-09 17:44:11 +000028
Guido van Rossum72be3061997-05-20 18:03:22 +000029# Example: provide pickling support for complex numbers.
Guido van Rossum47065621997-04-09 17:44:11 +000030
Martin v. Löwis502ba462003-06-07 20:10:54 +000031try:
32 complex
33except NameError:
34 pass
35else:
Guido van Rossum72be3061997-05-20 18:03:22 +000036
Martin v. Löwis502ba462003-06-07 20:10:54 +000037 def pickle_complex(c):
38 return complex, (c.real, c.imag)
39
40 pickle(complex, pickle_complex, complex)
Guido van Rossum3926a632001-09-25 16:25:58 +000041
Guido van Rossum298e4212003-02-13 16:30:16 +000042# Support for pickling new-style objects
Guido van Rossum3926a632001-09-25 16:25:58 +000043
Guido van Rossum3926a632001-09-25 16:25:58 +000044def _reconstructor(cls, base, state):
Guido van Rossum298e4212003-02-13 16:30:16 +000045 if base is object:
46 obj = object.__new__(cls)
47 else:
48 obj = base.__new__(cls, state)
49 base.__init__(obj, state)
Guido van Rossum3926a632001-09-25 16:25:58 +000050 return obj
Guido van Rossum3926a632001-09-25 16:25:58 +000051
52_HEAPTYPE = 1<<9
53
Guido van Rossumbe532422003-02-21 22:20:31 +000054# Python code for object.__reduce_ex__ for protocols 0 and 1
55
56def _reduce_ex(self, proto):
57 assert proto < 2
Guido van Rossum3926a632001-09-25 16:25:58 +000058 for base in self.__class__.__mro__:
Guido van Rossum00fb0c92001-11-24 21:04:31 +000059 if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
Guido van Rossum3926a632001-09-25 16:25:58 +000060 break
61 else:
62 base = object # not really reachable
63 if base is object:
64 state = None
65 else:
Guido van Rossum2a6f5b32001-12-27 16:27:28 +000066 if base is self.__class__:
67 raise TypeError, "can't pickle %s objects" % base.__name__
Guido van Rossum3926a632001-09-25 16:25:58 +000068 state = base(self)
Guido van Rossum6cef6d52001-09-28 18:13:29 +000069 args = (self.__class__, base, state)
70 try:
Guido van Rossum00fb0c92001-11-24 21:04:31 +000071 getstate = self.__getstate__
Guido van Rossum6cef6d52001-09-28 18:13:29 +000072 except AttributeError:
Guido van Rossum3f50cdc2003-02-10 21:31:27 +000073 if getattr(self, "__slots__", None):
74 raise TypeError("a class that defines __slots__ without "
75 "defining __getstate__ cannot be pickled")
Guido van Rossum00fb0c92001-11-24 21:04:31 +000076 try:
77 dict = self.__dict__
78 except AttributeError:
79 dict = None
80 else:
81 dict = getstate()
Guido van Rossum6cef6d52001-09-28 18:13:29 +000082 if dict:
83 return _reconstructor, args, dict
84 else:
85 return _reconstructor, args
Guido van Rossum255f3ee2003-01-29 06:14:11 +000086
Guido van Rossumbe532422003-02-21 22:20:31 +000087# Helper for __reduce_ex__ protocol 2
Guido van Rossum5aac4e62003-02-06 22:57:00 +000088
89def __newobj__(cls, *args):
90 return cls.__new__(cls, *args)
91
Guido van Rossum5aac4e62003-02-06 22:57:00 +000092def _slotnames(cls):
93 """Return a list of slot names for a given class.
94
95 This needs to find slots defined by the class and its bases, so we
96 can't simply return the __slots__ attribute. We must walk down
97 the Method Resolution Order and concatenate the __slots__ of each
98 class found there. (This assumes classes don't modify their
99 __slots__ attribute to misrepresent their slots after the class is
100 defined.)
101 """
102
103 # Get the value from a cache in the class if possible
104 names = cls.__dict__.get("__slotnames__")
105 if names is not None:
106 return names
107
108 # Not cached -- calculate the value
109 names = []
110 if not hasattr(cls, "__slots__"):
111 # This class has no slots
112 pass
113 else:
114 # Slots found -- gather slot names from all base classes
115 for c in cls.__mro__:
116 if "__slots__" in c.__dict__:
117 names += [name for name in c.__dict__["__slots__"]
118 if name not in ("__dict__", "__weakref__")]
119
120 # Cache the outcome in the class if at all possible
121 try:
122 cls.__slotnames__ = names
123 except:
124 pass # But don't die if we can't
125
126 return names
127
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000128# A registry of extension codes. This is an ad-hoc compression
129# mechanism. Whenever a global reference to <module>, <name> is about
130# to be pickled, the (<module>, <name>) tuple is looked up here to see
131# if it is a registered extension code for it. Extension codes are
132# universal, so that the meaning of a pickle does not depend on
133# context. (There are also some codes reserved for local use that
134# don't have this restriction.) Codes are positive ints; 0 is
135# reserved.
136
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000137_extension_registry = {} # key -> code
138_inverted_registry = {} # code -> key
139_extension_cache = {} # code -> object
Tim Peters5b7da392003-02-04 00:21:07 +0000140# Don't ever rebind those names: cPickle grabs a reference to them when
141# it's initialized, and won't see a rebinding.
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000142
143def add_extension(module, name, code):
144 """Register an extension code."""
145 code = int(code)
Tim Peters2d629652003-02-04 05:06:17 +0000146 if not 1 <= code <= 0x7fffffff:
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000147 raise ValueError, "code out of range"
148 key = (module, name)
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000149 if (_extension_registry.get(key) == code and
150 _inverted_registry.get(code) == key):
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000151 return # Redundant registrations are benign
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000152 if key in _extension_registry:
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000153 raise ValueError("key %s is already registered with code %s" %
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000154 (key, _extension_registry[key]))
155 if code in _inverted_registry:
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000156 raise ValueError("code %s is already in use for key %s" %
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000157 (code, _inverted_registry[code]))
158 _extension_registry[key] = code
159 _inverted_registry[code] = key
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000160
161def remove_extension(module, name, code):
162 """Unregister an extension code. For testing only."""
163 key = (module, name)
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000164 if (_extension_registry.get(key) != code or
165 _inverted_registry.get(code) != key):
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000166 raise ValueError("key %s is not registered with code %s" %
167 (key, code))
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000168 del _extension_registry[key]
169 del _inverted_registry[code]
170 if code in _extension_cache:
171 del _extension_cache[code]
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000172
173def clear_extension_cache():
Guido van Rossumd4b920c2003-02-04 01:54:49 +0000174 _extension_cache.clear()
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000175
176# Standard extension code assignments
177
178# Reserved ranges
179
180# First Last Count Purpose
181# 1 127 127 Reserved for Python standard library
Guido van Rossumcef9db62003-02-07 20:56:38 +0000182# 128 191 64 Reserved for Zope
Guido van Rossum255f3ee2003-01-29 06:14:11 +0000183# 192 239 48 Reserved for 3rd parties
184# 240 255 16 Reserved for private use (will never be assigned)
185# 256 Inf Inf Reserved for future assignment
186
187# Extension codes are assigned by the Python Software Foundation.