Pickle in python2 then unpickle in python3 results in TypeError: an integer is required (got type str)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
pytz |
Invalid
|
Undecided
|
Unassigned |
Bug Description
When pickling a datetime with tzinfo in python2 and later unpickle it in python3 it results in an TypeError: an integer is required (got type str)
== Versions ==
python2 -V
Python 2.7.12
python3 -V
Python 3.5.2
python2 -c "import pytz
print(pytz.
2018.9
python3 -c "import pytz
print(pytz.
2018.9
== Create the pickle and verify in python 2 ==
python2
>>> import pickle, pytz
>>> from datetime import datetime
>>> d = pickle.
>>> with open('data.pickle', 'w+') as f:
f.write(d)
python2
>>> import pickle
>>> print(pickle.
2019-03-03 22:46:07.
python2
>>> import pickletools
>>> pickletools.
0: \x80 PROTO 2
2: c GLOBAL 'datetime datetime'
21: q BINPUT 0
23: U SHORT_BINSTRING '\x07\xe3\
35: q BINPUT 1
37: c GLOBAL 'pytz _UTC'
48: q BINPUT 2
50: ) EMPTY_TUPLE
51: R REDUCE
52: q BINPUT 3
54: \x86 TUPLE2
55: q BINPUT 4
57: R REDUCE
58: q BINPUT 5
60: . STOP
highest protocol among opcodes = 2
== Type to open the pickle in python 3 ==
python3
>>> import pickle
>>> print(pickle.
Traceback (most recent call last):
File "<string>", line 2, in <module>
TypeError: an integer is required (got type str)
== There is also a small difference in the SHORT_BINSTRING: ã ==
python3
>>> import pickletools
>>> pickletools.
0: \x80 PROTO 2
2: c GLOBAL 'datetime datetime'
21: q BINPUT 0
23: U SHORT_BINSTRING '\x07ã\
35: q BINPUT 1
37: c GLOBAL 'pytz _UTC'
48: q BINPUT 2
50: ) EMPTY_TUPLE
51: R REDUCE
52: q BINPUT 3
54: \x86 TUPLE2
55: q BINPUT 4
57: R REDUCE
58: q BINPUT 5
60: . STOP
highest protocol among opcodes = 2
I can reproduce the problem when pickling a datetime that uses a pytz timezone. However, I can successfully pickle and unpickle the timezone instance itself.
This looks like a Python bug, as it is reproducible without pytz:
Python2:
>>> from datetime import tzinfo, datetime dumps(datetime. utcnow( ).replace( tzinfo= tzinfo( )), protocol= pickle. HIGHEST_ PROTOCOL)
>>> import pickle
>>> d = pickle.
>>> with open('p4', 'wb') as f:
... f.write(d)
Python3:
>>> import pickle load(open( 'p4', 'rb'), encoding='latin-1')
>>> pickle.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type str)