Skip to content

Commit 774dc24

Browse files
committed
[GR-38116] Minor fixes observed during experiments with sandboxed embedding usecase
PullRequest: graalpython/2228
2 parents 31f43bc + faaadb5 commit 774dc24

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

docs/user/Packages.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,47 @@ Note that to try extensions on GraalVM's Python runtime, you have to download, b
4343
### Using `pip`
4444

4545
The `pip` package installer is available and working when using a `venv`.
46+
47+
### Including packages in a Java application
48+
49+
When using Python from Java via the GraalVM embedder APIs, a bit of preparationis required to make packages available to the runtime.
50+
After a venv is created and any desired packages are installed, this venv is made available to the Java embedded Python by setting a context option.
51+
A good idea is to include the entire venv folder as a resource, and use Java's resource API:
52+
53+
```java
54+
String venvExePath = getClass().
55+
getClassLoader().
56+
getResource(Paths.get("venv", "bin", "graalpython").toString()).
57+
getPath();
58+
59+
Context ctx = Context.newBuilder("python").
60+
allowIO(true).
61+
option("python.Executable", venvExePath).
62+
build();
63+
64+
ctx.eval("python", "import site");
65+
```
66+
67+
The initial `import site` loads the Python standard library module `site`, which sets up the library paths.
68+
To do so, it uses the path of the currently running Python executable.
69+
For a language like Python, which is built around the filesystem, this makes sense, but in our Java embedding context, we do not have a Python executable running.
70+
This is what the `python.Executable` option is for: it reports which executable _would be_ running if we were running Python directly inside our venv.
71+
That is enough to make the machinery work and any packages inside the venv available to the embedded Python in Java.
72+
73+
A simple venv is already quite heavy, because it comes with the machinery to install more packages.
74+
For a Java distribution, we can strip the venv down somewhat without much trouble.
75+
Just run these inside the top-level venv directory:
76+
```shell
77+
find . -type d -name "__pycache__" -exec rm -rf "{}" ";"
78+
rmdir include
79+
rm bin/*
80+
rmdir bin
81+
rm lib/python3.*/site-packages/easy_install.py
82+
rm -rf lib/python3.*/site-packages/pip*
83+
```
84+
85+
Some packages may require the following, but most do not, so you can also remove these, but be aware that it _may_ break a few packages:
86+
```shell
87+
rm -rf lib/python3.*/site-packages/setuptools*
88+
rm -rf lib/python3.*/site-packages/pkg_resources*
89+
```

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -938,10 +938,6 @@ public static boolean isPointerToPrimitive(LLVMType llvmType) {
938938
@TruffleBoundary
939939
public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, String name, String path) throws IOException, ImportException, ApiInitException {
940940
if (!context.hasCApiContext()) {
941-
if (!context.getEnv().isNativeAccessAllowed()) {
942-
throw new ImportException(null, name, path, ErrorMessages.NATIVE_ACCESS_NOT_ALLOWED);
943-
}
944-
945941
Env env = context.getEnv();
946942

947943
String libPythonName = "libpython" + context.getSoAbi();
@@ -968,6 +964,9 @@ public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context,
968964
*/
969965
throw e.getExceptionForReraise();
970966
} catch (RuntimeException e) {
967+
if (!context.getEnv().isNativeAccessAllowed()) {
968+
throw new ImportException(null, name, path, ErrorMessages.NATIVE_ACCESS_NOT_ALLOWED);
969+
}
971970
throw new ApiInitException(wrapJavaException(e, node), name, ErrorMessages.CAPI_LOAD_ERROR, capiFile.getAbsoluteFile().getPath());
972971
}
973972
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ private static long[] unixStat(TruffleFile file, LinkOption... linkOptions) thro
975975
LAST_ACCESS_TIME,
976976
LAST_MODIFIED_TIME,
977977
UNIX_CTIME), linkOptions);
978-
return setTimestamps(attributes, new long[]{
978+
return setTimestamps(attributes, UNIX_CTIME, new long[]{
979979
attributes.get(UNIX_MODE),
980980
attributes.get(UNIX_INODE),
981981
attributes.get(UNIX_DEV),
@@ -1001,7 +1001,7 @@ private long[] posixStat(TruffleFile file, LinkOption... linkOptions) throws IOE
10011001
UNIX_GROUP,
10021002
UNIX_PERMISSIONS), linkOptions);
10031003
final Set<PosixFilePermission> posixFilePermissions = attributes.get(UNIX_PERMISSIONS);
1004-
return setTimestamps(attributes, new long[]{
1004+
return setTimestamps(attributes, CREATION_TIME, new long[]{
10051005
posixPermissionsToMode(fileTypeBitsFromAttributes(attributes), posixFilePermissions),
10061006
getEmulatedInode(file), // ino
10071007
0, // dev
@@ -1040,7 +1040,7 @@ private long[] basicStat(TruffleFile file, LinkOption... linkOptions) throws IOE
10401040
mode |= 0100;
10411041
}
10421042
int inode = getEmulatedInode(file);
1043-
return setTimestamps(attributes, new long[]{
1043+
return setTimestamps(attributes, CREATION_TIME, new long[]{
10441044
mode,
10451045
inode, // ino
10461046
0, // dev
@@ -1053,10 +1053,10 @@ private long[] basicStat(TruffleFile file, LinkOption... linkOptions) throws IOE
10531053
});
10541054
}
10551055

1056-
private static long[] setTimestamps(Attributes attributes, long[] statResult) {
1056+
private static long[] setTimestamps(Attributes attributes, TruffleFile.AttributeDescriptor<FileTime> ctimeDescriptor, long[] statResult) {
10571057
FileTime atime = attributes.get(LAST_ACCESS_TIME);
10581058
FileTime mtime = attributes.get(LAST_MODIFIED_TIME);
1059-
FileTime ctime = attributes.get(UNIX_CTIME);
1059+
FileTime ctime = attributes.get(ctimeDescriptor);
10601060
statResult[7] = fileTimeToSeconds(atime);
10611061
statResult[8] = fileTimeToSeconds(mtime);
10621062
statResult[9] = fileTimeToSeconds(ctime);

0 commit comments

Comments
 (0)