Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
3daaafb7
Commit
3daaafb7
authored
Nov 16, 2017
by
Serhiy Storchaka
Committed by
GitHub
Nov 16, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-32037: Use the INT opcode for 32-bit integers in protocol 0 pickles. (#4407)
parent
0a2abdfc
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
70 additions
and
63 deletions
+70
-63
Lib/pickle.py
Lib/pickle.py
+4
-1
Lib/pickletools.py
Lib/pickletools.py
+36
-36
Lib/test/pickletester.py
Lib/test/pickletester.py
+3
-3
Misc/NEWS.d/next/Library/2017-11-15-19-04-22.bpo-32037.r8-5Nk.rst
...S.d/next/Library/2017-11-15-19-04-22.bpo-32037.r8-5Nk.rst
+4
-0
Modules/_pickle.c
Modules/_pickle.c
+23
-23
No files found.
Lib/pickle.py
View file @
3daaafb7
...
...
@@ -674,7 +674,10 @@ class _Pickler:
else
:
self
.
write
(
LONG4
+
pack
(
"<i"
,
n
)
+
encoded
)
return
self
.
write
(
LONG
+
repr
(
obj
).
encode
(
"ascii"
)
+
b'L
\
n
'
)
if
-
0x80000000
<=
obj
<=
0x7fffffff
:
self
.
write
(
INT
+
repr
(
obj
).
encode
(
"ascii"
)
+
b'
\
n
'
)
else
:
self
.
write
(
LONG
+
repr
(
obj
).
encode
(
"ascii"
)
+
b'L
\
n
'
)
dispatch
[
int
]
=
save_long
def
save_float
(
self
,
obj
):
...
...
Lib/pickletools.py
View file @
3daaafb7
...
...
@@ -2480,35 +2480,35 @@ _dis_test = r"""
0: ( MARK
1: l LIST (MARK at 0)
2: p PUT 0
5:
L LONG
1
9
: a APPEND
10: L LONG
2
1
4
: a APPEND
1
5
: ( MARK
1
6: L LONG
3
20: L LONG
4
2
4: t TUPLE (MARK at 15
)
2
5
: p PUT 1
2
8
: a APPEND
2
9
: ( MARK
30: d DICT (MARK at 29
)
31
: p PUT 2
3
4
: c GLOBAL '_codecs encode'
50
: p PUT 3
53
: ( MARK
5
4
: V UNICODE 'abc'
5
9
: p PUT 4
62
: V UNICODE 'latin1'
70
: p PUT 5
73: t TUPLE (MARK at 53
)
7
4
: p PUT 6
7
7
: R REDUCE
7
8
: p PUT 7
81
: V UNICODE 'def'
8
6
: p PUT 8
8
9
: s SETITEM
90
: a APPEND
91
: . STOP
5:
I INT
1
8
: a APPEND
9: I INT
2
1
2
: a APPEND
1
3
: ( MARK
1
4: I INT
3
17: I INT
4
2
0: t TUPLE (MARK at 13
)
2
1
: p PUT 1
2
4
: a APPEND
2
5
: ( MARK
26: d DICT (MARK at 25
)
27
: p PUT 2
3
0
: c GLOBAL '_codecs encode'
46
: p PUT 3
49
: ( MARK
5
0
: V UNICODE 'abc'
5
5
: p PUT 4
58
: V UNICODE 'latin1'
66
: p PUT 5
69: t TUPLE (MARK at 49
)
7
0
: p PUT 6
7
3
: R REDUCE
7
4
: p PUT 7
77
: V UNICODE 'def'
8
2
: p PUT 8
8
5
: s SETITEM
86
: a APPEND
87
: . STOP
highest protocol among opcodes = 0
Try again with a "binary" pickle.
...
...
@@ -2577,13 +2577,13 @@ highest protocol among opcodes = 0
93: p PUT 6
96: V UNICODE 'value'
103: p PUT 7
106:
L LONG
42
11
1
: s SETITEM
11
2
: b BUILD
11
3
: a APPEND
11
4
: g GET 5
11
7
: a APPEND
11
8
: . STOP
106:
I INT
42
11
0
: s SETITEM
11
1
: b BUILD
11
2
: a APPEND
11
3
: g GET 5
11
6
: a APPEND
11
7
: . STOP
highest protocol among opcodes = 0
>>> dis(pickle.dumps(x, 1))
...
...
Lib/test/pickletester.py
View file @
3daaafb7
...
...
@@ -1821,7 +1821,7 @@ class AbstractPickleTests(unittest.TestCase):
with
self
.
subTest
(
proto
=
proto
):
s
=
self
.
dumps
(
x
,
proto
)
if
proto
<
1
:
self
.
assertIn
(
b'
\
n
L64206'
,
s
)
# LONG
self
.
assertIn
(
b'
\
n
I64206'
,
s
)
# INT
else
:
self
.
assertIn
(
b'M
\
xce
\
xfa
'
,
s
)
# BININT2
self
.
assertEqual
(
opcode_in_pickle
(
pickle
.
NEWOBJ
,
s
),
...
...
@@ -1837,7 +1837,7 @@ class AbstractPickleTests(unittest.TestCase):
with
self
.
subTest
(
proto
=
proto
):
s
=
self
.
dumps
(
x
,
proto
)
if
proto
<
1
:
self
.
assertIn
(
b'
\
n
L64206'
,
s
)
# LONG
self
.
assertIn
(
b'
\
n
I64206'
,
s
)
# INT
elif
proto
<
2
:
self
.
assertIn
(
b'M
\
xce
\
xfa
'
,
s
)
# BININT2
elif
proto
<
4
:
...
...
@@ -1857,7 +1857,7 @@ class AbstractPickleTests(unittest.TestCase):
with
self
.
subTest
(
proto
=
proto
):
s
=
self
.
dumps
(
x
,
proto
)
if
proto
<
1
:
self
.
assertIn
(
b'
\
n
L64206'
,
s
)
# LONG
self
.
assertIn
(
b'
\
n
I64206'
,
s
)
# INT
elif
proto
<
2
:
self
.
assertIn
(
b'M
\
xce
\
xfa
'
,
s
)
# BININT2
elif
proto
<
4
:
...
...
Misc/NEWS.d/next/Library/2017-11-15-19-04-22.bpo-32037.r8-5Nk.rst
0 → 100644
View file @
3daaafb7
Integers that fit in a signed 32-bit integer will be now pickled with
protocol 0 using the INT opcode. This will decrease the size of a pickle,
speed up pickling and unpickling, and make these integers be unpickled as
int instances in Python 2.
Modules/_pickle.c
View file @
3daaafb7
...
...
@@ -1858,18 +1858,13 @@ save_long(PicklerObject *self, PyObject *obj)
PyObject
*
repr
=
NULL
;
Py_ssize_t
size
;
long
val
;
int
overflow
;
int
status
=
0
;
const
char
long_op
=
LONG
;
val
=
PyLong_AsLong
(
obj
);
if
(
val
==
-
1
&&
PyErr_Occurred
())
{
/* out of range for int pickling */
PyErr_Clear
();
}
else
if
(
self
->
bin
&&
(
sizeof
(
long
)
<=
4
||
(
val
<=
0x7fffffffL
&&
val
>=
(
-
0x7fffffffL
-
1
))))
{
val
=
PyLong_AsLongAndOverflow
(
obj
,
&
overflow
);
if
(
!
overflow
&&
(
sizeof
(
long
)
<=
4
||
(
val
<=
0x7fffffffL
&&
val
>=
(
-
0x7fffffffL
-
1
))))
{
/* result fits in a signed 4-byte integer.
Note: we can't use -0x80000000L in the above condition because some
...
...
@@ -1882,31 +1877,35 @@ save_long(PicklerObject *self, PyObject *obj)
char
pdata
[
32
];
Py_ssize_t
len
=
0
;
pdata
[
1
]
=
(
unsigned
char
)(
val
&
0xff
);
pdata
[
2
]
=
(
unsigned
char
)((
val
>>
8
)
&
0xff
);
pdata
[
3
]
=
(
unsigned
char
)((
val
>>
16
)
&
0xff
);
pdata
[
4
]
=
(
unsigned
char
)((
val
>>
24
)
&
0xff
);
if
((
pdata
[
4
]
==
0
)
&&
(
pdata
[
3
]
==
0
))
{
if
(
pdata
[
2
]
==
0
)
{
pdata
[
0
]
=
BININT
1
;
len
=
2
;
if
(
self
->
bin
)
{
pdata
[
1
]
=
(
unsigned
char
)(
val
&
0xff
);
pdata
[
2
]
=
(
unsigned
char
)((
val
>>
8
)
&
0xff
);
pdata
[
3
]
=
(
unsigned
char
)((
val
>>
16
)
&
0xff
);
pdata
[
4
]
=
(
unsigned
char
)((
val
>>
24
)
&
0xff
);
if
(
(
pdata
[
4
]
!=
0
)
||
(
pdata
[
3
]
!=
0
)
)
{
pdata
[
0
]
=
BININT
;
len
=
5
;
}
else
{
else
if
(
pdata
[
2
]
!=
0
)
{
pdata
[
0
]
=
BININT2
;
len
=
3
;
}
else
{
pdata
[
0
]
=
BININT1
;
len
=
2
;
}
}
else
{
pdata
[
0
]
=
BININT
;
len
=
5
;
sprintf
(
pdata
,
"%c%ld
\n
"
,
INT
,
val
)
;
len
=
strlen
(
pdata
)
;
}
if
(
_Pickler_Write
(
self
,
pdata
,
len
)
<
0
)
return
-
1
;
return
0
;
}
assert
(
!
PyErr_Occurred
());
if
(
self
->
proto
>=
2
)
{
/* Linear-time pickling. */
...
...
@@ -1986,6 +1985,7 @@ save_long(PicklerObject *self, PyObject *obj)
goto
error
;
}
else
{
const
char
long_op
=
LONG
;
const
char
*
string
;
/* proto < 2: write the repr and newline. This is quadratic-time (in
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment