|
57 | 57 | import org.graalvm.collections.EconomicMap;
|
58 | 58 |
|
59 | 59 | import com.oracle.graal.python.PythonLanguage;
|
| 60 | +import com.oracle.graal.python.builtins.PythonBuiltinClassType; |
60 | 61 | import com.oracle.graal.python.builtins.modules.PythonCextBuiltins;
|
61 | 62 | import com.oracle.graal.python.builtins.objects.PNone;
|
62 | 63 | import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
|
|
82 | 83 | import com.oracle.graal.python.builtins.objects.module.PythonModule;
|
83 | 84 | import com.oracle.graal.python.nodes.ErrorMessages;
|
84 | 85 | import com.oracle.graal.python.nodes.IndirectCallNode;
|
| 86 | +import com.oracle.graal.python.nodes.PRaiseNode; |
85 | 87 | import com.oracle.graal.python.nodes.PRootNode;
|
86 | 88 | import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
|
87 | 89 | import com.oracle.graal.python.nodes.call.GenericInvokeNode;
|
88 | 90 | import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
|
| 91 | +import com.oracle.graal.python.nodes.object.GetClassNode; |
89 | 92 | import com.oracle.graal.python.runtime.AsyncHandler;
|
90 | 93 | import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
|
91 | 94 | import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
|
@@ -959,6 +962,19 @@ public Object initCApiModule(Node location, Object llvmLibrary, String initFuncN
|
959 | 962 | Object result = AsPythonObjectNodeGen.getUncached().execute(ResolveHandleNodeGen.getUncached().execute(nativeResult));
|
960 | 963 | if (!(result instanceof PythonModule)) {
|
961 | 964 | // 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 | + |
962 | 978 | return CreateModuleNodeGen.getUncached().execute(context.getCApiContext(), spec, result);
|
963 | 979 | } else {
|
964 | 980 | ((PythonModule) result).setAttribute(__FILE__, spec.path);
|
|
0 commit comments