@@ -48,17 +48,16 @@ to :class:`~bson.binary.Binary`::
48
48
{u'binary': Binary('this is a byte string', 0), u'_id': ObjectId('4f9086b1fba5222021000000')}
49
49
50
50
51
- Are there any issues migrating from Python 2 to Python 3?
52
- ---------------------------------------------------------
51
+ Why can't I share pickled ObjectIds between some versions of Python 2 and 3?
52
+ ----------------------------------------------------------------------------
53
53
54
- There are some issues sharing pickled instances of
55
- :class: `~bson.objectid.ObjectId ` between Python versions.
56
- :class: `~bson.objectid.ObjectId ` instances are implemented
57
- internally as packed binary data (:class: `str ` in Python 2,
58
- :class: `bytes ` in Python 3).
54
+ Instances of :class: `bytes ` pickled in Python 3 versions older than 3.2.3
55
+ can not be unpickled properly in Python 2. :class: `~bson.objectid.ObjectId `
56
+ instances are implemented internally as packed binary data (:class: `str ` in
57
+ Python 2, :class: `bytes ` in Python 3).
59
58
60
59
Changes have been made to allow unpickling in Python 3 of instances
61
- pickled in Python 2. You just have to use the encoding parameter
60
+ pickled in Python 2. You just have to use the `` encoding `` parameter
62
61
to pickle.loads::
63
62
64
63
Python 2.7.3 (default, Apr 12 2012, 10:35:17)
@@ -70,24 +69,78 @@ to pickle.loads::
70
69
>>> oid
71
70
ObjectId('4f919ba2fba5225b84000000')
72
71
>>> pickle.dumps(oid)
73
- 'ccopy_reg\n_reconstructor\np0\n(cbson.objectid\nObjectId\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\nS\'O\\x91\\x9b\\xa2\\xfb\\xa5"[\\x84\\x00\\x00\\x00\'\np5\nb .'
72
+ 'ccopy_reg\n_reconstructor\np0\n(cbson.objectid\.. .'
74
73
75
74
Python 3.1.4 (default, Mar 21 2012, 14:34:01)
76
75
[GCC 4.5.3] on linux2
77
76
Type "help", "copyright", "credits" or "license" for more information.
78
77
>>> import pickle
79
- >>> pickle.loads(b'ccopy_reg\n_reconstructor\np0\n(cbson.objectid\nObjectId\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\nS\'O\\x91\\x9b\\xa2\\xfb\\xa5"[\\x84\\x00\\x00\\x00\'\np5\nb .', encoding='latin-1')
78
+ >>> pickle.loads(b'ccopy_reg\n_reconstructor\np0\n(cbson.objectid\.. .', encoding='latin-1')
80
79
ObjectId('4f919ba2fba5225b84000000')
81
80
82
- Unfortunately there isn't currently a way to unpickle in Python 2
83
- instances of ObjectId pickled in Python 3. Python 2.4 and 2.5 will
84
- raise exceptions. Python 2.6 and 2.7 will decode the ObjectId to
85
- a garbage value. See the following links for an explanation and
86
- possible future work-arounds:
87
81
88
- http://bugs.python.org/issue6784
82
+ If you pickled the ObjectId using Python 3.2.3 or newer you can unpickle the
83
+ instance in Python 2. You just have to use ``protocol <= 2 ``::
89
84
90
- http://mail.python.org/pipermail/python-dev/2012-March/117536.html
85
+ Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50)
86
+ [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
87
+ Type "help", "copyright", "credits" or "license" for more information.
88
+ >>> import pickle
89
+ >>> from bson.objectid import ObjectId
90
+ >>> oid = ObjectId()
91
+ >>> oid
92
+ ObjectId('4f96f20c430ee6bd06000000')
93
+ >>> pickle.dumps(oid, protocol=2)
94
+ b'\x80\x02cbson.objectid\nObjectId\nq\x00)\x81q\x01c_codecs\nencode\...'
95
+
96
+ Python 2.4.4 (#1, Oct 18 2006, 10:34:39)
97
+ [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
98
+ Type "help", "copyright", "credits" or "license" for more information.
99
+ >>> import pickle
100
+ >>> pickle.loads('\x80\x02cbson.objectid\nObjectId\nq\x00)\x81q\x01c_codecs\nencode\...')
101
+ ObjectId('4f96f20c430ee6bd06000000')
102
+
103
+
104
+ Unfortunately this won't work if you pickled the ObjectId in a Python 3 version
105
+ older than 3.2.3::
106
+
107
+ Python 3.2.2 (default, Mar 21 2012, 14:32:23)
108
+ [GCC 4.5.3] on linux2
109
+ Type "help", "copyright", "credits" or "license" for more information.
110
+ >>> import pickle
111
+ >>> from bson.objectid import ObjectId
112
+ >>> oid = ObjectId()
113
+ >>> pickle.dumps(oid, protocol=2)
114
+ b'\x80\x02cbson.objectid\nObjectId\nq\x00)\x81q\x01c__builtin__\nbytes\...'
115
+
116
+ Python 2.4.6 (#1, Apr 12 2012, 14:48:24)
117
+ [GCC 4.5.3] on linux3
118
+ Type "help", "copyright", "credits" or "license" for more information.
119
+ >>> import pickle
120
+ >>> pickle.loads('\x80\x02cbson.objectid\nObjectId\nq\x00)\x81q\x01c__builtin__\nbytes\...')
121
+ Traceback (most recent call last):
122
+ File "<stdin>", line 1, in ?
123
+ File "/usr/lib/python2.4/pickle.py", line 1394, in loads
124
+ return Unpickler(file).load()
125
+ File "/usr/lib/python2.4/pickle.py", line 872, in load
126
+ dispatch[key](self)
127
+ File "/usr/lib/python2.4/pickle.py", line 1104, in load_global
128
+ klass = self.find_class(module, name)
129
+ File "/usr/lib/python2.4/pickle.py", line 1140, in find_class
130
+ klass = getattr(mod, name)
131
+ AttributeError: 'module' object has no attribute 'bytes'
132
+
133
+ .. warning ::
134
+
135
+ Unpickling in Python 2.6 or 2.7 an ObjectId pickled in a Python 3 version
136
+ older than 3.2.3 will seem to succeed but the resulting ObjectId instance
137
+ will contain garbage data.
138
+
139
+ >>> pickle.loads(' \x80\x02 cbson.objectid\n ObjectId\n q\x00 )\x81 q\x01 c__builtin__\n bytes\...)
140
+ ObjectId('5b37392c203135302c203234362c2034352c203235312c203136352c2033342c203532...')
141
+
142
+ See `http://bugs.python.org/issue13505 <http://bugs.python.org/issue13505 >`_
143
+ for more information about this issue.
91
144
92
145
93
146
Why do I get a syntax error importing pymongo after installing from source?
0 commit comments