Skip to content

Commit 3e578e5

Browse files
timfelmsimacek
authored andcommitted
Add an option to warn when C extensions are loaded
1 parent 7181ef6 commit 3e578e5

File tree

4 files changed

+21
-2
lines changed

4 files changed

+21
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ language runtime. The main focus is on user-observable behavior of the engine.
77
* Updated developer metadata of Maven artifacts.
88

99
## Version 24.1.0
10+
* GraalPy is now considered stable for pure Python workloads. While many workloads involving native extension modules work, we continue to consider them experimental. You can use the command-line option `--python.WarnExperimentalFeatures` to enable warnings for such modules at runtime. In Java embeddings, set the context option `python.WarnExperimentalFeatures` to true.
1011
* Update to Python 3.11.7
1112
* We now provide intrinsified `_pickle` module also in the community version.
1213
* `polyglot.eval` now raises more meaningful exceptions. Unavaliable languages raise `ValueError`. Exceptions from the polyglot language are raised directly as interop objects (typed as `polyglot.ForeignException`). The shortcut for executing python files without specifying language has been removed, use regular `eval` for executing Python code.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
GraalPy is a high-performance implementation of the [Python](https://www.python.org/) language for the JVM built on [GraalVM](https://www.graalvm.org/).
88
GraalPy has first-class support for embedding in Java and can turn Python applications into fast, standalone binaries.
9+
GraalPy is ready for production running pure Python code and has experimental support for many popular native extension modules.
910

1011
## Why GraalPy?
1112

@@ -17,15 +18,15 @@ GraalPy has first-class support for embedding in Java and can turn Python applic
1718

1819
**Compatible with the Python ecosystem**
1920

20-
* Install [packages](docs/user/Python-Runtime.md#installing-packages) like *NumPy*, *PyTorch*, or *Tensorflow*; run [Hugging Face](https://huggingface.co/) models like *Stable Diffusion* or *GPT*
21-
* See if the packages you need work with our [Python Compatibility Checker](https://www.graalvm.org/python/compatibility/)
2221
* Use almost any standard Python feature, the CPython tests run on every commit and pass ~85%
2322
![](docs/user/assets/mcd.svg#gh-light-mode-only)![](docs/user/assets/mcd-dark.svg#gh-dark-mode-only)<sup>
2423
We run the tests of the [most depended on PyPI packages](https://libraries.io/pypi) every day.
2524
For 96% of those packages a recent version can be installed on GraalPy and GraalPy passes about 50% of all tests of all packages combined.
2625
We assume that CPython not passing 100% of all tests is due to problems in our infrastructure that may also affect GraalPy.
2726
Packages where CPython fails all tests are marked as "not tested" for both CPython and GraalPy.
2827
</sup>
28+
* See if the packages you need work according to our [Python Compatibility Checker](https://www.graalvm.org/python/compatibility/)
29+
* Support for native extension modules is considered experimental, but you can already install [packages](docs/user/Python-Runtime.md#installing-packages) like *NumPy*, *PyTorch*, or *Tensorflow*; run [Hugging Face](https://huggingface.co/) models like *Stable Diffusion* or *GPT*
2930

3031
**Runs Python code faster**
3132

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
import java.io.IOException;
5555
import java.nio.file.LinkOption;
56+
import java.util.Set;
5657

5758
import org.graalvm.collections.Pair;
5859
import org.graalvm.shadowed.com.ibm.icu.impl.Punycode;
@@ -274,6 +275,15 @@ private static String dlopenFlagsToString(int flags) {
274275
return str;
275276
}
276277

278+
private static final Set<String> C_EXT_SUPPORTED_LIST = Set.of(
279+
// Stdlib modules are considered supported
280+
"_cpython_sre",
281+
"_cpython_unicodedata",
282+
"_sha3",
283+
"_sqlite3",
284+
"termios",
285+
"pyexpat");
286+
277287
/**
278288
* This method loads a C extension module (C API) and will initialize the corresponding native
279289
* contexts if necessary.
@@ -295,6 +305,10 @@ private static String dlopenFlagsToString(int flags) {
295305
public static Object loadCExtModule(Node location, PythonContext context, ModuleSpec spec, CheckFunctionResultNode checkFunctionResultNode)
296306
throws IOException, ApiInitException, ImportException {
297307

308+
if (context.getOption(PythonOptions.WarnExperimentalFeatures) && !C_EXT_SUPPORTED_LIST.contains(spec.name.toJavaStringUncached())) {
309+
getLogger().warning(() -> "Loading C extension module %s from '%s'. Support for the Python C API is considered experimental.".formatted(spec.name, spec.path));
310+
}
311+
298312
// we always need to load the CPython C API
299313
CApiContext cApiContext = CApiContext.ensureCapiWasLoaded(location, context, spec.name, spec.path);
300314
Object library;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ private PythonOptions() {
388388
@EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "If true, uses native storage strategy for primitive types") //
389389
public static final OptionKey<Boolean> UseNativePrimitiveStorageStrategy = new OptionKey<>(false);
390390

391+
@Option(category = OptionCategory.EXPERT, usageSyntax = "true|false", help = "Print warnings when using experimental features at runtime.", stability = OptionStability.STABLE) //
392+
public static final OptionKey<Boolean> WarnExperimentalFeatures = new OptionKey<>(false);
393+
391394
public static final OptionDescriptors DESCRIPTORS = new PythonOptionsOptionDescriptors();
392395

393396
@CompilationFinal(dimensions = 1) private static final OptionKey<?>[] ENGINE_OPTION_KEYS;

0 commit comments

Comments
 (0)