Skip to content

Commit 00987f6

Browse files
bpo-32011: Revert "Issue #15480: Remove the deprecated and unused TYPE_INT64 code from marshal." (#4381)
Simplify the reverted code. This reverts commit e9bbe8b.
1 parent ddbce13 commit 00987f6

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

Lib/test/test_marshal.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,29 @@ def test_ints(self):
3434
self.helper(expected)
3535
n = n >> 1
3636

37+
def test_int64(self):
38+
# Simulate int marshaling with TYPE_INT64.
39+
maxint64 = (1 << 63) - 1
40+
minint64 = -maxint64-1
41+
for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
42+
while base:
43+
s = b'I' + int.to_bytes(base, 8, 'little', signed=True)
44+
got = marshal.loads(s)
45+
self.assertEqual(base, got)
46+
if base == -1: # a fixed-point for shifting right 1
47+
base = 0
48+
else:
49+
base >>= 1
50+
51+
got = marshal.loads(b'I\xfe\xdc\xba\x98\x76\x54\x32\x10')
52+
self.assertEqual(got, 0x1032547698badcfe)
53+
got = marshal.loads(b'I\x01\x23\x45\x67\x89\xab\xcd\xef')
54+
self.assertEqual(got, -0x1032547698badcff)
55+
got = marshal.loads(b'I\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f')
56+
self.assertEqual(got, 0x7f6e5d4c3b2a1908)
57+
got = marshal.loads(b'I\xf7\xe6\xd5\xc4\xb3\xa2\x91\x80')
58+
self.assertEqual(got, -0x7f6e5d4c3b2a1909)
59+
3760
def test_bool(self):
3861
for b in (True, False):
3962
self.helper(b)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Restored support of loading marshal files with the TYPE_INT64 code. These
2+
files can be produced in Python 2.7.

Python/marshal.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ module marshal
3939
#define TYPE_STOPITER 'S'
4040
#define TYPE_ELLIPSIS '.'
4141
#define TYPE_INT 'i'
42+
/* TYPE_INT64 is not generated anymore.
43+
Supported for backward compatibility only. */
44+
#define TYPE_INT64 'I'
4245
#define TYPE_FLOAT 'f'
4346
#define TYPE_BINARY_FLOAT 'g'
4447
#define TYPE_COMPLEX 'x'
@@ -783,6 +786,19 @@ r_long(RFILE *p)
783786
return x;
784787
}
785788

789+
/* r_long64 deals with the TYPE_INT64 code. */
790+
static PyObject *
791+
r_long64(RFILE *p)
792+
{
793+
const unsigned char *buffer = (const unsigned char *) r_string(8, p);
794+
if (buffer == NULL) {
795+
return NULL;
796+
}
797+
return _PyLong_FromByteArray(buffer, 8,
798+
1 /* little endian */,
799+
1 /* signed */);
800+
}
801+
786802
static PyObject *
787803
r_PyLong(RFILE *p)
788804
{
@@ -982,6 +998,11 @@ r_object(RFILE *p)
982998
R_REF(retval);
983999
break;
9841000

1001+
case TYPE_INT64:
1002+
retval = r_long64(p);
1003+
R_REF(retval);
1004+
break;
1005+
9851006
case TYPE_LONG:
9861007
retval = r_PyLong(p);
9871008
R_REF(retval);

0 commit comments

Comments
 (0)