-
Notifications
You must be signed in to change notification settings - Fork 7
/
patch
325 lines (287 loc) · 10.9 KB
/
patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
--- ../38/Include/picklebufobject.h 2020-05-10 16:01:50.000000000 -0700
+++ pickle5/picklebufobject.h 2020-05-18 16:44:04.000000000 -0700
@@ -10,18 +10,18 @@
#ifndef Py_LIMITED_API
-PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type;
+extern PyTypeObject PyPickleBuffer_Type;
#define PyPickleBuffer_Check(op) (Py_TYPE(op) == &PyPickleBuffer_Type)
/* Create a PickleBuffer redirecting to the given buffer-enabled object */
-PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *);
+PyObject *PyPickleBuffer_FromObject(PyObject *);
/* Get the PickleBuffer's underlying view to the original object
* (NULL if released)
*/
-PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *);
+const Py_buffer *PyPickleBuffer_GetBuffer(PyObject *);
/* Release the PickleBuffer. Returns 0 on success, -1 on error. */
-PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *);
+int PyPickleBuffer_Release(PyObject *);
#endif /* !Py_LIMITED_API */
--- ../38/Objects/picklebufobject.c 2020-05-10 16:01:50.000000000 -0700
+++ pickle5/picklebufobject.c 2020-05-18 16:46:09.000000000 -0700
@@ -4,6 +4,8 @@
#include "Python.h"
#include <stddef.h>
+#include "picklebufobject.h"
+
typedef struct {
PyObject_HEAD
/* The view exported by the original object */
--- ../38/Modules/_pickle.c 2020-05-18 14:58:20.000000000 -0700
+++ pickle5/_pickle.c 2020-05-19 22:02:26.000000000 -0700
@@ -1,11 +1,11 @@
-/* pickle accelerator C extensor: _pickle module.
- *
- * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows
- * and as an extension module (Py_BUILD_CORE_MODULE define) on other
- * platforms. */
-#if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE)
-# error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined"
+#include "compat.h"
+#include "picklebufobject.h"
+
+/* Core extension modules are built-in on some platforms (e.g. Windows). */
+#ifdef Py_BUILD_CORE
+#define Py_BUILD_CORE_BUILTIN
+#undef Py_BUILD_CORE
#endif
#include "Python.h"
@@ -709,7 +709,15 @@
static PyTypeObject Pickler_Type;
static PyTypeObject Unpickler_Type;
+#if PY_VERSION_HEX < 0x03060000
+#include "clinic/_pickle-3.5.c.h"
+#elif PY_VERSION_HEX < 0x03070000
+#include "clinic/_pickle-3.6.c.h"
+#elif PY_VERSION_HEX < 0x03080000
+#include "clinic/_pickle-3.7.c.h"
+#else
#include "clinic/_pickle.c.h"
+#endif
/*************************************************************************
A custom hashtable mapping void* to Python ints. This is used by the pickler
@@ -7066,11 +7074,6 @@
PyObject *global;
PyObject *module;
- if (PySys_Audit("pickle.find_class", "OO",
- module_name, global_name) < 0) {
- return NULL;
- }
-
/* Try to map the old names used in Python 2.x to the new ones used in
Python 3.x. We do this only with old pickle protocols and when the
user has not disabled the feature. */
@@ -7923,11 +7926,25 @@
return NULL;
}
+static PyObject*
+make_memoryview_readonly(PyObject *self, PyObject *arg)
+{
+ if (!PyMemoryView_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "_make_memoryview_readonly() argument must be memoryview");
+ return NULL;
+ }
+ PyMemoryViewObject *mv = (PyMemoryViewObject *) arg;
+ mv->view.readonly = 1;
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef pickle_methods[] = {
_PICKLE_DUMP_METHODDEF
_PICKLE_DUMPS_METHODDEF
_PICKLE_LOAD_METHODDEF
_PICKLE_LOADS_METHODDEF
+ {"_make_memoryview_readonly", make_memoryview_readonly, METH_O},
{NULL, NULL} /* sentinel */
};
@@ -8012,6 +8029,8 @@
Py_INCREF(&Unpickler_Type);
if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0)
return NULL;
+ if (PyType_Ready(&PyPickleBuffer_Type) < 0)
+ return NULL;
Py_INCREF(&PyPickleBuffer_Type);
if (PyModule_AddObject(m, "PickleBuffer",
(PyObject *)&PyPickleBuffer_Type) < 0)
--- ../38/Lib/pickle.py 2020-05-18 14:58:20.000000000 -0700
+++ pickle5/pickle.py 2020-05-19 21:57:30.000000000 -0700
@@ -40,7 +40,7 @@
"Unpickler", "dump", "dumps", "load", "loads"]
try:
- from _pickle import PickleBuffer
+ from ._pickle import PickleBuffer, _make_memoryview_readonly
__all__.append("PickleBuffer")
_HAVE_PICKLE_BUFFER = True
except ImportError:
@@ -1405,7 +1405,9 @@
buf = self.stack[-1]
with memoryview(buf) as m:
if not m.readonly:
- self.stack[-1] = m.toreadonly()
+ mm = memoryview(buf)
+ _make_memoryview_readonly(mm)
+ self.stack[-1] = mm
dispatch[READONLY_BUFFER[0]] = load_readonly_buffer
def load_short_binstring(self):
@@ -1568,7 +1570,6 @@
def find_class(self, module, name):
# Subclasses may override this.
- sys.audit('pickle.find_class', module, name)
if self.proto < 3 and self.fix_imports:
if (module, name) in _compat_pickle.NAME_MAPPING:
module, name = _compat_pickle.NAME_MAPPING[(module, name)]
@@ -1759,7 +1760,7 @@
# Use the faster _pickle if possible
try:
- from _pickle import (
+ from ._pickle import (
PickleError,
PicklingError,
UnpicklingError,
--- ../38/Lib/pickletools.py 2020-05-10 16:01:50.000000000 -0700
+++ pickle5/pickletools.py 2020-05-18 16:41:34.000000000 -0700
@@ -12,10 +12,11 @@
import codecs
import io
-import pickle
import re
import sys
+from . import pickle
+
__all__ = ['dis', 'genops', 'optimize']
bytes_types = pickle.bytes_types
--- ../38/Lib/test/pickletester.py 2020-05-18 14:58:20.000000000 -0700
+++ pickle5/test/pickletester.py 2020-05-20 10:32:52.000000000 -0700
@@ -5,8 +5,6 @@
import functools
import os
import math
-import pickle
-import pickletools
import shutil
import struct
import sys
@@ -32,7 +30,8 @@
_2G, _4G, bigmemtest, reap_threads, forget,
)
-from pickle import bytes_types
+import pickle5 as pickle
+from pickle5 import pickletools, bytes_types
requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
"test is only meaningful on 32-bit builds")
@@ -285,9 +284,9 @@
return not (self == other)
def __repr__(self):
- return (f"{type(self)}(shape={self.array.shape},"
- f"strides={self.array.strides}, "
- f"bytes={self.array.tobytes()})")
+ return ("{}(shape={}, strides={}, bytes={})".format(
+ type(self), self.array.shape, self.array.strides,
+ self.array.tobytes()))
def __reduce_ex__(self, protocol):
if not self.array.contiguous:
@@ -1457,12 +1456,11 @@
# of 1.
def dont_test_disassembly(self):
from io import StringIO
- from pickletools import dis
for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
s = self.dumps(self._testdata, proto)
filelike = StringIO()
- dis(s, out=filelike)
+ pickletools.dis(s, out=filelike)
got = filelike.getvalue()
self.assertEqual(expected, got)
@@ -2107,6 +2105,10 @@
x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__
x.abc = 666
for proto in protocols:
+ if sys.version_info < (3, 6) and proto < 4:
+ # '__getnewargs_ex__' is not supported in protocol 2 & 3 before Python3.6.
+ # See https://docs.python.org/3/library/pickle.html#object.__getnewargs_ex__
+ continue
with self.subTest(proto=proto):
s = self.dumps(x, proto)
if proto < 1:
@@ -2340,7 +2342,6 @@
elif frameless_start is not None:
self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN)
- @support.skip_if_pgo_task
def test_framing_many_objects(self):
obj = list(range(10**5))
for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
@@ -2430,7 +2431,6 @@
count_opcode(pickle.FRAME, pickled))
self.assertEqual(obj, self.loads(some_frames_pickle))
- @support.skip_if_pgo_task
def test_framed_write_sizes_with_delayed_writer(self):
class ChunkAccumulator:
"""Accumulate pickler output in a list of raw chunks."""
@@ -2785,6 +2785,7 @@
data = self.loads(data_pickled, buffers=None)
@unittest.skipIf(np is None, "Test needs Numpy")
+ @unittest.skipIf(sys.version_info < (3, 6), "Test requires Python version >= 3.6")
def test_buffers_numpy(self):
def check_no_copy(x, y):
np.testing.assert_equal(x, y)
--- ../38/Lib/test/test_pickle.py 2020-05-10 16:01:50.000000000 -0700
+++ pickle5/test/test_pickle.py 2020-05-18 16:37:57.000000000 -0700
@@ -1,7 +1,6 @@
from _compat_pickle import (IMPORT_MAPPING, REVERSE_IMPORT_MAPPING,
NAME_MAPPING, REVERSE_NAME_MAPPING)
import builtins
-import pickle
import io
import collections
import struct
@@ -11,19 +10,20 @@
import unittest
from test import support
-from test.pickletester import AbstractHookTests
-from test.pickletester import AbstractUnpickleTests
-from test.pickletester import AbstractPickleTests
-from test.pickletester import AbstractPickleModuleTests
-from test.pickletester import AbstractPersistentPicklerTests
-from test.pickletester import AbstractIdentityPersistentPicklerTests
-from test.pickletester import AbstractPicklerUnpicklerObjectTests
-from test.pickletester import AbstractDispatchTableTests
-from test.pickletester import AbstractCustomPicklerClass
-from test.pickletester import BigmemPickleTests
+from .pickletester import AbstractHookTests
+from .pickletester import AbstractUnpickleTests
+from .pickletester import AbstractPickleTests
+from .pickletester import AbstractPickleModuleTests
+from .pickletester import AbstractPersistentPicklerTests
+from .pickletester import AbstractIdentityPersistentPicklerTests
+from .pickletester import AbstractPicklerUnpicklerObjectTests
+from .pickletester import AbstractDispatchTableTests
+from .pickletester import AbstractCustomPicklerClass
+from .pickletester import BigmemPickleTests
+import pickle5 as pickle
try:
- import _pickle
+ from pickle5 import _pickle
has_c_implementation = True
except ImportError:
has_c_implementation = False
@@ -212,7 +212,7 @@
if has_c_implementation:
class CPickleTests(AbstractPickleModuleTests):
- from _pickle import dump, dumps, load, loads, Pickler, Unpickler
+ from pickle5._pickle import dump, dumps, load, loads, Pickler, Unpickler
class CUnpicklerTests(PyUnpicklerTests):
unpickler = _pickle.Unpickler
--- ../38/Lib/test/test_picklebuffer.py 2020-05-10 16:01:50.000000000 -0700
+++ pickle5/test/test_picklebuffer.py 2020-05-18 16:31:01.000000000 -0700
@@ -4,12 +4,13 @@
"""
import gc
-from pickle import PickleBuffer
import weakref
import unittest
from test import support
+from pickle5 import PickleBuffer
+
class B(bytes):
pass