Skip to content

Commit 5b4b3f2

Browse files
committed
Cleanup error handling and reporting when loading C API/Exts.
1 parent dc282dc commit 5b4b3f2

File tree

2 files changed

+38
-26
lines changed

2 files changed

+38
-26
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4344
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FILE__;
4445
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ImportError;
4546
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
@@ -78,12 +79,12 @@
7879
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
7980
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
8081
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
82+
import com.oracle.graal.python.nodes.statement.ExceptionHandlingStatementNode;
8183
import com.oracle.graal.python.parser.sst.SerializationUtils;
8284
import com.oracle.graal.python.runtime.ExecutionContext.ForeignCallContext;
8385
import com.oracle.graal.python.runtime.PythonContext;
8486
import com.oracle.graal.python.runtime.PythonOptions;
8587
import com.oracle.graal.python.runtime.exception.PException;
86-
import com.oracle.graal.python.runtime.exception.PythonErrorType;
8788
import com.oracle.truffle.api.CallTarget;
8889
import com.oracle.truffle.api.CompilerDirectives;
8990
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -230,17 +231,17 @@ private Object loadDynamicModuleWithSpec(String name, String path, InteropLibrar
230231
CallTarget callTarget = env.parseInternal(Source.newBuilder(LLVM_LANGUAGE, context.getPublicTruffleFileRelaxed(path, extSuffix)).build());
231232
sulongLibrary = (TruffleObject) callTarget.call();
232233
} catch (SecurityException | IOException e) {
233-
LOGGER.severe(() -> String.format("cannot load C extension '%s'", path));
234234
logJavaException(e);
235-
throw raise(ImportError, ErrorMessages.CANNOT_LOAD_M, path, e);
235+
throw raise(ImportError, wrapJavaException(e), ErrorMessages.CANNOT_LOAD_M, path, e);
236236
} catch (RuntimeException e) {
237237
throw reportImportError(e, path);
238238
}
239239
TruffleObject pyinitFunc;
240240
try {
241241
pyinitFunc = (TruffleObject) interop.readMember(sulongLibrary, "PyInit_" + basename);
242-
} catch (UnknownIdentifierException | UnsupportedMessageException e1) {
243-
throw raise(ImportError, ErrorMessages.NO_FUNCTION_FOUND, "PyInit_", basename, path);
242+
} catch (UnknownIdentifierException | UnsupportedMessageException e) {
243+
logJavaException(e);
244+
throw raise(ImportError, wrapJavaException(e), ErrorMessages.NO_FUNCTION_FOUND, "PyInit_", basename, path);
244245
}
245246
try {
246247
Object nativeResult = interop.execute(pyinitFunc);
@@ -250,7 +251,7 @@ private Object loadDynamicModuleWithSpec(String name, String path, InteropLibrar
250251
if (!(result instanceof PythonModule)) {
251252
// PyModuleDef_Init(pyModuleDef)
252253
// TODO: PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
253-
throw raise(PythonErrorType.NotImplementedError, "multi-phase init of extension module %s", name);
254+
throw raise(NotImplementedError, "multi-phase init of extension module %s", name);
254255
} else {
255256
((PythonObject) result).setAttribute(__FILE__, path);
256257
// TODO: _PyImport_FixupExtensionObject(result, name, path, sys.modules)
@@ -259,8 +260,8 @@ private Object loadDynamicModuleWithSpec(String name, String path, InteropLibrar
259260
return result;
260261
}
261262
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
262-
e.printStackTrace();
263-
throw raise(ImportError, ErrorMessages.CANNOT_INITIALIZE_WITH, "PyInit_", path, basename);
263+
logJavaException(e);
264+
throw raise(ImportError, wrapJavaException(e), ErrorMessages.CANNOT_INITIALIZE_WITH, "PyInit_", path, basename);
264265
} catch (RuntimeException e) {
265266
throw reportImportError(e, path);
266267
}
@@ -276,31 +277,35 @@ private void ensureCapiWasLoaded() {
276277
String libPythonName = "libpython" + ExtensionSuffixesNode.getSoAbi(context);
277278
TruffleFile homePath = env.getInternalTruffleFile(context.getCAPIHome());
278279
TruffleFile capiFile = homePath.resolve(libPythonName);
279-
Object capi = null;
280+
Object capi;
280281
try {
281282
SourceBuilder capiSrcBuilder = Source.newBuilder(LLVM_LANGUAGE, capiFile);
282283
if (!context.getLanguage().getEngineOption(PythonOptions.ExposeInternalSources)) {
283284
capiSrcBuilder.internal(true);
284285
}
285286
capi = context.getEnv().parseInternal(capiSrcBuilder.build()).call();
286287
} catch (IOException | RuntimeException e) {
287-
LOGGER.severe(() -> String.format(ErrorMessages.CAPI_LOAD_ERROR, capiFile.getAbsoluteFile().getPath()));
288-
LOGGER.severe(() -> "Original error was: " + e);
289-
e.printStackTrace();
290-
throw raise(PythonErrorType.ImportError, ErrorMessages.CAPI_LOAD_ERROR, capiFile.getAbsoluteFile().getPath());
288+
logJavaException(e);
289+
throw raise(ImportError, wrapJavaException(e), ErrorMessages.CAPI_LOAD_ERROR, capiFile.getAbsoluteFile().getPath());
290+
}
291+
try {
292+
// call into Python to initialize python_cext module globals
293+
ReadAttributeFromObjectNode readNode = ReadAttributeFromObjectNode.getUncached();
294+
PythonModule builtinModule = context.getCore().lookupBuiltinModule(PythonCextBuiltins.PYTHON_CEXT);
295+
296+
CallUnaryMethodNode callNode = CallUnaryMethodNode.getUncached();
297+
callNode.executeObject(null, readNode.execute(builtinModule, INITIALIZE_CAPI), capi);
298+
context.setCapiWasLoaded(capi);
299+
callNode.executeObject(null, readNode.execute(builtinModule, RUN_CAPI_LOADED_HOOKS), capi);
300+
301+
// initialization needs to be finished already but load memoryview
302+
// implementation
303+
// immediately
304+
callNode.executeObject(null, readNode.execute(builtinModule, IMPORT_NATIVE_MEMORYVIEW), capi);
305+
} catch (RuntimeException e) {
306+
logJavaException(e);
307+
throw raise(ImportError, wrapJavaException(e), ErrorMessages.CAPI_LOAD_ERROR, capiFile.getAbsoluteFile().getPath());
291308
}
292-
// call into Python to initialize python_cext module globals
293-
ReadAttributeFromObjectNode readNode = ReadAttributeFromObjectNode.getUncached();
294-
PythonModule builtinModule = context.getCore().lookupBuiltinModule(PythonCextBuiltins.PYTHON_CEXT);
295-
296-
CallUnaryMethodNode callNode = CallUnaryMethodNode.getUncached();
297-
callNode.executeObject(null, readNode.execute(builtinModule, INITIALIZE_CAPI), capi);
298-
context.setCapiWasLoaded(capi);
299-
callNode.executeObject(null, readNode.execute(builtinModule, RUN_CAPI_LOADED_HOOKS), capi);
300-
301-
// initialization needs to be finished already but load memoryview implementation
302-
// immediately
303-
callNode.executeObject(null, readNode.execute(builtinModule, IMPORT_NATIVE_MEMORYVIEW), capi);
304309
}
305310
}
306311

@@ -316,6 +321,12 @@ private static String getJavaStacktrace(Exception e) {
316321
return sw.toString();
317322
}
318323

324+
@TruffleBoundary
325+
private PBaseException wrapJavaException(Throwable e) {
326+
PBaseException excObject = factory().createBaseException(SystemError, e.getMessage(), new Object[0]);
327+
return ExceptionHandlingStatementNode.wrapJavaException(e, this, excObject).getEscapedException();
328+
}
329+
319330
private SetItemNode getSetItemNode() {
320331
if (setItemNode == null) {
321332
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -466,7 +477,7 @@ public Object run(PCode code, String path) {
466477
}
467478
}
468479

469-
@Builtin(name = "extension_suffixes", minNumOfPositionalArgs = 0)
480+
@Builtin(name = "extension_suffixes")
470481
@GenerateNodeFactory
471482
public abstract static class ExtensionSuffixesNode extends PythonBuiltinNode {
472483
@Specialization

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,4 +523,5 @@ public abstract class ErrorMessages {
523523
public static final String PRECISION_NOT_ALLOWED_FOR_INT = "Precision not allowed in integer format specifier";
524524
public static final String SIGN_NOT_ALLOWED_WITH_C_FOR_INT = "Sign not allowed with integer format specifier 'c'";
525525
public static final String CAPI_LOAD_ERROR = "Could not load C API from %s.";
526+
public static final String NATIVE_ACCESS_NOT_ALLOWED = "Cannot run any C extensions because native access is not allowed.\n";
526527
}

0 commit comments

Comments
 (0)