Skip to content

Commit f4e7871

Browse files
committed
improvements to javadoc in GraalPyResources and VirtualFileSystem
1 parent 5d60a97 commit f4e7871

File tree

3 files changed

+155
-29
lines changed

3 files changed

+155
-29
lines changed

graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,64 @@
5555
import java.nio.file.Paths;
5656

5757
/**
58-
* This class provides utilities related to Python resources used in GraalPy embedding scenarios.
58+
* This class provides utilities related to Python resources used in GraalPy embedding scenarios
59+
* which can be of the following kind:
60+
* <ul>
61+
* <li>Python application files</li>
62+
* <li>Third-party Python packages</li>
63+
* <li>The Python standard library</li>
64+
* </ul>
65+
*
5966
* <p>
6067
* Resource files can be embedded and distributed in an <b>application file</b> or made available
6168
* from an <b>external directory</b>.
6269
* </p>
6370
*
71+
* <h3>Virtual Filesystem</h3>
6472
* <p>
65-
* If the resource files are part of a <b>jar file</b> or a <b>native image</b> executable, then at
66-
* runtime they will be accessed as standard Java resources through GraalPy
73+
* If the resource files are part of an <b>application file</b> (jar file or a native image
74+
* executable), then at runtime they will be accessed as standard Java resources through GraalPy
6775
* {@link VirtualFileSystem}. This will be transparent to Python code running in GraalPy so that it
68-
* can use standard Python IO to access those files. Note that in order to make this work, it is
69-
* necessary for those embedded resources to have their <b>root directory</b> set to
70-
* <code>/org.graalvm.python.vfs</code> which in python code will be mapped to the virtual
71-
* filesystem mount point, by default <code>/graalpy_vfs</code>. Refer to
76+
* can use standard Python IO to access those files.
77+
* </p>
78+
*
79+
* <p>
80+
* In order to make this work, it is necessary for those embedded resources to have their <b>root
81+
* directory</b> set to <code>/org.graalvm.python.vfs</code> which in python code will be mapped to
82+
* the virtual filesystem <b>mount point</b>, by default <code>/graalpy_vfs</code>. Refer to
7283
* {@link VirtualFileSystem.Builder} documentation for more details.
7384
* </p>
85+
*
86+
* <h3>External Directory</h3>
87+
* <p>
88+
* As an alternative to Java resources with the Virtual Filesystem, it is also possible to configure
89+
* the GraalPy context to use an external directory, which is not embedded as a Java resource into
90+
* the resulting application. Python code will access the files directly from the real filesystem.
91+
* </p>
92+
*
93+
* <h3>Conventions</h3>
94+
* <p>
95+
* The factory methods in GraalPyResources rely on the following conventions:
96+
* <ul>
97+
* <li>${resources_root}/src: used for Python application files. This directory will be configured
98+
* as the default search path for Python module files (equivalent to PYTHONPATH environment
99+
* variable).</li>
100+
* <li>${resources_root}/venv: used for the Python virtual environment holding installed third-party
101+
* Python packages. The Context will be configured as if it is executed from this virtual
102+
* environment. Notably packages installed in this virtual environment will be automatically
103+
* available for importing.</li>
104+
* <li>${resources_root}/home: used for the Python standard library (equivalent to PYTHONHOME
105+
* environment variable).</li>
106+
* </ul>
107+
* where ${resources_root} is either the resource root <code>/org.graalvm.python.vfs</code> or an
108+
* external directory.
109+
* </p>
110+
*
74111
* <p>
75112
* <b>Example</b> creating a GraalPy context configured for the usage with a
76113
* {@link VirtualFileSystem}:
77-
*
114+
* </p>
115+
*
78116
* <pre>
79117
* VirtualFileSystem.Builder builder = VirtualFileSystem.newBuilder();
80118
* builder.unixMountPoint("/python-resources");
@@ -101,16 +139,19 @@
101139
* <p>
102140
* <b>GraalPy context</b> instances created by factory methods in this class are preconfigured with
103141
* some particular resource paths:
104-
* <li><code>${resources_root_directory}/venv</code> - is reserved for a python virtual environment
105-
* holding third-party packages. The context will be configured as if it were executed from this
106-
* virtual environment. Notably packages installed in this virtual environment will be automatically
142+
* <li><code>${resources_root}/home</code> - is reserved for the GraalPy Standard Library. GraalPy
143+
* context will be configured to use this standard library as if set in PYTHONHOME environment
144+
* variable.</li>
145+
* <li><code>${resources_root}/venv</code> - is reserved for a python virtual environment holding
146+
* third-party packages. The context will be configured as if it were executed from this virtual
147+
* environment. Notably packages installed in this virtual environment will be automatically
107148
* available for importing.</li>
108-
* <li><code>${resources_root_directory}/src</code> - is reserved for python application files -
109-
* e.g. python sources. GraalPy context will be configured to see those files as if set in
110-
* PYTHONPATH environment variable.</li>
149+
* <li><code>${resources_root}/src</code> - is reserved for python application files - e.g. python
150+
* sources. GraalPy context will be configured to see those files as if set in PYTHONPATH
151+
* environment variable.</li>
111152
* </ul>
112-
* where <code>${resources_root_directory}</code> is either an external directory or the virtual
113-
* filesystem resource root <code>/org.graalvm.python.vfs</code>.
153+
* where <code>${resources_root}</code> is either an external directory or the virtual filesystem
154+
* resource root <code>/org.graalvm.python.vfs</code>.
114155
* </p>
115156
* <p>
116157
* <b>Example</b> creating a GraalPy context configured for the usage with an external resource
@@ -144,6 +185,8 @@
144185
*
145186
* @see VirtualFileSystem
146187
* @see VirtualFileSystem.Builder
188+
*
189+
* @since 24.2.0
147190
*/
148191
public final class GraalPyResources {
149192

@@ -162,6 +205,9 @@ private GraalPyResources() {
162205
* <li><code>/org.graalvm.python.vfs/src</code> - is set as the python sources location</li>
163206
* </ul>
164207
* </p>
208+
*
209+
* @return a new {@link Context} instance
210+
* @since 24.2.0
165211
*/
166212
public static Context createContext() {
167213
return contextBuilder().build();
@@ -196,6 +242,8 @@ public static Context createContext() {
196242
*
197243
* @see <a href=
198244
* "https://github.com/oracle/graalpython/blob/master/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java">PythonOptions</a>
245+
* @return a new {@link org.graalvm.polyglot.Context.Builder} instance
246+
* @since 24.2.0
199247
*/
200248
public static Context.Builder contextBuilder() {
201249
VirtualFileSystem vfs = VirtualFileSystem.create();
@@ -242,10 +290,13 @@ public static Context.Builder contextBuilder() {
242290
* <li>use the context to invoke a python snippet reading a resource file</li>
243291
* </ul>
244292
* </p>
245-
*
293+
*
294+
* @param vfs the {@link VirtualFileSystem} to be used with the created {@link Context}
295+
* @return a new {@link org.graalvm.polyglot.Context.Builder} instance
246296
* @see VirtualFileSystem
247297
* @see VirtualFileSystem.Builder
248-
*
298+
*
299+
* @since 24.2.0
249300
*/
250301
public static Context.Builder contextBuilder(VirtualFileSystem vfs) {
251302
return createContextBuilder().
@@ -299,6 +350,8 @@ public static Context.Builder contextBuilder(VirtualFileSystem vfs) {
299350
* </p>
300351
*
301352
* @param resourcesDirectory the root directory with GraalPy specific embedding resources
353+
* @return a new {@link org.graalvm.polyglot.Context.Builder} instance
354+
* @since 24.2.0
302355
*/
303356
public static Context.Builder contextBuilder(Path resourcesDirectory) {
304357
String execPath;
@@ -364,6 +417,8 @@ private static Context.Builder createContextBuilder() {
364417
*
365418
* @return the native executable path if it could be retrieved, otherwise <code>null</code>.
366419
* @see #contextBuilder(Path)
420+
*
421+
* @since 24.2.0
367422
*/
368423
public static Path getNativeExecutablePath() {
369424
if (ImageInfo.inImageRuntimeCode()) {
@@ -406,8 +461,13 @@ public static Path getNativeExecutablePath() {
406461
* </pre>
407462
* </p>
408463
*
464+
* @param vfs the {@link VirtualFileSystem} from which resources are to be extracted
465+
* @param resourcesDirectory the target directory to extract the resources to
466+
* @throws IOException if resources isn't a directory
409467
* @see #contextBuilder(Path)
410468
* @see VirtualFileSystem.Builder#resourceLoadingClass(Class)
469+
*
470+
* @since 24.2.0
411471
*/
412472
public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path resourcesDirectory) throws IOException {
413473
if (Files.exists(resourcesDirectory) && !Files.isDirectory(resourcesDirectory)) {

graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/VirtualFileSystem.java

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,50 @@
4646
import java.nio.file.Path;
4747
import java.util.function.Predicate;
4848

49+
/**
50+
* The GraalPy Virtual Filesystem accesses embedded resource files as standard Java resources and
51+
* makes them available to Python code running in GraalPy.
52+
*
53+
* @see GraalPyResources for more information on Python resources in GraalPy embedding and how to
54+
* use the {@link VirtualFileSystem} together with a GraalPy context.
55+
*
56+
* @since 24.2.0
57+
*/
4958
public final class VirtualFileSystem implements AutoCloseable {
5059

5160
final VirtualFileSystemImpl impl;
5261
final FileSystem delegatingFileSystem;
5362

63+
/**
64+
* Determines if and how much host IO is allowed outside the {@link VirtualFileSystem}.
65+
*
66+
* @since 24.2.0
67+
*/
5468
public static enum HostIO {
69+
/**
70+
* No host IO allowed.
71+
*
72+
* @since 24.2.0
73+
*/
5574
NONE,
75+
/**
76+
* Only read access allowed.
77+
*
78+
* @since 24.2.0
79+
*/
5680
READ,
81+
/**
82+
* Read and write access is allowed.
83+
*
84+
* @since 24.2.0
85+
*/
5786
READ_WRITE,
5887
}
5988

6089
/**
6190
* Builder class to create {@link VirtualFileSystem} instances.
91+
*
92+
* @since 24.2.0
6293
*/
6394
public static final class Builder {
6495
private static final Predicate<Path> DEFAULT_EXTRACT_FILTER = (p) -> {
@@ -81,14 +112,18 @@ private Builder() {
81112
/**
82113
* Sets the file system to be case-insensitive. Defaults to true on Windows and false
83114
* elsewhere.
115+
*
116+
* @since 24.2.0
84117
*/
85118
public Builder caseInsensitive(boolean value) {
86119
caseInsensitive = value;
87120
return this;
88121
}
89122

90123
/**
91-
* Determines if and how much host IO is allowed outside of the virtual filesystem.
124+
* Determines if and how much host IO is allowed outside the {@link VirtualFileSystem}.
125+
*
126+
* @since 24.2.0
92127
*/
93128
public Builder allowHostIO(HostIO b) {
94129
allowHostIO = b;
@@ -102,10 +137,14 @@ public Builder allowHostIO(HostIO b) {
102137
* "X:\graalpy_vfs\xyz\abc". This needs to be an absolute path with platform-specific
103138
* separators without any trailing separator. If that file or directory actually exists, it
104139
* will not be accessible.
140+
*
141+
* @throws IllegalArgumentException if the provided mount point isn't absolute or ends with
142+
* a trailing separator
143+
* @since 24.2.0
105144
*/
106-
public Builder windowsMountPoint(String s) {
145+
public Builder windowsMountPoint(String windowsMountPoint) {
107146
if (VirtualFileSystemImpl.isWindows()) {
108-
mountPoint = getMountPointAsPath(s);
147+
this.mountPoint = getMountPointAsPath(windowsMountPoint);
109148
}
110149
return this;
111150
}
@@ -117,10 +156,14 @@ public Builder windowsMountPoint(String s) {
117156
* "/graalpy_vfs/xyz/abc". This needs to be an absolute path with platform-specific
118157
* separators without any trailing separator. If that file or directory actually exists, it
119158
* will not be accessible.
159+
*
160+
* @throws IllegalArgumentException if the provided mount point isn't absolute or ends with
161+
* a trailing separator
162+
* @since 24.2.0
120163
*/
121-
public Builder unixMountPoint(String s) {
164+
public Builder unixMountPoint(String unixMountPoint) {
122165
if (!VirtualFileSystemImpl.isWindows()) {
123-
mountPoint = getMountPointAsPath(s);
166+
this.mountPoint = getMountPointAsPath(unixMountPoint);
124167
}
125168
return this;
126169
}
@@ -131,6 +174,8 @@ public Builder unixMountPoint(String s) {
131174
* <code>resourceLoadingClass</code> to determine where to locate resources in cases when
132175
* for example <code>VirtualFileSystem</code> is on module path and the jar containing the
133176
* resources is on class path.
177+
*
178+
* @since 24.2.0
134179
*/
135180
public Builder resourceLoadingClass(Class<?> c) {
136181
resourceLoadingClass = c;
@@ -148,6 +193,7 @@ public Builder resourceLoadingClass(Class<?> c) {
148193
*
149194
* @param filter the extraction filter, where the provided path is an absolute path from the
150195
* VirtualFileSystem.
196+
* @since 24.2.0
151197
*/
152198
public Builder extractFilter(Predicate<Path> filter) {
153199
if (filter == null) {
@@ -158,6 +204,12 @@ public Builder extractFilter(Predicate<Path> filter) {
158204
return this;
159205
}
160206

207+
/**
208+
* Build a new {@link VirtualFileSystem} instance from the configuration provided in the
209+
* builder.
210+
*
211+
* @since 24.2.0
212+
*/
161213
public VirtualFileSystem build() {
162214
if (mountPoint == null) {
163215
mountPoint = VirtualFileSystemImpl.isWindows() ? Path.of(DEFAULT_WINDOWS_MOUNT_POINT) : Path.of(DEFAULT_UNIX_MOUNT_POINT);
@@ -184,19 +236,31 @@ private VirtualFileSystem(Predicate<Path> extractFilter,
184236
this.delegatingFileSystem = VirtualFileSystemImpl.createDelegatingFileSystem(impl);
185237
}
186238

239+
/**
240+
* Creates a builder for constructing a {@link VirtualFileSystem} with a custom configuration.
241+
*
242+
* @since 24.2.0
243+
*/
187244
public static Builder newBuilder() {
188245
return new Builder();
189246
}
190247

248+
/**
249+
* Creates a {@link VirtualFileSystem}.
250+
*
251+
* @since 24.2.0
252+
*/
191253
public static VirtualFileSystem create() {
192254
return newBuilder().build();
193255
}
194256

195257
/**
196-
* The mount point for the virtual filesystem.
258+
* Returns the mount point for this {@link VirtualFileSystem}.
197259
*
198260
* @see VirtualFileSystem.Builder#windowsMountPoint(String)
199261
* @see VirtualFileSystem.Builder#unixMountPoint(String)
262+
*
263+
* @since 24.2.0
200264
*/
201265
public String getMountPoint() {
202266
return this.impl.mountPoint.toString();

graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/package-info.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@
4040
*/
4141

4242
/**
43-
* Utilities for GraalPy embedding scenarios.
44-
*
45-
* @see org.graalvm.python.embedding.utils.GraalPyResources for an overview on how to create and
46-
* configure a GraalPy context to get access to Python related resources in GraalPy embedding
47-
* scenarios.
43+
* Utilities for resources management in GraalPy embedding scenarios.
44+
* <p>
45+
* For an overview on how to create and configure a GraalPy context to get access to Python related
46+
* resources in GraalPy embedding scenarios see
47+
* {@link org.graalvm.python.embedding.utils.GraalPyResources}.
48+
* </p>
49+
*
4850
*
4951
* @since 24.2.0
5052
*/

0 commit comments

Comments
 (0)