Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
d92f0406
Kaydet (Commit)
d92f0406
authored
Tem 17, 2010
tarafından
Alexander Belopolsky
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
python when they contain instances of old-style classes.
üst
bbda0c5f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
40 deletions
+91
-40
pickle.py
Lib/pickle.py
+5
-16
pickletester.py
Lib/test/pickletester.py
+69
-0
NEWS
Misc/NEWS
+3
-0
_pickle.c
Modules/_pickle.c
+14
-24
No files found.
Lib/pickle.py
Dosyayı görüntüle @
d92f0406
...
@@ -1034,19 +1034,15 @@ class _Unpickler:
...
@@ -1034,19 +1034,15 @@ class _Unpickler:
def
_instantiate
(
self
,
klass
,
k
):
def
_instantiate
(
self
,
klass
,
k
):
args
=
tuple
(
self
.
stack
[
k
+
1
:])
args
=
tuple
(
self
.
stack
[
k
+
1
:])
del
self
.
stack
[
k
:]
del
self
.
stack
[
k
:]
instantiated
=
False
if
(
args
or
not
isinstance
(
klass
,
type
)
or
if
(
not
args
and
hasattr
(
klass
,
"__getinitargs__"
)):
isinstance
(
klass
,
type
)
and
not
hasattr
(
klass
,
"__getinitargs__"
)):
value
=
_EmptyClass
()
value
.
__class__
=
klass
instantiated
=
True
if
not
instantiated
:
try
:
try
:
value
=
klass
(
*
args
)
value
=
klass
(
*
args
)
except
TypeError
as
err
:
except
TypeError
as
err
:
raise
TypeError
(
"in constructor for
%
s:
%
s"
%
raise
TypeError
(
"in constructor for
%
s:
%
s"
%
(
klass
.
__name__
,
str
(
err
)),
sys
.
exc_info
()[
2
])
(
klass
.
__name__
,
str
(
err
)),
sys
.
exc_info
()[
2
])
else
:
value
=
klass
.
__new__
(
klass
)
self
.
append
(
value
)
self
.
append
(
value
)
def
load_inst
(
self
):
def
load_inst
(
self
):
...
@@ -1239,14 +1235,7 @@ class _Unpickler:
...
@@ -1239,14 +1235,7 @@ class _Unpickler:
raise
_Stop
(
value
)
raise
_Stop
(
value
)
dispatch
[
STOP
[
0
]]
=
load_stop
dispatch
[
STOP
[
0
]]
=
load_stop
# Helper class for load_inst/load_obj
# Encode/decode longs.
class
_EmptyClass
:
pass
# Encode/decode longs in linear time.
import
binascii
as
_binascii
def
encode_long
(
x
):
def
encode_long
(
x
):
r"""Encode a long to a two's complement little-endian binary string.
r"""Encode a long to a two's complement little-endian binary string.
...
...
Lib/test/pickletester.py
Dosyayı görüntüle @
d92f0406
...
@@ -65,9 +65,21 @@ class C:
...
@@ -65,9 +65,21 @@ class C:
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
return
self
.
__dict__
==
other
.
__dict__
return
self
.
__dict__
==
other
.
__dict__
class
D
(
C
):
def
__init__
(
self
,
arg
):
pass
class
E
(
C
):
def
__getinitargs__
(
self
):
return
()
import
__main__
import
__main__
__main__
.
C
=
C
__main__
.
C
=
C
C
.
__module__
=
"__main__"
C
.
__module__
=
"__main__"
__main__
.
D
=
D
D
.
__module__
=
"__main__"
__main__
.
E
=
E
E
.
__module__
=
"__main__"
class
myint
(
int
):
class
myint
(
int
):
def
__init__
(
self
,
x
):
def
__init__
(
self
,
x
):
...
@@ -425,6 +437,63 @@ class AbstractPickleTests(unittest.TestCase):
...
@@ -425,6 +437,63 @@ class AbstractPickleTests(unittest.TestCase):
def
test_load_from_data2
(
self
):
def
test_load_from_data2
(
self
):
self
.
assertEqual
(
self
.
_testdata
,
self
.
loads
(
DATA2
))
self
.
assertEqual
(
self
.
_testdata
,
self
.
loads
(
DATA2
))
def
test_load_classic_instance
(
self
):
# See issue5180. Test loading 2.x pickles that
# contain an instance of old style class.
for
X
,
args
in
[(
C
,
()),
(
D
,
(
'x'
,)),
(
E
,
())]:
xname
=
X
.
__name__
.
encode
(
'ascii'
)
# Protocol 0 (text mode pickle):
"""
0: ( MARK
1: i INST '__main__ X' (MARK at 0)
15: p PUT 0
18: ( MARK
19: d DICT (MARK at 18)
20: p PUT 1
23: b BUILD
24: . STOP
"""
pickle0
=
(
b
"(i__main__
\n
"
b
"X
\n
"
b
"p0
\n
"
b
"(dp1
\n
b."
)
.
replace
(
b
'X'
,
xname
)
self
.
assertEqual
(
X
(
*
args
),
self
.
loads
(
pickle0
))
# Protocol 1 (binary mode pickle)
"""
0: ( MARK
1: c GLOBAL '__main__ X'
15: q BINPUT 0
17: o OBJ (MARK at 0)
18: q BINPUT 1
20: } EMPTY_DICT
21: q BINPUT 2
23: b BUILD
24: . STOP
"""
pickle1
=
(
b
'(c__main__
\n
'
b
'X
\n
'
b
'q
\x00
oq
\x01
}q
\x02
b.'
)
.
replace
(
b
'X'
,
xname
)
self
.
assertEqual
(
X
(
*
args
),
self
.
loads
(
pickle1
))
# Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
"""
0:
\x80
PROTO 2
2: ( MARK
3: c GLOBAL '__main__ X'
17: q BINPUT 0
19: o OBJ (MARK at 2)
20: q BINPUT 1
22: } EMPTY_DICT
23: q BINPUT 2
25: b BUILD
26: . STOP
"""
pickle2
=
(
b
'
\x80\x02
(c__main__
\n
'
b
'X
\n
'
b
'q
\x00
oq
\x01
}q
\x02
b.'
)
.
replace
(
b
'X'
,
xname
)
self
.
assertEqual
(
X
(
*
args
),
self
.
loads
(
pickle2
))
# There are gratuitous differences between pickles produced by
# There are gratuitous differences between pickles produced by
# pickle and cPickle, largely because cPickle starts PUT indices at
# pickle and cPickle, largely because cPickle starts PUT indices at
# 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
# 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --
...
...
Misc/NEWS
Dosyayı görüntüle @
d92f0406
...
@@ -1429,6 +1429,9 @@ Library
...
@@ -1429,6 +1429,9 @@ Library
Extension Modules
Extension Modules
-----------------
-----------------
- Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
python when they contain instances of old-style classes.
- Issue #9165: Add new functions math.isfinite and cmath.isfinite, to
- Issue #9165: Add new functions math.isfinite and cmath.isfinite, to
accompany existing isinf and isnan functions.
accompany existing isinf and isnan functions.
...
...
Modules/_pickle.c
Dosyayı görüntüle @
d92f0406
...
@@ -3466,29 +3466,19 @@ load_dict(UnpicklerObject *self)
...
@@ -3466,29 +3466,19 @@ load_dict(UnpicklerObject *self)
static
PyObject
*
static
PyObject
*
instantiate
(
PyObject
*
cls
,
PyObject
*
args
)
instantiate
(
PyObject
*
cls
,
PyObject
*
args
)
{
{
PyObject
*
r
=
NULL
;
PyObject
*
result
=
NULL
;
/* Caller must assure args are a tuple. Normally, args come from
/* XXX: The pickle.py module does not create instances this way when the
Pdata_poptuple which packs objects from the top of the stack
args tuple is empty. See Unpickler._instantiate(). */
into a newly created tuple. */
if
((
r
=
PyObject_CallObject
(
cls
,
args
)))
assert
(
PyTuple_Check
(
args
));
return
r
;
if
(
Py_SIZE
(
args
)
>
0
||
!
PyType_Check
(
cls
)
||
PyObject_HasAttrString
(
cls
,
"__getinitargs__"
))
{
/* XXX: Is this still nescessary? */
result
=
PyObject_CallObject
(
cls
,
args
);
{
PyObject
*
tp
,
*
v
,
*
tb
,
*
tmp_value
;
PyErr_Fetch
(
&
tp
,
&
v
,
&
tb
);
tmp_value
=
v
;
/* NULL occurs when there was a KeyboardInterrupt */
if
(
tmp_value
==
NULL
)
tmp_value
=
Py_None
;
if
((
r
=
PyTuple_Pack
(
3
,
tmp_value
,
cls
,
args
)))
{
Py_XDECREF
(
v
);
v
=
r
;
}
PyErr_Restore
(
tp
,
v
,
tb
);
}
}
return
NULL
;
else
{
result
=
PyObject_CallMethod
(
cls
,
"__new__"
,
"O"
,
cls
);
}
return
result
;
}
}
static
int
static
int
...
@@ -3547,7 +3537,7 @@ load_inst(UnpicklerObject *self)
...
@@ -3547,7 +3537,7 @@ load_inst(UnpicklerObject *self)
if
(
len
<
2
)
if
(
len
<
2
)
return
bad_readline
();
return
bad_readline
();
class_name
=
PyUnicode_DecodeASCII
(
s
,
len
-
1
,
"strict"
);
class_name
=
PyUnicode_DecodeASCII
(
s
,
len
-
1
,
"strict"
);
if
(
class_name
=
=
NULL
)
{
if
(
class_name
!
=
NULL
)
{
cls
=
find_class
(
self
,
module_name
,
class_name
);
cls
=
find_class
(
self
,
module_name
,
class_name
);
Py_DECREF
(
class_name
);
Py_DECREF
(
class_name
);
}
}
...
@@ -4276,7 +4266,7 @@ load_reduce(UnpicklerObject *self)
...
@@ -4276,7 +4266,7 @@ load_reduce(UnpicklerObject *self)
return
-
1
;
return
-
1
;
PDATA_POP
(
self
->
stack
,
callable
);
PDATA_POP
(
self
->
stack
,
callable
);
if
(
callable
)
{
if
(
callable
)
{
obj
=
instantiate
(
callable
,
argtup
);
obj
=
PyObject_CallObject
(
callable
,
argtup
);
Py_DECREF
(
callable
);
Py_DECREF
(
callable
);
}
}
Py_DECREF
(
argtup
);
Py_DECREF
(
argtup
);
...
...
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