Pickle in python2 then unpickle in python3 results in TypeError: an integer is required (got type str)

Bug #1818453 reported by Ronnie
6
This bug affects 1 person
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.__version__)"
2018.9

python3 -c "import pytz
print(pytz.__version__)"
2018.9

== Create the pickle and verify in python 2 ==
python2
>>> import pickle, pytz
>>> from datetime import datetime
>>> d = pickle.dumps(datetime.utcnow().replace(tzinfo=pytz.utc), protocol=pickle.HIGHEST_PROTOCOL)
>>> with open('data.pickle', 'w+') as f:
        f.write(d)

python2
>>> import pickle
>>> print(pickle.load(open('data.pickle', 'rb')))
2019-03-03 22:46:07.651744+00:00

python2
>>> import pickletools
>>> pickletools.dis(open('data.pickle', 'rb').read())
    0: \x80 PROTO 2
    2: c GLOBAL 'datetime datetime'
   21: q BINPUT 0
   23: U SHORT_BINSTRING '\x07\xe3\x03\x03\x16.\x07\t\xf1\xe0'
   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.load(open('data.pickle', 'rb'), encoding='latin-1'))
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.dis(open('data.pickle', 'rb').read())
    0: \x80 PROTO 2
    2: c GLOBAL 'datetime datetime'
   21: q BINPUT 0
   23: U SHORT_BINSTRING '\x07ã\x03\x03\x16.\x07\tñà'
   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

Revision history for this message
Stuart Bishop (stub) wrote :

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
>>> import pickle
>>> d = pickle.dumps(datetime.utcnow().replace(tzinfo=tzinfo()), protocol=pickle.HIGHEST_PROTOCOL)
>>> with open('p4', 'wb') as f:
... f.write(d)

Python3:

>>> import pickle
>>> pickle.load(open('p4', 'rb'), encoding='latin-1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type str)

Changed in pytz:
status: New → Incomplete
Revision history for this message
Ronnie (ronnie.vd.c) wrote :

Thanks, i see it's already fixed in Python 2.7

Changed in pytz:
status: Incomplete → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.