Skip to content

Commit 252b280

Browse files
committed
[GR-44758] Fixes for PyGame
PullRequest: graalpython/2676
2 parents 4a6507f + ca8d95d commit 252b280

File tree

9 files changed

+85
-48
lines changed

9 files changed

+85
-48
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ language runtime. The main focus is on user-observable behavior of the engine.
1212
* Allow excluding the Java-based SSL module that uses classes from `java.security.*`, `org.bouncycastle.*`, `javax.net.ssl.*` and any related classes from the native image by passing `-Dpython.java.ssl=false` to the native image build Java arguments.
1313
* Allow excluding the Java UnixSystem classes from `com.sun.security.auth.*` by passing `-Dpython.java.auth=false` to the native image build Java arguments. This makes the POSIX calls `getpwuid`, `getpwname`, and `getuid` return less precise results in the Java-based POSIX backend.
1414
* Allow excluding the use of `sun.misc.Signal` and `sun.misc.SignalHandler` from GraalPy by passing `-Dpython.java.signals=false` to the native image build Java arguments. This removes the `signal` module from the binary.
15+
* We now run an publish benchmark results from the community's [pyperformance](https://pyperformance.readthedocs.io) benchmark suite on our [website](http://graalvm.org/python). This makes it easier to compare and reproduce our results.
16+
* Allow building and running basic workloads on Windows. This enables Windows users to build and use GraalPy, especially for embedding into Java.
17+
* Implement complete support for PEP 622 pattern matching. All features of Python's structural pattern matching should now work.
18+
* Update the distribution layout of GraalPy to match CPython's. This reduces the number of patches we need for various build systems to discover GraalPy's library locations.
19+
* Add an option for embedders of GraalPy to poll asynchronous actions explicitly. This prevents GraalPy from creating system threads for collecting Python-level references and instead provides a callback that the embedder calls to do this work at regular intervals. See docs/user/PythonNativeImages.md for details.
20+
* Remove the intrinsified `zipimport` module in favor of the pure Python version. This fixes subtle incompatibilities with CPython when handling ZIP files.
21+
* Use the JDK's `MessageDigest` for hashing instead of pure Python implementations. This improves performance and compatibility in Java embeddings.
22+
* Add initial support for `asyncio`. While not complete, this already allows some async libraries like `aiofiles` to work.
23+
* Add a new implementation of our Python C API interface that uses fully native execution by default. This improves performance and compatibility with some extensions that spend a lot of time in native code, but can have negative effects in workloads that cross often from Python to native code and back. There are new options to control how extensions are built and run: `python.NativeModules` and `python.UseSystemToolchain`. The new default is to use the host system's toolchain for building extensions rather than the LLVM toolchain that ships with GraalVM, and to run all modules natively.
1524

1625
## Version 22.3.0
1726
* Rename GraalPython to GraalPy. This change also updates the launchers we ship to include symlinks from `python` and `python3` to `graalpy` for better integration with other tools.

README.md

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
# GraalVM Implementation of Python
22

3-
This is an early-stage experimental implementation of Python. A primary goal is
4-
to support SciPy and its constituent libraries. GraalPy can usually execute
5-
pure Python code faster than CPython (but not when C extensions are
6-
involved). GraalPy currently aims to be compatible
7-
with Python 3.8, but it is a long way from there, and it is very likely that any
8-
Python program that uses more features of standard library modules or external
9-
packages will hit something unsupported. At this point, the Python
10-
implementation is made available for experimentation and curious end-users.
3+
This is GraalPy, an implementation of the Python language.
4+
A primary goal is to support SciPy and its constituent libraries.
5+
GraalPy can usually execute pure Python code faster than CPython (but not when C extensions are involved).
6+
GraalPy currently aims to be compatible with Python 3.10, but it is some way from there.
7+
While your specific workload may function, any Python program that uses external packages could hit something unsupported.
8+
At this point, the Python implementation is made available for experimentation and curious end-users.
119

1210
### Trying It
1311

14-
The easiest option to try GraalPy is
15-
[Pyenv](https://github.com/pyenv/pyenv/), the Python version manager. It allows
16-
you to easily install different GraalPy releases. To get version 22.3.0, for
17-
example, just run `pyenv install graalpy-22.3.0`.
12+
The easiest option to try GraalPy is [Pyenv](https://github.com/pyenv/pyenv/), the Python version manager.
13+
It allows you to easily install different GraalPy releases.
14+
To get version 22.3.0, for example, just run `pyenv install graalpy-22.3.0`.
1815

19-
To try GraalPy with a full GraalVM, including the support for Java embedding
20-
and interop with other languages, you can use the bundled releases from
21-
[www.graalvm.org](https://www.graalvm.org/downloads/).
16+
To try GraalPy with a full GraalVM, including the support for Java embedding and interop with other languages, you can use the bundled releases from [www.graalvm.org](https://www.graalvm.org/downloads/).
17+
18+
Another option is to use [Conda-Forge](https://conda-forge.org/).
19+
To get an environment with the latest GraalPy, use `conda create -c conda-forge -n graalpy graalpy`.
2220

2321
### Building from Source
2422

@@ -62,30 +60,11 @@ In the venv, multiple executables are available, like `python`, `python3` and `g
6260

6361
### Installing Packages
6462

65-
Currently, not enough of the standard library is implemented to run the
66-
standard package installers for many packages. As a convenience, we provide a
67-
simple module to install packages that we know to be working (including
68-
potential patches required for those packages). Try the following to find out
69-
which packages are at least partially supported and tested by us in our CI:
70-
```
71-
graalpy -m ginstall install --help
72-
```
73-
74-
As a slightly exciting example, try:
75-
```
76-
graalpy -m ginstall install pandas
77-
```
78-
79-
If all goes well (also consider native dependencies of NumPy), you should be
80-
able to `import numpy` and `import pandas` afterwards.
81-
82-
Support for more extension modules is high priority for us. We are actively
83-
building out our support for the Python C API to make extensions such as NumPy,
84-
SciPy, Scikit-learn, Pandas, Tensorflow and the like work fully. This work means
85-
that some other extensions might also already work, but we're not actively
86-
testing other extensions right now and cannot promise anything. Note that to try
87-
other extensions on this implementation, you have to download, build, and
88-
install them manually for now.
63+
You should be able to use the `pip` command from a GraalPy venv to install packages.
64+
Our `pip` ships some patches for packages that we test internally, these will be applied automatically where necessary.
65+
Support for as many extension modules as possible is a high priority for us.
66+
We are actively building out our support for the Python C API to make extensions such as NumPy, SciPy, Scikit-learn, Pandas, Tensorflow and the like work fully.
67+
This means that some might already work, but we're still actively working on compatibility especially with native extensions.
8968

9069
### Polyglot Usage
9170

@@ -96,7 +75,7 @@ cross-language interop. This will hopefully give you an idea how to use it.
9675

9776
We are working on a mode that is "mostly compatible" with some of Jython's
9877
features, minus of course that Jython implements Python 2.7 and we implement
99-
Python 3.8+. We describe the current status of the compatibility mode
78+
Python 3.10+. We describe the current status of the compatibility mode
10079
[here](docs/user/Jython.md).
10180

10281
### Contributing

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ typedef struct {
299299
BUILTIN(PyTruffleObject_GenericGetAttr, PyObject*, PyObject*, PyObject*) \
300300
BUILTIN(PyTruffleObject_GenericSetAttr, int, PyObject*, PyObject*, PyObject*) \
301301
BUILTIN(PyTruffleObject_GetItemString, PyObject*, PyObject*, const char*) \
302-
BUILTIN(PyTruffleState_FindModule, PyObject*, struct PyModuleDef*) \
302+
BUILTIN(PyTruffleState_FindModule, PyObject*, Py_ssize_t) \
303303
BUILTIN(PyTruffleStructSequence_InitType2, int, PyTypeObject*, void*, void*, int) \
304304
BUILTIN(PyTruffleStructSequence_NewType, PyTypeObject*, const char*, const char*, void*, void*, int) \
305305
BUILTIN(PyTruffleToCharPointer, void*, PyObject*) \

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltinRegistry.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int;
5252
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.LONG_LONG;
5353
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Long;
54-
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PYMODULEDEF_PTR;
5554
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_CAPSULE_DESTRUCTOR;
5655
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_COMPILER_FLAGS;
5756
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_GIL_STATE_STATE;
@@ -566,7 +565,7 @@ private PythonCextBuiltinRegistry() {
566565
new CApiBuiltinExecutable("PyTruffleObject_GetItemString", Ignored, PyObjectTransfer,
567566
new ArgDescriptor[]{PyObject, ConstCharPtrAsTruffleString}, 201),
568567
new CApiBuiltinExecutable("PyTruffleState_FindModule", Ignored, PyObjectBorrowed,
569-
new ArgDescriptor[]{PYMODULEDEF_PTR}, 202),
568+
new ArgDescriptor[]{Py_ssize_t}, 202),
570569
new CApiBuiltinExecutable("PyTruffleStructSequence_InitType2", Ignored, Int,
571570
new ArgDescriptor[]{PyTypeObject, Pointer, Pointer, Int}, 203),
572571
new CApiBuiltinExecutable("PyTruffleStructSequence_NewType", Ignored, PyTypeObjectTransfer,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,13 @@ static PythonBuiltinObject doOther(@SuppressWarnings("unused") Object value) {
244244
}
245245

246246
public static PException checkThrowableBeforeNative(Throwable t, String where1, Object where2) {
247-
if (t instanceof PException) {
247+
if (t instanceof PException pe) {
248248
// this is ok, and will be handled correctly
249-
throw (PException) t;
249+
throw pe;
250+
}
251+
if (t instanceof ThreadDeath td) {
252+
// ThreadDeath subclasses are used internally by Truffle
253+
throw td;
250254
}
251255
// everything else: log and convert to PException (SystemError)
252256
CompilerDirectives.transferToInterpreter();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@
4343
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct;
4444
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored;
4545
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int;
46-
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PYMODULEDEF_PTR;
4746
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_GIL_STATE_STATE;
4847
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectBorrowed;
4948
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadState;
49+
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
5050
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void;
5151

5252
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin;
@@ -123,7 +123,7 @@ PDict get(@Cached PythonObjectFactory factory) {
123123
}
124124
}
125125

126-
@CApiBuiltin(ret = PyObjectBorrowed, args = {PYMODULEDEF_PTR}, call = Ignored)
126+
@CApiBuiltin(ret = PyObjectBorrowed, args = {Py_ssize_t}, call = Ignored)
127127
abstract static class PyTruffleState_FindModule extends CApiUnaryBuiltinNode {
128128

129129
@Specialization

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ public enum ArgDescriptor {
313313

314314
func_objint("int (*)(PyObject*value)"),
315315
func_voidvoidptr("void (*)(void*)"),
316-
func_voidvoid("void (*)(void)"),
316+
func_voidvoid(ArgBehavior.Pointer, "void (*)(void)"),
317317
func_intvoidptr("int (*)(void*)"),
318318
func_objvoid("PyObject*(*)(void)"),
319319
func_objcharsizevoidptr("PyObject*(*)(const char*, Py_ssize_t, void*)"),
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
diff --git a/src_c/base.c b/src_c/base.c
2+
index e73eb001..6f1c479d 100644
3+
--- a/src_c/base.c
4+
+++ b/src_c/base.c
5+
@@ -25,6 +25,7 @@
6+
#include "pygame.h"
7+
8+
#include <signal.h>
9+
+#include <string.h>
10+
#include "doc/pygame_doc.h"
11+
#include "pgarrinter.h"
12+
#include "pgcompat.h"
13+
@@ -2022,18 +2023,27 @@ pg_install_parachute(void)
14+
{
15+
#ifdef HAVE_SIGNAL_H
16+
int i;
17+
- void (*ohandler)(int);
18+
+ struct sigaction act;
19+
20+
if (parachute_installed) {
21+
return;
22+
}
23+
parachute_installed = 1;
24+
25+
- /* Set a handler for any fatal signal not already handled */
26+
+ /* Set a handler for any fatal signal not already handled.
27+
+ Use sigaction to retrieve the current handler first, so
28+
+ we don't mess with signal handlers in multi-threaded
29+
+ runtimes without a GIL. This is still racy, but better
30+
+ than using the signal function. */
31+
for (i = 0; fatal_signals[i]; ++i) {
32+
- ohandler = (void (*)(int))signal(fatal_signals[i], pygame_parachute);
33+
- if (ohandler != SIG_DFL) {
34+
- signal(fatal_signals[i], ohandler);
35+
+ sigaction(fatal_signals[i], NULL, &act);
36+
+ if (act.sa_handler == SIG_DFL) {
37+
+ memset(&act, 0, sizeof(struct sigaction));
38+
+ sigemptyset(&act.sa_mask);
39+
+ sigaddset(&act.sa_mask, fatal_signals[i]);
40+
+ act.sa_handler = pygame_parachute;
41+
+ act.sa_flags = SA_RESTART;
42+
+ sigaction(fatal_signals[i], &act, NULL);
43+
}
44+
}
45+

mx.graalpython/mx_graalpython.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,7 @@ def _python_checkpatchfiles():
18431843
"MIT", "BSD", "BSD-3-Clause", "BSD 3-Clause License", "BSD or Apache License, Version 2.0",
18441844
"MIT license", "PSF", "BSD-3-Clause OR Apache-2.0", "Apache", "Apache License", "new BSD",
18451845
"(Apache-2.0 OR BSD-3-Clause) AND PSF-2.0", "Apache 2.0", "MPL-2.0", "BSD 3-Clause",
1846+
"LGPL",
18461847
]
18471848
for line in content.split("\n"):
18481849
if not line or os.stat(line).st_size == 0:

0 commit comments

Comments
 (0)