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
6b91a597
Unverified
Kaydet (Commit)
6b91a597
authored
Ara 20, 2017
tarafından
Serhiy Storchaka
Kaydeden (comit)
GitHub
Ara 20, 2017
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-32385: Clean up the C3 MRO algorithm implementation. (#4942)
Use tuples and raw arrays instead of lists.
üst
ca719ac4
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
64 additions
and
77 deletions
+64
-77
typeobject.c
Objects/typeobject.c
+64
-77
No files found.
Objects/typeobject.c
Dosyayı görüntüle @
6b91a597
...
@@ -1564,12 +1564,13 @@ call_maybe(PyObject *obj, _Py_Identifier *name,
...
@@ -1564,12 +1564,13 @@ call_maybe(PyObject *obj, _Py_Identifier *name,
*/
*/
static
int
static
int
tail_contains
(
PyObject
*
list
,
int
whence
,
PyObject
*
o
)
{
tail_contains
(
PyObject
*
tuple
,
int
whence
,
PyObject
*
o
)
{
Py_ssize_t
j
,
size
;
Py_ssize_t
j
,
size
;
size
=
Py
List_GET_SIZE
(
list
);
size
=
Py
Tuple_GET_SIZE
(
tuple
);
for
(
j
=
whence
+
1
;
j
<
size
;
j
++
)
{
for
(
j
=
whence
+
1
;
j
<
size
;
j
++
)
{
if
(
Py
List_GET_ITEM
(
list
,
j
)
==
o
)
if
(
Py
Tuple_GET_ITEM
(
tuple
,
j
)
==
o
)
return
1
;
return
1
;
}
}
return
0
;
return
0
;
...
@@ -1593,17 +1594,17 @@ class_name(PyObject *cls)
...
@@ -1593,17 +1594,17 @@ class_name(PyObject *cls)
}
}
static
int
static
int
check_duplicates
(
PyObject
*
list
)
check_duplicates
(
PyObject
*
tuple
)
{
{
Py_ssize_t
i
,
j
,
n
;
Py_ssize_t
i
,
j
,
n
;
/* Let's use a quadratic time algorithm,
/* Let's use a quadratic time algorithm,
assuming that the bases
list
s is short.
assuming that the bases
tuple
s is short.
*/
*/
n
=
Py
List_GET_SIZE
(
list
);
n
=
Py
Tuple_GET_SIZE
(
tuple
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyObject
*
o
=
Py
List_GET_ITEM
(
list
,
i
);
PyObject
*
o
=
Py
Tuple_GET_ITEM
(
tuple
,
i
);
for
(
j
=
i
+
1
;
j
<
n
;
j
++
)
{
for
(
j
=
i
+
1
;
j
<
n
;
j
++
)
{
if
(
Py
List_GET_ITEM
(
list
,
j
)
==
o
)
{
if
(
Py
Tuple_GET_ITEM
(
tuple
,
j
)
==
o
)
{
o
=
class_name
(
o
);
o
=
class_name
(
o
);
if
(
o
!=
NULL
)
{
if
(
o
!=
NULL
)
{
PyErr_Format
(
PyExc_TypeError
,
PyErr_Format
(
PyExc_TypeError
,
...
@@ -1631,19 +1632,18 @@ check_duplicates(PyObject *list)
...
@@ -1631,19 +1632,18 @@ check_duplicates(PyObject *list)
*/
*/
static
void
static
void
set_mro_error
(
PyObject
*
to_merg
e
,
int
*
remain
)
set_mro_error
(
PyObject
*
*
to_merge
,
Py_ssize_t
to_merge_siz
e
,
int
*
remain
)
{
{
Py_ssize_t
i
,
n
,
off
,
to_merge_size
;
Py_ssize_t
i
,
n
,
off
;
char
buf
[
1000
];
char
buf
[
1000
];
PyObject
*
k
,
*
v
;
PyObject
*
k
,
*
v
;
PyObject
*
set
=
PyDict_New
();
PyObject
*
set
=
PyDict_New
();
if
(
!
set
)
return
;
if
(
!
set
)
return
;
to_merge_size
=
PyList_GET_SIZE
(
to_merge
);
for
(
i
=
0
;
i
<
to_merge_size
;
i
++
)
{
for
(
i
=
0
;
i
<
to_merge_size
;
i
++
)
{
PyObject
*
L
=
PyList_GET_ITEM
(
to_merge
,
i
)
;
PyObject
*
L
=
to_merge
[
i
]
;
if
(
remain
[
i
]
<
Py
List
_GET_SIZE
(
L
))
{
if
(
remain
[
i
]
<
Py
Tuple
_GET_SIZE
(
L
))
{
PyObject
*
c
=
Py
List
_GET_ITEM
(
L
,
remain
[
i
]);
PyObject
*
c
=
Py
Tuple
_GET_ITEM
(
L
,
remain
[
i
]);
if
(
PyDict_SetItem
(
set
,
c
,
Py_None
)
<
0
)
{
if
(
PyDict_SetItem
(
set
,
c
,
Py_None
)
<
0
)
{
Py_DECREF
(
set
);
Py_DECREF
(
set
);
return
;
return
;
...
@@ -1676,19 +1676,17 @@ consistent method resolution\norder (MRO) for bases");
...
@@ -1676,19 +1676,17 @@ consistent method resolution\norder (MRO) for bases");
}
}
static
int
static
int
pmerge
(
PyObject
*
acc
,
PyObject
*
to_merg
e
)
pmerge
(
PyObject
*
acc
,
PyObject
**
to_merge
,
Py_ssize_t
to_merge_siz
e
)
{
{
int
res
=
0
;
int
res
=
0
;
Py_ssize_t
i
,
j
,
to_merge_size
,
empty_cnt
;
Py_ssize_t
i
,
j
,
empty_cnt
;
int
*
remain
;
int
*
remain
;
to_merge_size
=
PyList_GET_SIZE
(
to_merge
);
/* remain stores an index into each sublist of to_merge.
/* remain stores an index into each sublist of to_merge.
remain[i] is the index of the next base in to_merge[i]
remain[i] is the index of the next base in to_merge[i]
that is not included in acc.
that is not included in acc.
*/
*/
remain
=
(
int
*
)
PyMem_MALLOC
(
SIZEOF_INT
*
to_merge_size
);
remain
=
PyMem_New
(
int
,
to_merge_size
);
if
(
remain
==
NULL
)
{
if
(
remain
==
NULL
)
{
PyErr_NoMemory
();
PyErr_NoMemory
();
return
-
1
;
return
-
1
;
...
@@ -1701,9 +1699,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
...
@@ -1701,9 +1699,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
for
(
i
=
0
;
i
<
to_merge_size
;
i
++
)
{
for
(
i
=
0
;
i
<
to_merge_size
;
i
++
)
{
PyObject
*
candidate
;
PyObject
*
candidate
;
PyObject
*
cur_
list
=
PyList_GET_ITEM
(
to_merge
,
i
)
;
PyObject
*
cur_
tuple
=
to_merge
[
i
]
;
if
(
remain
[
i
]
>=
Py
List_GET_SIZE
(
cur_list
))
{
if
(
remain
[
i
]
>=
Py
Tuple_GET_SIZE
(
cur_tuple
))
{
empty_cnt
++
;
empty_cnt
++
;
continue
;
continue
;
}
}
...
@@ -1715,9 +1713,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
...
@@ -1715,9 +1713,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
of the earliest direct superclass of the new class.
of the earliest direct superclass of the new class.
*/
*/
candidate
=
Py
List_GET_ITEM
(
cur_list
,
remain
[
i
]);
candidate
=
Py
Tuple_GET_ITEM
(
cur_tuple
,
remain
[
i
]);
for
(
j
=
0
;
j
<
to_merge_size
;
j
++
)
{
for
(
j
=
0
;
j
<
to_merge_size
;
j
++
)
{
PyObject
*
j_lst
=
PyList_GET_ITEM
(
to_merge
,
j
)
;
PyObject
*
j_lst
=
to_merge
[
j
]
;
if
(
tail_contains
(
j_lst
,
remain
[
j
],
candidate
))
if
(
tail_contains
(
j_lst
,
remain
[
j
],
candidate
))
goto
skip
;
/* continue outer loop */
goto
skip
;
/* continue outer loop */
}
}
...
@@ -1726,9 +1724,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
...
@@ -1726,9 +1724,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
goto
out
;
goto
out
;
for
(
j
=
0
;
j
<
to_merge_size
;
j
++
)
{
for
(
j
=
0
;
j
<
to_merge_size
;
j
++
)
{
PyObject
*
j_lst
=
PyList_GET_ITEM
(
to_merge
,
j
)
;
PyObject
*
j_lst
=
to_merge
[
j
]
;
if
(
remain
[
j
]
<
Py
List
_GET_SIZE
(
j_lst
)
&&
if
(
remain
[
j
]
<
Py
Tuple
_GET_SIZE
(
j_lst
)
&&
Py
List
_GET_ITEM
(
j_lst
,
remain
[
j
])
==
candidate
)
{
Py
Tuple
_GET_ITEM
(
j_lst
,
remain
[
j
])
==
candidate
)
{
remain
[
j
]
++
;
remain
[
j
]
++
;
}
}
}
}
...
@@ -1737,12 +1735,12 @@ pmerge(PyObject *acc, PyObject* to_merge)
...
@@ -1737,12 +1735,12 @@ pmerge(PyObject *acc, PyObject* to_merge)
}
}
if
(
empty_cnt
!=
to_merge_size
)
{
if
(
empty_cnt
!=
to_merge_size
)
{
set_mro_error
(
to_merge
,
remain
);
set_mro_error
(
to_merge
,
to_merge_size
,
remain
);
res
=
-
1
;
res
=
-
1
;
}
}
out:
out:
PyMem_
FREE
(
remain
);
PyMem_
Del
(
remain
);
return
res
;
return
res
;
}
}
...
@@ -1750,10 +1748,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
...
@@ -1750,10 +1748,9 @@ pmerge(PyObject *acc, PyObject* to_merge)
static
PyObject
*
static
PyObject
*
mro_implementation
(
PyTypeObject
*
type
)
mro_implementation
(
PyTypeObject
*
type
)
{
{
PyObject
*
result
=
NULL
;
PyObject
*
result
;
PyObject
*
bases
;
PyObject
*
bases
;
PyObject
*
to_merge
,
*
bases_aslist
;
PyObject
**
to_merge
;
int
res
;
Py_ssize_t
i
,
n
;
Py_ssize_t
i
,
n
;
if
(
type
->
tp_dict
==
NULL
)
{
if
(
type
->
tp_dict
==
NULL
)
{
...
@@ -1762,21 +1759,25 @@ mro_implementation(PyTypeObject *type)
...
@@ -1762,21 +1759,25 @@ mro_implementation(PyTypeObject *type)
}
}
bases
=
type
->
tp_bases
;
bases
=
type
->
tp_bases
;
assert
(
PyTuple_Check
(
bases
));
n
=
PyTuple_GET_SIZE
(
bases
);
n
=
PyTuple_GET_SIZE
(
bases
);
if
(
n
==
1
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* Fast path: if there is a single base, constructing the MRO
PyTypeObject
*
base
=
(
PyTypeObject
*
)
PyTuple_GET_ITEM
(
bases
,
i
);
* is trivial.
*/
PyTypeObject
*
base
=
(
PyTypeObject
*
)
PyTuple_GET_ITEM
(
bases
,
0
);
Py_ssize_t
k
;
if
(
base
->
tp_mro
==
NULL
)
{
if
(
base
->
tp_mro
==
NULL
)
{
PyErr_Format
(
PyExc_TypeError
,
PyErr_Format
(
PyExc_TypeError
,
"Cannot extend an incomplete type '%.100s'"
,
"Cannot extend an incomplete type '%.100s'"
,
base
->
tp_name
);
base
->
tp_name
);
return
NULL
;
return
NULL
;
}
}
k
=
PyTuple_GET_SIZE
(
base
->
tp_mro
);
assert
(
PyTuple_Check
(
base
->
tp_mro
));
}
if
(
n
==
1
)
{
/* Fast path: if there is a single base, constructing the MRO
* is trivial.
*/
PyTypeObject
*
base
=
(
PyTypeObject
*
)
PyTuple_GET_ITEM
(
bases
,
0
);
Py_ssize_t
k
=
PyTuple_GET_SIZE
(
base
->
tp_mro
);
result
=
PyTuple_New
(
k
+
1
);
result
=
PyTuple_New
(
k
+
1
);
if
(
result
==
NULL
)
{
if
(
result
==
NULL
)
{
return
NULL
;
return
NULL
;
...
@@ -1791,59 +1792,45 @@ mro_implementation(PyTypeObject *type)
...
@@ -1791,59 +1792,45 @@ mro_implementation(PyTypeObject *type)
return
result
;
return
result
;
}
}
/* This is just a basic sanity check. */
if
(
check_duplicates
(
bases
)
<
0
)
{
return
NULL
;
}
/* Find a superclass linearization that honors the constraints
/* Find a superclass linearization that honors the constraints
of the explicit
list
s of bases and the constraints implied by
of the explicit
tuple
s of bases and the constraints implied by
each base class.
each base class.
to_merge is a
list of lists, where each list
is a superclass
to_merge is a
n array of tuples, where each tuple
is a superclass
linearization implied by a base class. The last element of
linearization implied by a base class. The last element of
to_merge is the declared
list
of bases.
to_merge is the declared
tuple
of bases.
*/
*/
to_merge
=
PyList_New
(
n
+
1
);
to_merge
=
PyMem_New
(
PyObject
*
,
n
+
1
);
if
(
to_merge
==
NULL
)
if
(
to_merge
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
return
NULL
;
}
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyTypeObject
*
base
;
PyTypeObject
*
base
=
(
PyTypeObject
*
)
PyTuple_GET_ITEM
(
bases
,
i
);
PyObject
*
base_mro_aslist
;
to_merge
[
i
]
=
base
->
tp_mro
;
base
=
(
PyTypeObject
*
)
PyTuple_GET_ITEM
(
bases
,
i
);
if
(
base
->
tp_mro
==
NULL
)
{
PyErr_Format
(
PyExc_TypeError
,
"Cannot extend an incomplete type '%.100s'"
,
base
->
tp_name
);
goto
out
;
}
base_mro_aslist
=
PySequence_List
(
base
->
tp_mro
);
if
(
base_mro_aslist
==
NULL
)
goto
out
;
PyList_SET_ITEM
(
to_merge
,
i
,
base_mro_aslist
);
}
}
to_merge
[
n
]
=
bases
;
bases_aslist
=
PySequence_List
(
bases
);
result
=
PyList_New
(
1
);
if
(
bases_aslist
==
NULL
)
if
(
result
==
NULL
)
{
goto
out
;
PyMem_Del
(
to_merge
);
/* This is just a basic sanity check. */
return
NULL
;
if
(
check_duplicates
(
bases_aslist
)
<
0
)
{
Py_DECREF
(
bases_aslist
);
goto
out
;
}
}
PyList_SET_ITEM
(
to_merge
,
n
,
bases_aslist
);
result
=
Py_BuildValue
(
"[O]"
,
(
PyObject
*
)
type
);
if
(
result
==
NULL
)
goto
out
;
res
=
pmerge
(
result
,
to_merge
);
Py_INCREF
(
type
);
if
(
res
<
0
)
PyList_SET_ITEM
(
result
,
0
,
(
PyObject
*
)
type
);
if
(
pmerge
(
result
,
to_merge
,
n
+
1
)
<
0
)
{
Py_CLEAR
(
result
);
Py_CLEAR
(
result
);
}
out:
PyMem_Del
(
to_merge
);
Py_DECREF
(
to_merge
);
return
result
;
return
result
;
}
}
...
...
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