Skip to content

Commit 83f4c3f

Browse files
committed
Fix: check if PyModuleDef object was initialized
1 parent 9157632 commit 83f4c3f

File tree

1 file changed

+16
-0
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi

1 file changed

+16
-0
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.graalvm.collections.EconomicMap;
5858

5959
import com.oracle.graal.python.PythonLanguage;
60+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
6061
import com.oracle.graal.python.builtins.modules.PythonCextBuiltins;
6162
import com.oracle.graal.python.builtins.objects.PNone;
6263
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
@@ -82,10 +83,12 @@
8283
import com.oracle.graal.python.builtins.objects.module.PythonModule;
8384
import com.oracle.graal.python.nodes.ErrorMessages;
8485
import com.oracle.graal.python.nodes.IndirectCallNode;
86+
import com.oracle.graal.python.nodes.PRaiseNode;
8587
import com.oracle.graal.python.nodes.PRootNode;
8688
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
8789
import com.oracle.graal.python.nodes.call.GenericInvokeNode;
8890
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
91+
import com.oracle.graal.python.nodes.object.GetClassNode;
8992
import com.oracle.graal.python.runtime.AsyncHandler;
9093
import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
9194
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
@@ -959,6 +962,19 @@ public Object initCApiModule(Node location, Object llvmLibrary, String initFuncN
959962
Object result = AsPythonObjectNodeGen.getUncached().execute(ResolveHandleNodeGen.getUncached().execute(nativeResult));
960963
if (!(result instanceof PythonModule)) {
961964
// Multi-phase extension module initialization
965+
966+
/*
967+
* See 'importdl.c: _PyImport_LoadDynamicModuleWithSpec' before
968+
* 'PyModule_FromDefAndSpec' is called. The 'PyModule_FromDefAndSpec' would initialize
969+
* the module def as Python object but before that, CPython explicitly checks if the
970+
* init function did this initialization by calling 'PyModuleDef_Init' on it. So, we
971+
* must do it here because 'CreateModuleNode' should just ignore this case.
972+
*/
973+
Object clazz = GetClassNode.getUncached().execute(result);
974+
if (clazz == PNone.NO_VALUE) {
975+
throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.SystemError, "init function of %s returned uninitialized object", initFuncName);
976+
}
977+
962978
return CreateModuleNodeGen.getUncached().execute(context.getCApiContext(), spec, result);
963979
} else {
964980
((PythonModule) result).setAttribute(__FILE__, spec.path);

0 commit comments

Comments
 (0)