Skip to content

Commit ff7e755

Browse files
committed
[GR-47071] Support lazy type initalization during subclass creation
PullRequest: graalpython/2861
2 parents d25e526 + 707bfc2 commit ff7e755

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,12 @@ PyAPI_FUNC(void) truffle_set_tp_flags(PyTypeObject* type, unsigned long flags) {
13501350
type->tp_flags = flags;
13511351
}
13521352

1353+
PyAPI_FUNC(void) truffle_check_type_ready(PyTypeObject* type) {
1354+
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
1355+
PyType_Ready(type);
1356+
}
1357+
}
1358+
13531359
PyAPI_FUNC(int) truffle_BASETYPE_check(PyObject* type) {
13541360
return PyType_HasFeature(Py_TYPE(type), Py_TPFLAGS_BASETYPE);
13551361
}

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_object.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,34 @@ def test_inheret_numbers_slots(self):
305305
assert X.B_has_add_slot()
306306
assert Y.E_has_add_slot()
307307

308+
def test_managed_class_with_native_base(self):
309+
NativeModule = CPyExtType("NativeModule_",
310+
'''
311+
PyTypeObject NativeBase_Type = {
312+
PyVarObject_HEAD_INIT(&PyType_Type, 0)
313+
.tp_name = "NativeModule_.NativeBase",
314+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
315+
.tp_base = &PyModule_Type,
316+
};
317+
318+
static PyObject* get_NativeBase_type(PyObject* cls) {
319+
return (PyObject*) &NativeBase_Type;
320+
}
321+
322+
''',
323+
tp_methods='''{"get_NativeBase_type", (PyCFunction)get_NativeBase_type, METH_NOARGS | METH_CLASS, ""}''',
324+
ready_code='''
325+
/* testing lazy type initialization */
326+
// if (PyType_Ready(&NativeBase_Type) < 0)
327+
// return NULL;
328+
''',
329+
)
330+
NativeBase = NativeModule.get_NativeBase_type()
331+
assert NativeBase
332+
class ManagedType(NativeBase):
333+
def __init__(self):
334+
super(ManagedType, self).__init__("DummyModuleName")
335+
assert ManagedType()
308336

309337
def test_index(self):
310338
TestIndex = CPyExtType("TestIndex",

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
313313
FUN_UNICODE_SUBTYPE_NEW("unicode_subtype_new"),
314314
FUN_CHECK_BASESIZE_FOR_GETSTATE("tuffle_check_basesize_for_getstate"),
315315
FUN_TRUFFLE_SET_TP_FLAGS("truffle_set_tp_flags"),
316+
FUN_TRUFFLE_CHECK_TYPE_READY("truffle_check_type_ready"),
316317

317318
/* PyDateTime_CAPI */
318319

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535

3636
import com.oracle.graal.python.PythonLanguage;
3737
import com.oracle.graal.python.builtins.objects.PNone;
38+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
39+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToSulongNode;
40+
import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
3841
import com.oracle.graal.python.builtins.objects.cext.capi.PythonClassNativeWrapper;
3942
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4043
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
@@ -267,6 +270,10 @@ private void unsafeSetSuperClass(PythonAbstractClass... newBaseClasses) {
267270
}
268271
for (PythonAbstractClass base : getBaseClasses()) {
269272
if (base != null) {
273+
if (PGuards.isNativeClass(base)) {
274+
Object nativeBase = ToSulongNode.getUncached().execute(base);
275+
PCallCapiFunction.getUncached().call(NativeCAPISymbol.FUN_TRUFFLE_CHECK_TYPE_READY, nativeBase);
276+
}
270277
GetSubclassesNode.getUncached().execute(base).add(this);
271278
}
272279
}

0 commit comments

Comments
 (0)