diff --git a/docs/site/01-jvm-developers.md b/docs/site/01-jvm-developers.md index 92fe1b8634..945ed1c361 100644 --- a/docs/site/01-jvm-developers.md +++ b/docs/site/01-jvm-developers.md @@ -366,6 +366,12 @@ try (Context context = GraalPyResources.contextBuilder().build()) {
Use GraalPy with Maven or Gradle in a Java SE Application
+
+ book icon + +
Freeze Transitive Python Dependencies for Reproducible Builds
+
+
book icon @@ -380,6 +386,12 @@ try (Context context = GraalPyResources.contextBuilder().build()) {
Use GraalPy with Micronaut
+
+ book icon + +
Manually Install Python Packages
+
+
book icon @@ -400,6 +412,12 @@ try (Context context = GraalPyResources.contextBuilder().build()) {

Demos

-
- - -
-
-
- diff --git a/docs/site/02-jvm-developers-docs.md b/docs/site/02-jvm-developers-docs.md index 9954df4183..8c969c3572 100644 --- a/docs/site/02-jvm-developers-docs.md +++ b/docs/site/02-jvm-developers-docs.md @@ -22,6 +22,7 @@ These guides cover everything you need to know: {% gfm_docs ../user/Embedding-Getting-Started.md %} {% gfm_docs ../user/Embedding-Build-Tools.md %} {% gfm_docs ../user/Embedding-Permissions.md %} +{% gfm_docs ../user/Embedding-Native-Extensions.md %} {% gfm_docs ../user/Interoperability.md %} {% gfm_docs ../user/Native-Images-with-Python.md %} {% gfm_docs ../user/Python-on-JVM.md %} diff --git a/docs/site/02-python-developers-docs.md b/docs/site/02-python-developers-docs.md index cb7732ddfc..be9e34bc9e 100644 --- a/docs/site/02-python-developers-docs.md +++ b/docs/site/02-python-developers-docs.md @@ -19,19 +19,12 @@ You get better performance, the ability to compile to native binaries, and acces These guides cover everything you need to know: {% gfm_docs ../user/Standalone-Getting-Started.md %} -{% gfm_docs ../user/Python-Runtime.md %} {% gfm_docs ../user/Python-Standalone-Applications.md %} {% gfm_docs ../user/Native-Extensions.md %} +{% gfm_docs ../user/Interoperability.md %} {% gfm_docs ../user/Performance.md %} {% gfm_docs ../user/Tooling.md %} -

-Python Context Options -

-Below are the options you can set on contexts for GraalPy. -{% python_options ../../graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java %} - {% gfm_docs ../user/Test-Tiers.md %} -{% gfm_docs ../user/Troubleshooting.md %} {% copy_assets ../user/assets %} diff --git a/docs/user/Embedding-Native-Extensions.md b/docs/user/Embedding-Native-Extensions.md new file mode 100644 index 0000000000..eaa31c0cd3 --- /dev/null +++ b/docs/user/Embedding-Native-Extensions.md @@ -0,0 +1,45 @@ +# Embedding Limitations for Native Extensions + +Python native extensions run by default as native binaries, with full access to the underlying system. +This has a few implications: + +1. Native code is entirely unrestricted and can circumvent any security protections Truffle or the JVM may provide. +2. Native data structures are not subject to the Java GC and the combination of them with Java data structures may lead to increased memory pressure or memory leaks. +3. Native libraries generally cannot be loaded multiple times into the same process, and they may contain global state that cannot be safely reset. + +## Full Native Access + +The Context API allows you to set options such as `allowIO`, `allowHostAccess`, `allowThreads`, and more on created contexts. +To use Python native extensions on GraalPy, the `allowNativeAccess` option must be set to `true`, but this opens the door to full native access. +This means that while Python code may be denied access to the host file system, thread or subprocess creation, and more, the native extension is under no such restriction. + +## Memory Management + +Python C extensions, like the CPython reference implementation, use reference counting for memory management. +This is fundamentally incompatible with JVM GCs. + +Java objects may end up being referenced from native data structures that the JVM cannot trace, so to avoid crashing, GraalPy keeps such Java objects strongly referenced. +To avoid memory leaks, GraalPy implements a cycle detector that regularly traces references between Java objects and native objects that have crossed between the two worlds and cleans up strong references that are no longer needed. + +On the other side, reference-counted native extension objects may end up being referenced from Java objects, and in this case GraalPy bumps their reference count to make them unreclaimable. +Any such references to native extension objects are registered with a `java.lang.ref.WeakReference`, and when the JVM GC has collected the owning Java object, the reference count of the native object is reduced again. + +Both of these mechanisms together mean there is additional delay between objects becoming unreachable and their memory being reclaimed when compared to the CPython implementation. +This can manifest in increased memory usage when running C extensions. +You can tweak the context options `python.BackgroundGCTaskInterval`, `python.BackgroundGCTaskThreshold`, and `BackgroundGCTaskMinimum` to mitigate this. +They control the minimum interval between cycle detections, how much RSS memory must have increased since the last time to trigger the cycle detector, and the absolute minimum RSS under which no cycle detection should be done. +You can also manually trigger the detector with the Python `gc.collect()` call. + +## Multi-Context and Native Libraries + +Using C extensions in multiple contexts is only possible on Linux for now, and many C extensions still have issues in this mode. +You should test your applications thoroughly if you want to use this feature. +There are many possibilities for native code to sidestep the library isolation through other process-wide global state, corrupting the state and leading to incorrect results or crashing. +The implementation also relies on `venv` to work, even if you are not using external packages. + +To support creating multiple GraalPy contexts that access native modules within the same JVM or Native Image, GraalPy isolates them from each other. +The current strategy for this is to copy the libraries and modify them such that the dynamic library loader of the operating system will isolate them. +To do this, all GraalPy contexts in the same process, not just those in the same engine, must set the `python.IsolateNativeModules` option to `true`. +You should test your applications thoroughly if you want to use this feature, as there are many possibilities for native code to sidestep the library isolation through other process-wide global state. + +For more details on this, see [our implementation details](https://github.com/oracle/graalpython/blob/master/docs/contributor/IMPLEMENTATION_DETAILS.md#c-extension-copying). diff --git a/docs/user/Embedding-Permissions.md b/docs/user/Embedding-Permissions.md index 1326a545f0..316714b44c 100644 --- a/docs/user/Embedding-Permissions.md +++ b/docs/user/Embedding-Permissions.md @@ -128,4 +128,4 @@ Context context = Context.newBuilder("python") Python native extensions run by default as native binaries with full access to the underlying system. This means they bypass the security controls described above. -For more information about limitations when embedding native extensions, see [Embedding limitations](Native-Extensions.md#embedding-limitations). \ No newline at end of file +For more information about limitations when embedding native extensions, see [Embedding limitations](Embedding-Native-Extensions.md). diff --git a/docs/user/Interoperability.md b/docs/user/Interoperability.md index 1f402bf540..0c0bcb7347 100644 --- a/docs/user/Interoperability.md +++ b/docs/user/Interoperability.md @@ -5,6 +5,8 @@ This means that you can use other languages' objects and functions directly from This interoperability works in both directions. Python can call other languages, and other languages can call Python code. +> **Note for Python users:** The Java interoperability sections below require a JVM-based GraalPy runtime with the relevant Java classes on the classpath. The later `polyglot` sections describe the more general cross-language APIs for working with other Graal languages. + ## Call Java from Python Java is the host language of the JVM and runs the GraalPy interpreter itself. diff --git a/docs/user/Native-Extensions.md b/docs/user/Native-Extensions.md index ecbeb12830..094042216f 100644 --- a/docs/user/Native-Extensions.md +++ b/docs/user/Native-Extensions.md @@ -7,49 +7,3 @@ Packages that use the native API must be built and installed with GraalPy, and t For best results, it is crucial that you only use the `pip` command that comes preinstalled in GraalPy virtual environments to install packages. The version of `pip` shipped with GraalPy applies additional patches to packages upon installation to fix known compatibility issues and it is preconfigured to use an additional repository from graalvm.org where we publish a selection of prebuilt wheels for GraalPy. Please do not update `pip` or use alternative tools such as `uv`. - -## Embedding limitations - -Python native extensions run by default as native binaries, with full access to the underlying system. -This has a few implications: - -1. Native code is entirely unrestricted and can circumvent any security protections Truffle or the JVM may provide. -2. Native data structures are not subject to the Java GC and the combination of them with Java data structures may lead to increased memory pressure or memory leaks. -3. Native libraries generally cannot be loaded multiple times into the same process, and they may contain global state that cannot be safely reset. - -### Full Native Access - -The Context API allows to set options such as `allowIO`, `allowHostAccess`, `allowThreads` and more on the created contexts. -To use Python native extensions on GraalPy, the `allowNativeAccess` option must be set to true, but this opens the door to full native access. -This means that while Python code may be denied access to the host file system, thread- or subprocess creation, and more, the native extension is under no such restriction. - -### Memory Management - -Python C extensions, like the CPython reference implementation, use reference counting for memory management. -This is fundamentally incompatible with JVM GCs. - -Java objects may end up being referenced from native data structures which the JVM cannot trace, so to avoid crashing, GraalPy keeps such Java objects strongly referenced. -To avoid memory leaks, GraalPy implements a cycle detector that regularly traces references between Java objects and native objects that have crossed between the two worlds and cleans up strong references that are no longer needed. - -On the other side, reference-counted native extension objects may end up being referenced from Java objects, and in this case GraalPy bumps their reference count to make them unreclaimable. -Any such references to native extension objects are registered with a `java.lang.ref.WeakReference` and when the JVM GC has collected the owning Java object, the reference count of the native object is reduced again. - -Both of these mechanisms together mean there is additional delay between objects becoming unreachable and their memory being reclaimed when compared to the CPython implementation. -This can manifest in increased memory usage when running C extensions. -You can tweak the Context options `python.BackgroundGCTaskInterval`, `python.BackgroundGCTaskThreshold`, and `BackgroundGCTaskMinimum` to mitigate this. -They control the minimum interval between cycle detections, how much RSS memory must have increased since the last time to trigger the cycle detector, and the absolute minimum RSS under which no cycle detection should be done. -You can also manually trigger the detector with the Python `gc.collect()` call. - -### Multi-Context and Native Libraries - -Using C extensions in multiple contexts is only possible on Linux for now, and many C extensions still have issues in this mode. -You should test your applications thoroughly if you want to use this feature. -There are many possibilities for native code to sidestep the library isolation through other process-wide global state, corrupting the state and leading to incorrect results or crashing. -The implementation also relies on `venv` to work, even if you are not using external packages. - -To support creating multiple GraalPy contexts that access native modules within the same JVM or Native Image, we need to isolate them from each other. -The current strategy for this is to copy the libraries and modify them such that the dynamic library loader of the operating system will isolate them for us. -To do this, all GraalPy contexts in the same process (not just those in the same engine!) must set the `python.IsolateNativeModules` option to `true`. -You should test your applications thoroughly if you want to use this feature, as there are many possiblities for native code to sidestep the library isolation through other process-wide global state. - -For more details on this, see [our implementation details](https://github.com/oracle/graalpython/blob/master/docs/contributor/IMPLEMENTATION_DETAILS.md#c-extension-copying). diff --git a/docs/user/Python-Runtime.md b/docs/user/Python-Runtime.md index 394355711f..b8730d9354 100644 --- a/docs/user/Python-Runtime.md +++ b/docs/user/Python-Runtime.md @@ -1,153 +1,19 @@ # GraalPy Runtime Guide -> **Quick Start**: For installation and basic usage, see [Standalone Getting Started](Standalone-Getting-Started.md). +This content has been merged into [Using GraalPy as a Standalone Python Runtime](Standalone-Getting-Started.md). ## Choosing a GraalPy Distribution -GraalPy is available in multiple distributions: - -### Distribution Options - -- **GraalPy built on Oracle GraalVM** - Provides the best experience with additional optimizations, significantly faster performance and better memory efficiency. Licensed under the [GraalVM Free Terms and Conditions (GFTC)](https://www.oracle.com/downloads/licenses/graal-free-license.html), which permits use by any user including commercial and production use. Redistribution is permitted as long as it is not for a fee. -- **GraalPy Community** - Built on top of GraalVM Community Edition, fully open-source. - -### Runtime Options - -Two language runtime options are available for both distributions: - -- **Native** (recommended for standalone use) - - GraalPy is compiled ahead-of-time to a native executable - - You do not need a JVM to run GraalPy and it is compact in size - - Faster startup time - - Faster time to reach peak performance - -- **JVM** - - You can easily exploit Java interoperability - - Peak performance may be higher than the native option - - Slower startup time - -### Distribution Identification - -The GraalPy runtimes are identified using the pattern _graalpy(-community)(-jvm)-<version>-<os>-<arch>_: - -| Distribution | Native | JVM | -| ------------- | ----------------------------------------- | ---- | -| **Oracle** | `graalpy---` | `graalpy-jvm---` | -| **Community** | `graalpy-community---` | `graalpy-community-jvm---` | - -### Runtime Comparison - -| Runtime | Native (default) | JVM | -|:-------|:-----------------|:----| -|Time to start | faster | slower | -| Time to reach peak performance | faster | slower | -| Peak performance (also considering GC) |good | best | -| Java interoperability | needs configuration | works | +See [Choosing a GraalPy Distribution](Standalone-Getting-Started.md#choosing-a-graalpy-distribution). ## GraalPy Capabilities -GraalPy provides a Python 3.12 compliant runtime. -A primary goal is to support PyTorch, SciPy, and their constituent libraries, as well as to work with other data science and machine learning libraries from the rich Python ecosystem. -The GraalPy runtime is distributed as an ahead-of-time compiled native executable, compact in size. - -GraalPy provides the following capabilities: - -* CPython-compatible distribution. This is the most compatible option to test Python code on GraalPy, since it most closely resembles the structure of CPython distributions. -* Unique deployment mode for Python applications. Compile a Python application on GraalPy to [a single native binary](Python-Standalone-Applications.md) that embeds all needed resources. -* Access to GraalVM's language ecosystems and tools. GraalPy can run many standard Python tools as well as tools from the GraalVM ecosystem. +See [GraalPy Capabilities](Standalone-Getting-Started.md#graalpy-capabilities). ## Installing GraalPy -> NOTE: There will be a delay between GraalPy release and its availability on Pyenv. - -### Linux - -The easiest way to install GraalPy on Linux is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). -To install version 25.0.2 using Pyenv, run the following commands: -```bash -pyenv install graalpy-25.0.2 -``` -```bash -pyenv shell graalpy-25.0.2 -``` -> Before running `pyenv install`, you may need to update `pyenv` to include the latest GraalPy versions. - -Alternatively, you can download a compressed GraalPy installation file from [GitHub releases](https://github.com/oracle/graalpython/releases). - -1. Find the download that matches the pattern _graalpy-XX.Y.Z-linux-amd64.tar.gz_ or _graalpy-XX.Y.Z-linux-aarch64.tar.gz_ (depending on your platform) and download. -2. Uncompress the file and update your `PATH` environment variable to include to the _graalpy-XX.Y.Z-linux-amd64/bin_ (or _graalpy-XX.Y.Z-linux-aarch64/bin_) directory. - -### macOS - -The easiest way to install GraalPy on macOS is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). -To install version 25.0.2 using Pyenv, run the following commands: -```bash -pyenv install graalpy-25.0.2 -``` -```bash -pyenv shell graalpy-25.0.2 -``` -> Before running `pyenv install`, you may need to update `pyenv` to include the latest GraalPy versions. - -Alternatively, you can download a compressed GraalPy installation file from [GitHub releases](https://github.com/oracle/graalpython/releases). - -1. Find the download that matches the pattern _graalpy-XX.Y.Z-macos-aarch64.tar.gz_ and download. -2. Remove the quarantine attribute. - ```bash - sudo xattr -r -d com.apple.quarantine /path/to/graalpy - ``` - For example: - ```bash - sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-25.0.2 - ``` -3. Uncompress the file and update your `PATH` environment variable to include to the _graalpy-XX.Y.Z-macos-aarch64/bin_ directory. - -### Windows - -1. Find and download a compressed GraalPy installation file from [GitHub releases](https://github.com/oracle/graalpython/releases) that matches the pattern _graalpy-XX.Y.Z-windows-amd64.tar.gz_. -2. Uncompress the file and update your `PATH` variable to include to the _graalpy-XX.Y.Z-windows-amd64/bin_ directory. - -#### Windows Limitations - -The Windows distribution of GraalPy has more limitations than its Linux or macOS counterpart, so not all features and packages may be available. - -It has the following known issues: -- JLine treats Windows as a dumb terminal, with no autocomplete and limited editing capabilities in the REPL -- Interactive `help()` in the REPL does not work -- Inside a virtual environment: - - _graalpy.cmd_ and _graalpy.exe_ are broken - - _pip.exe_ cannot be used directly - - `pip` has trouble with cache file loading, use `--no-cache-dir` - - Only pure Python binary wheels can be installed, no native extensions or source builds - - To install a package, use `myvenv/Scripts/python.exe -m pip --no-cache-dir install ` -- Running from PowerShell works better than running from CMD, various scripts will fail on the latter +See [Installation](Standalone-Getting-Started.md#installation). ## Installing Packages -The best way of using GraalPy is from a [venv](https://docs.python.org/3/library/venv.html) virtual environment. -This generates wrapper scripts and makes the implementation usable from a shell as the standard Python interpreter. - -1. Create a virtual environment with GraalPy by running the following command: - ```bash - graalpy -m venv - ``` - For example: - ```bash - graalpy -m venv ~/.virtualenvs/graalpy-25.0.2 - ``` - -2. Activate the environment in your shell session: - ```bash - source /bin/activate - ``` - For example: - ```bash - source ~/.virtualenvs/graalpy-25.0.2/bin/activate - ``` - -Multiple executables are available in the virtual environment, including: `python`, `python3`, and `graalpy`. - -> Note: To deactivate the Python environment (and return to your shell), run `deactivate`. - -The `pip` package installer is available when using a virtual environment. -The GraalPy implementation of `pip` may choose package versions other than the latest in cases where it ships patches to make these work better. +See [Using Virtual Environments](Standalone-Getting-Started.md#using-virtual-environments). diff --git a/docs/user/README.md b/docs/user/README.md index 0ea22fbeae..f28d486032 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -35,16 +35,16 @@ You get better performance, the ability to compile to native binaries, and acces These guides cover everything you need to know: - **[Getting Started](Standalone-Getting-Started.md)** - Installation and basic usage -- **[Runtime Guide](Python-Runtime.md)** - Runtime options and compatibility - **[Standalone Applications](Python-Standalone-Applications.md)** - Compile Python to native binaries - **[Native Extensions](Native-Extensions.md)** - Working with C extensions and native packages +- **[Interoperability](Interoperability.md)** - Use Java and other Graal languages from Python - **[Performance](Performance.md)** - Optimization tips and benchmarks - **[Tooling](Tooling.md)** - IDE integration and development tools ## General Information - **[Test Tiers](Test-Tiers.md)** - Platform compatibility and testing information -- **[Troubleshooting](Troubleshooting.md)** - Common issues and solutions +- **[Troubleshooting](Troubleshooting.md)** - Common embedding issues and solutions ## Version Compatibility diff --git a/docs/user/Standalone-Getting-Started.md b/docs/user/Standalone-Getting-Started.md index 3ee39fdda2..f84b92b17b 100644 --- a/docs/user/Standalone-Getting-Started.md +++ b/docs/user/Standalone-Getting-Started.md @@ -1,9 +1,59 @@ # Using GraalPy as a Standalone Python Runtime GraalPy can be used as a standalone Python runtime, providing a drop-in replacement for CPython. -This guide covers installation, basic usage, and deployment options for standalone GraalPy applications. +This guide covers choosing a distribution, installation, package management, basic usage, and deployment options for standalone GraalPy applications. -> **Choosing a Distribution**: For detailed information about GraalPy distributions and runtime options, see [Python Runtime](Python-Runtime.md#choosing-a-graalpy-distribution). +## Choosing a GraalPy Distribution + +GraalPy is available in multiple distributions: + +### Distribution Options + +- **GraalPy built on Oracle GraalVM** provides the best experience with additional optimizations, significantly faster performance, and better memory efficiency. It is licensed under the [GraalVM Free Terms and Conditions (GFTC)](https://www.oracle.com/downloads/licenses/graal-free-license.html), which permits use by any user including commercial and production use. Redistribution is permitted as long as it is not for a fee. +- **GraalPy Community** is built on top of GraalVM Community Edition and is fully open source. + +### Runtime Options + +Two language runtime options are available for both distributions: + +- **Native** (recommended for standalone use) + - GraalPy is compiled ahead-of-time to a native executable + - You do not need a JVM to run GraalPy and it is compact in size + - Faster startup time + - Faster time to reach peak performance +- **JVM** + - You can easily exploit Java interoperability + - Peak performance may be higher than the native option + - Slower startup time + +### Distribution Identification + +The GraalPy runtimes are identified using the pattern _graalpy(-community)(-jvm)-<version>-<os>-<arch>_: + +| Distribution | Native | JVM | +| ------------- | ----------------------------------------- | ---- | +| **Oracle** | `graalpy---` | `graalpy-jvm---` | +| **Community** | `graalpy-community---` | `graalpy-community-jvm---` | + +### Runtime Comparison + +| Runtime | Native (default) | JVM | +|:-------|:-----------------|:----| +| Time to start | faster | slower | +| Time to reach peak performance | faster | slower | +| Peak performance (also considering GC) | good | best | +| Java interoperability | needs configuration | works | + +## GraalPy Capabilities + +GraalPy provides a Python 3.12 compliant runtime. +A primary goal is to support PyTorch, SciPy, and their constituent libraries, as well as to work with other data science and machine learning libraries from the rich Python ecosystem. + +GraalPy provides the following capabilities: + +- CPython-compatible distribution for testing Python code on GraalPy. +- A [single native binary packaging mode](Python-Standalone-Applications.md) for Python applications. +- Access to GraalVM language ecosystems and tools. ## Installation diff --git a/docs/user/Troubleshooting.md b/docs/user/Troubleshooting.md index 31733a4080..1b351f9183 100644 --- a/docs/user/Troubleshooting.md +++ b/docs/user/Troubleshooting.md @@ -1,6 +1,7 @@ -# GraalPy Troubleshooting +# GraalPy Embedding Troubleshooting -This guide helps you resolve common issues when using GraalPy, whether running it standalone or embedded in Java applications. +This guide helps you resolve common issues when embedding GraalPy in Java applications. +It focuses on Virtual FileSystem setup, context configuration, build tooling, and dependency alignment for JVM-based deployments. ## Virtual FileSystem Issues