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
9d4cbcc8
Kaydet (Commit)
9d4cbcc8
authored
Ock 30, 2015
tarafından
Benjamin Peterson
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
allow changing __class__ between a heaptype and non-heaptype in some cases (closes #22986)
Patch by Nathaniel Smith.
üst
91496a08
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
56 additions
and
26 deletions
+56
-26
test_descr.py
Lib/test/test_descr.py
+16
-0
NEWS
Misc/NEWS
+3
-0
typeobject.c
Objects/typeobject.c
+37
-26
No files found.
Lib/test/test_descr.py
Dosyayı görüntüle @
9d4cbcc8
...
@@ -1026,6 +1026,22 @@ order (MRO) for bases """
...
@@ -1026,6 +1026,22 @@ order (MRO) for bases """
self
.
assertEqual
(
x
.
foo
,
1
)
self
.
assertEqual
(
x
.
foo
,
1
)
self
.
assertEqual
(
x
.
__dict__
,
{
'foo'
:
1
})
self
.
assertEqual
(
x
.
__dict__
,
{
'foo'
:
1
})
def
test_object_class_assignment_between_heaptypes_and_nonheaptypes
(
self
):
class
SubType
(
types
.
ModuleType
):
a
=
1
m
=
types
.
ModuleType
(
"m"
)
self
.
assertTrue
(
m
.
__class__
is
types
.
ModuleType
)
self
.
assertFalse
(
hasattr
(
m
,
"a"
))
m
.
__class__
=
SubType
self
.
assertTrue
(
m
.
__class__
is
SubType
)
self
.
assertTrue
(
hasattr
(
m
,
"a"
))
m
.
__class__
=
types
.
ModuleType
self
.
assertTrue
(
m
.
__class__
is
types
.
ModuleType
)
self
.
assertFalse
(
hasattr
(
m
,
"a"
))
def
test_slots
(
self
):
def
test_slots
(
self
):
# Testing __slots__...
# Testing __slots__...
class
C0
(
object
):
class
C0
(
object
):
...
...
Misc/NEWS
Dosyayı görüntüle @
9d4cbcc8
...
@@ -10,6 +10,9 @@ Release date: TBA
...
@@ -10,6 +10,9 @@ Release date: TBA
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #22986: Allow changing an object'
s
__class__
between
a
dynamic
type
and
static
type
in
some
cases
.
-
Issue
#
15859
:
PyUnicode_EncodeFSDefault
(),
PyUnicode_EncodeMBCS
()
and
-
Issue
#
15859
:
PyUnicode_EncodeFSDefault
(),
PyUnicode_EncodeMBCS
()
and
PyUnicode_EncodeCodePage
()
now
raise
an
exception
if
the
object
is
not
an
PyUnicode_EncodeCodePage
()
now
raise
an
exception
if
the
object
is
not
an
Unicode
object
.
For
PyUnicode_EncodeFSDefault
(),
it
was
already
the
case
on
Unicode
object
.
For
PyUnicode_EncodeFSDefault
(),
it
was
already
the
case
on
...
...
Objects/typeobject.c
Dosyayı görüntüle @
9d4cbcc8
...
@@ -1196,8 +1196,11 @@ subtype_dealloc(PyObject *self)
...
@@ -1196,8 +1196,11 @@ subtype_dealloc(PyObject *self)
assert
(
basedealloc
);
assert
(
basedealloc
);
basedealloc
(
self
);
basedealloc
(
self
);
/* Can't reference self beyond this point */
/* Can't reference self beyond this point. It's possible tp_del switched
Py_DECREF
(
type
);
our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about
reference counting. */
if
(
type
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
Py_DECREF
(
type
);
endlabel:
endlabel:
++
_PyTrash_delete_nesting
;
++
_PyTrash_delete_nesting
;
...
@@ -3425,17 +3428,18 @@ object_get_class(PyObject *self, void *closure)
...
@@ -3425,17 +3428,18 @@ object_get_class(PyObject *self, void *closure)
}
}
static
int
static
int
equiv_structs
(
PyTypeObject
*
a
,
PyTypeObject
*
b
)
compatible_with_tp_base
(
PyTypeObject
*
child
)
{
{
return
a
==
b
||
PyTypeObject
*
parent
=
child
->
tp_base
;
(
a
!=
NULL
&&
return
(
parent
!=
NULL
&&
b
!=
NULL
&&
child
->
tp_basicsize
==
parent
->
tp_basicsize
&&
a
->
tp_basicsize
==
b
->
tp_basicsize
&&
child
->
tp_itemsize
==
parent
->
tp_itemsize
&&
a
->
tp_itemsize
==
b
->
tp_itemsize
&&
child
->
tp_dictoffset
==
parent
->
tp_dictoffset
&&
a
->
tp_dictoffset
==
b
->
tp_dictoffset
&&
child
->
tp_weaklistoffset
==
parent
->
tp_weaklistoffset
&&
a
->
tp_weaklistoffset
==
b
->
tp_weaklistoffset
&&
((
child
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)
==
((
a
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)
==
(
parent
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
))
&&
(
b
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)));
(
child
->
tp_dealloc
==
subtype_dealloc
||
child
->
tp_dealloc
==
parent
->
tp_dealloc
));
}
}
static
int
static
int
...
@@ -3453,6 +3457,10 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b)
...
@@ -3453,6 +3457,10 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b)
size
+=
sizeof
(
PyObject
*
);
size
+=
sizeof
(
PyObject
*
);
/* Check slots compliance */
/* Check slots compliance */
if
(
!
(
a
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
||
!
(
b
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
))
{
return
0
;
}
slots_a
=
((
PyHeapTypeObject
*
)
a
)
->
ht_slots
;
slots_a
=
((
PyHeapTypeObject
*
)
a
)
->
ht_slots
;
slots_b
=
((
PyHeapTypeObject
*
)
b
)
->
ht_slots
;
slots_b
=
((
PyHeapTypeObject
*
)
b
)
->
ht_slots
;
if
(
slots_a
&&
slots_b
)
{
if
(
slots_a
&&
slots_b
)
{
...
@@ -3468,9 +3476,7 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
...
@@ -3468,9 +3476,7 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
{
{
PyTypeObject
*
newbase
,
*
oldbase
;
PyTypeObject
*
newbase
,
*
oldbase
;
if
(
newto
->
tp_dealloc
!=
oldto
->
tp_dealloc
||
if
(
newto
->
tp_free
!=
oldto
->
tp_free
)
{
newto
->
tp_free
!=
oldto
->
tp_free
)
{
PyErr_Format
(
PyExc_TypeError
,
PyErr_Format
(
PyExc_TypeError
,
"%s assignment: "
"%s assignment: "
"'%s' deallocator differs from '%s'"
,
"'%s' deallocator differs from '%s'"
,
...
@@ -3479,11 +3485,21 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
...
@@ -3479,11 +3485,21 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
oldto
->
tp_name
);
oldto
->
tp_name
);
return
0
;
return
0
;
}
}
/*
It's tricky to tell if two arbitrary types are sufficiently compatible as
to be interchangeable; e.g., even if they have the same tp_basicsize, they
might have totally different struct fields. It's much easier to tell if a
type and its supertype are compatible; e.g., if they have the same
tp_basicsize, then that means they have identical fields. So to check
whether two arbitrary types are compatible, we first find the highest
supertype that each is compatible with, and then if those supertypes are
compatible then the original types must also be compatible.
*/
newbase
=
newto
;
newbase
=
newto
;
oldbase
=
oldto
;
oldbase
=
oldto
;
while
(
equiv_structs
(
newbase
,
newbase
->
tp_
base
))
while
(
compatible_with_tp_base
(
new
base
))
newbase
=
newbase
->
tp_base
;
newbase
=
newbase
->
tp_base
;
while
(
equiv_structs
(
oldbase
,
oldbase
->
tp_
base
))
while
(
compatible_with_tp_base
(
old
base
))
oldbase
=
oldbase
->
tp_base
;
oldbase
=
oldbase
->
tp_base
;
if
(
newbase
!=
oldbase
&&
if
(
newbase
!=
oldbase
&&
(
newbase
->
tp_base
!=
oldbase
->
tp_base
||
(
newbase
->
tp_base
!=
oldbase
->
tp_base
||
...
@@ -3518,17 +3534,12 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
...
@@ -3518,17 +3534,12 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
return
-
1
;
return
-
1
;
}
}
newto
=
(
PyTypeObject
*
)
value
;
newto
=
(
PyTypeObject
*
)
value
;
if
(
!
(
newto
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
||
!
(
oldto
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
))
{
PyErr_Format
(
PyExc_TypeError
,
"__class__ assignment: only for heap types"
);
return
-
1
;
}
if
(
compatible_for_assignment
(
oldto
,
newto
,
"__class__"
))
{
if
(
compatible_for_assignment
(
oldto
,
newto
,
"__class__"
))
{
Py_INCREF
(
newto
);
if
(
newto
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
Py_INCREF
(
newto
);
Py_TYPE
(
self
)
=
newto
;
Py_TYPE
(
self
)
=
newto
;
Py_DECREF
(
oldto
);
if
(
oldto
->
tp_flags
&
Py_TPFLAGS_HEAPTYPE
)
Py_DECREF
(
oldto
);
return
0
;
return
0
;
}
}
else
{
else
{
...
...
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