Skip to content

Commit 3e3980d

Browse files
authored
[mypyc] Move some functions to pythonsupport.c (#20555)
Followup to #20460 (comment) It's not possible to use `mypyc_interned_str.<name>` in header files. Move some functions from `pythonsupport.h` to `pythonsupport.c`.
1 parent ba3e064 commit 3e3980d

2 files changed

Lines changed: 105 additions & 102 deletions

File tree

mypyc/lib-rt/pythonsupport.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,109 @@
55

66
#include "pythonsupport.h"
77

8+
/////////////////////////////////////////
9+
// Adapted from bltinmodule.c in Python 3.7.0
10+
PyObject*
11+
update_bases(PyObject *bases)
12+
{
13+
Py_ssize_t i, j;
14+
PyObject *base, *meth, *new_base, *result, *new_bases = NULL;
15+
PyObject *stack[1] = {bases};
16+
assert(PyTuple_Check(bases));
17+
18+
Py_ssize_t nargs = PyTuple_GET_SIZE(bases);
19+
for (i = 0; i < nargs; i++) {
20+
base = PyTuple_GET_ITEM(bases, i);
21+
if (PyType_Check(base)) {
22+
if (new_bases) {
23+
/* If we already have made a replacement, then we append every normal base,
24+
otherwise just skip it. */
25+
if (PyList_Append(new_bases, base) < 0) {
26+
goto error;
27+
}
28+
}
29+
continue;
30+
}
31+
if (PyObject_GetOptionalAttr(base, mypyc_interned_str.__mro_entries__, &meth) < 0) {
32+
goto error;
33+
}
34+
if (!meth) {
35+
if (new_bases) {
36+
if (PyList_Append(new_bases, base) < 0) {
37+
goto error;
38+
}
39+
}
40+
continue;
41+
}
42+
new_base = PyObject_Vectorcall(meth, stack, 1, NULL);
43+
Py_DECREF(meth);
44+
if (!new_base) {
45+
goto error;
46+
}
47+
if (!PyTuple_Check(new_base)) {
48+
PyErr_SetString(PyExc_TypeError,
49+
"__mro_entries__ must return a tuple");
50+
Py_DECREF(new_base);
51+
goto error;
52+
}
53+
if (!new_bases) {
54+
/* If this is a first successful replacement, create new_bases list and
55+
copy previously encountered bases. */
56+
if (!(new_bases = PyList_New(i))) {
57+
goto error;
58+
}
59+
for (j = 0; j < i; j++) {
60+
base = PyTuple_GET_ITEM(bases, j);
61+
PyList_SET_ITEM(new_bases, j, base);
62+
Py_INCREF(base);
63+
}
64+
}
65+
j = PyList_GET_SIZE(new_bases);
66+
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
67+
goto error;
68+
}
69+
Py_DECREF(new_base);
70+
}
71+
if (!new_bases) {
72+
return bases;
73+
}
74+
result = PyList_AsTuple(new_bases);
75+
Py_DECREF(new_bases);
76+
return result;
77+
78+
error:
79+
Py_XDECREF(new_bases);
80+
return NULL;
81+
}
82+
83+
// From Python 3.7's typeobject.c
84+
int
85+
init_subclass(PyTypeObject *type, PyObject *kwds)
86+
{
87+
PyObject *super, *func, *result;
88+
PyObject *args[2] = {(PyObject *)type, (PyObject *)type};
89+
90+
super = PyObject_Vectorcall((PyObject *)&PySuper_Type, args, 2, NULL);
91+
if (super == NULL) {
92+
return -1;
93+
}
94+
95+
func = PyObject_GetAttr(super, mypyc_interned_str.__init_subclass__);
96+
Py_DECREF(super);
97+
if (func == NULL) {
98+
return -1;
99+
}
100+
101+
result = _PyObject_FastCallDict(func, NULL, 0, kwds);
102+
Py_DECREF(func);
103+
if (result == NULL) {
104+
return -1;
105+
}
106+
107+
Py_DECREF(result);
108+
return 0;
109+
}
110+
8111
#if CPY_3_12_FEATURES
9112

10113
// Slow path of CPyLong_AsSsize_tAndOverflow (non-inlined)

mypyc/lib-rt/pythonsupport.h

Lines changed: 2 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -34,108 +34,8 @@ extern "C" {
3434
} // why isn't emacs smart enough to not indent this
3535
#endif
3636

37-
/////////////////////////////////////////
38-
// Adapted from bltinmodule.c in Python 3.7.0
39-
static PyObject*
40-
update_bases(PyObject *bases)
41-
{
42-
Py_ssize_t i, j;
43-
PyObject *base, *meth, *new_base, *result, *new_bases = NULL;
44-
PyObject *stack[1] = {bases};
45-
assert(PyTuple_Check(bases));
46-
47-
Py_ssize_t nargs = PyTuple_GET_SIZE(bases);
48-
for (i = 0; i < nargs; i++) {
49-
base = PyTuple_GET_ITEM(bases, i);
50-
if (PyType_Check(base)) {
51-
if (new_bases) {
52-
/* If we already have made a replacement, then we append every normal base,
53-
otherwise just skip it. */
54-
if (PyList_Append(new_bases, base) < 0) {
55-
goto error;
56-
}
57-
}
58-
continue;
59-
}
60-
if (PyObject_GetOptionalAttrString(base, "__mro_entries__", &meth) < 0) {
61-
goto error;
62-
}
63-
if (!meth) {
64-
if (new_bases) {
65-
if (PyList_Append(new_bases, base) < 0) {
66-
goto error;
67-
}
68-
}
69-
continue;
70-
}
71-
new_base = PyObject_Vectorcall(meth, stack, 1, NULL);
72-
Py_DECREF(meth);
73-
if (!new_base) {
74-
goto error;
75-
}
76-
if (!PyTuple_Check(new_base)) {
77-
PyErr_SetString(PyExc_TypeError,
78-
"__mro_entries__ must return a tuple");
79-
Py_DECREF(new_base);
80-
goto error;
81-
}
82-
if (!new_bases) {
83-
/* If this is a first successful replacement, create new_bases list and
84-
copy previously encountered bases. */
85-
if (!(new_bases = PyList_New(i))) {
86-
goto error;
87-
}
88-
for (j = 0; j < i; j++) {
89-
base = PyTuple_GET_ITEM(bases, j);
90-
PyList_SET_ITEM(new_bases, j, base);
91-
Py_INCREF(base);
92-
}
93-
}
94-
j = PyList_GET_SIZE(new_bases);
95-
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
96-
goto error;
97-
}
98-
Py_DECREF(new_base);
99-
}
100-
if (!new_bases) {
101-
return bases;
102-
}
103-
result = PyList_AsTuple(new_bases);
104-
Py_DECREF(new_bases);
105-
return result;
106-
107-
error:
108-
Py_XDECREF(new_bases);
109-
return NULL;
110-
}
111-
112-
// From Python 3.7's typeobject.c
113-
static int
114-
init_subclass(PyTypeObject *type, PyObject *kwds)
115-
{
116-
PyObject *super, *func, *result;
117-
PyObject *args[2] = {(PyObject *)type, (PyObject *)type};
118-
119-
super = PyObject_Vectorcall((PyObject *)&PySuper_Type, args, 2, NULL);
120-
if (super == NULL) {
121-
return -1;
122-
}
123-
124-
func = PyObject_GetAttrString(super, "__init_subclass__");
125-
Py_DECREF(super);
126-
if (func == NULL) {
127-
return -1;
128-
}
129-
130-
result = _PyObject_FastCallDict(func, NULL, 0, kwds);
131-
Py_DECREF(func);
132-
if (result == NULL) {
133-
return -1;
134-
}
135-
136-
Py_DECREF(result);
137-
return 0;
138-
}
37+
PyObject* update_bases(PyObject *bases);
38+
int init_subclass(PyTypeObject *type, PyObject *kwds);
13939

14040
Py_ssize_t
14141
CPyLong_AsSsize_tAndOverflow_(PyObject *vv, int *overflow);

0 commit comments

Comments
 (0)