Skip to content

Commit b050f75

Browse files
committed
[GR-25265] Merge Python Reference documentation from graalvm.org with Python User documentation.
PullRequest: graalpython/1163
2 parents 78efe9f + 2041488 commit b050f75

File tree

8 files changed

+324
-176
lines changed

8 files changed

+324
-176
lines changed

docs/user/FAQ.md

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,58 @@
11
# Frequently Asked Questions
22

3-
### Does module/package XYZ work on GraalPython?
3+
### Does module/package XYZ work on GraalVM's Python implementation?
44

5-
It depends, but is currently unlikely. Our first goal with GraalPython was to
6-
show that we can run NumPy and related packages using the managed GraalVM LLVM
7-
implementation. Now that we have done so we are hard at work to improve the
8-
number of passing CPython unittests. We are also beginning to track our
9-
compatibility with popular PyPI packages and expect to increase our coverage
10-
there soon.
5+
It depends, but is currently unlikely. The first goal with the GraalVM Python implementation was to
6+
show that NumPy and related packages can run using the managed GraalVM LLVM
7+
implementation. Now the GraalVM team continue to improve the
8+
number of passing CPython unittests and to track the compatibility with popular PyPI packages.
119

12-
### Can GraalPython replace my Jython use case?
10+
### Can the GraalVM Python implementation replace my Jython use case?
1311

14-
We hope it can, but there are some caveats, like Python code subclassing Java
12+
It can, but there are some caveats, like Python code subclassing Java
1513
classes or use through the `javax.script.ScriptEngine` not being
16-
supported. Please see our [migration document](./JYTHON) for details.
14+
supported. See the [Jython Compatibility](Jython.md) guide for details.
1715

18-
### Do I need to compile and run native modules as LLVM bitcode to use GraalPython?
16+
### Do I need to compile and run native modules as LLVM bitcode to use GraalVM's Python implementation?
1917

2018
If you want to run C extensions or use certain built-in features, yes, you need
21-
to build the module with GraalPython and then it will run using the GraalVM LLVM
22-
runtime. However, many of the core features of Python (including e.g. large
23-
parts of the `os` API) are implemented in pure Java and many standard library
24-
modules and packages work without running any LLVM bitcode. So even though
25-
GraalPython depends on GraalVM LLVM, for many use cases you can disallow native
26-
modules entirely.
19+
to build the module with GraalVM's Python and then it will run using the GraalVM
20+
LLVM runtime. However, many of the core features of Python (including e.g.,
21+
large parts of the `os` API) are implemented in pure Java and many standard
22+
library modules and packages work without running any LLVM bitcode. So even
23+
though GraalVM's Python depends on the GraalVM LLVM runtime, for many use cases
24+
you can disallow native modules entirely.
2725

28-
### Can I use GraalVM sandboxing features with GraalPython?
26+
### Can I use GraalVM sandboxing features with GraalVM's Python implementation?
2927

30-
Yes! As an embedder, you can selectively disable features. As an example, you
28+
Yes, you can. As an embedder, you can selectively disable features. For example, you
3129
can disable native code execution or filesystem access. If you are a user of
32-
GraalVM Enterprise Edition, you will also find that the managed execution mode
30+
Oracle GraalVM Enterprise Edition, you will also find that the managed execution mode
3331
for LLVM fully works for running extensions such as NumPy in a safer manner.
3432

3533
### Do all the GraalVM polyglot features work?
3634

37-
We are doing our best to ensure the polyglot features of GraalVM work as a
35+
The team is continuously working to ensure all polyglot features of GraalVM work as a
3836
Python user would expect. There are still many cases where expectations are
39-
unclear or where multiple behaviors are imaginable. We are actively looking at
40-
use cases and are continuously evolving the implementation to provide the most
41-
convenient and least surprising behavior.
37+
unclear or where multiple behaviours are imaginable. The team is actively looking at
38+
use cases and are continuously evolving the Python implementation to provide the most
39+
convenient and least surprising behaviour.
4240

43-
### What is the performance I can expect from GraalPython?
41+
### What is the performance I can expect from GraalVM's Python implementation?
4442

4543
For pure Python code, performance after warm-up can be expected to be around 5-6
4644
times faster than CPython 3.8 (or 6-7x faster than Jython). For native
47-
extensions running as LLVM bitcode, we are currently slower than CPython - you
45+
extensions running as LLVM bitcode, CPython is currently slower -- you
4846
can expect to see between 0.1x and 0.5x performance.
4947

50-
### I heard languages with JIT compilers have slow startup. Is that true for GraalPython?
48+
### I heard languages with JIT compilers have slow startup. Is that true for GraalVM's Python?
5149

52-
It depends. When you use the GraalVM native image feature with GraalPython or
53-
use the GraalPython launcher in GraalVM its startup is competitive with
54-
CPython. In any case, both with native image or when running on JVM we first
50+
It depends. When you use the [GraalVM Native Image](https://www.graalvm.org/docs/reference-manual/graalvm-native-image/) feature with Python or
51+
use the `graalpython` launcher of GraalVM, its startup is competitive with
52+
CPython. In any case, both with Native Image or when running on JVM you first
5553
need to warm up to reach peak performance. This is a complicated story in
5654
itself, but in general it can take a while (a minute or two) after you have
57-
reached and are running your core workload. We are continuously working on
58-
improving this.
55+
reached and are running your core workload.
5956

6057
### Can I share warmed up code between multiple Python contexts?
6158

docs/user/POLYGLOT.md renamed to docs/user/Interoperability.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Interoperability
22

3+
GraalVM supports several other programming languages, including JavaScript, R,
4+
Ruby, and LLVM. GraalVM provides a Python API to interact with other languages
5+
available on the GraalVM. In fact, GraalVM uses this API internally to
6+
execute Python C extensions using the LLVM implementation in GraalVM.
7+
38
You can import the `polyglot` module to interact with other languages.
49

510
```python
@@ -46,6 +51,85 @@ def python_method():
4651
return "Hello from Python!"
4752
```
4853

54+
Here is an example of how to use JavaScript regular expression engine to
55+
match Python strings. Save this code to the `polyglot_example.py` file:
56+
57+
```python
58+
import polyglot
59+
60+
re = polyglot.eval(string="RegExp()", language="js")
61+
62+
pattern = re.compile(".*(?:we have (?:a )?matching strings?(?:[!\\?] )?)(.*)")
63+
64+
if pattern.exec("This string does not match"):
65+
raise SystemError("that shouldn't happen")
66+
67+
md = pattern.exec("Look, we have matching strings! This string was matched by Graal.js")
68+
if not md:
69+
raise SystemError("this should have matched")
70+
71+
print("Here is what we found: '%s'" % md[1])
72+
```
73+
74+
To run it, pass the `--jvm --polyglot` options to `graalpython` binary:
75+
```shell
76+
$ graalpython --jvm --polyglot polyglot_example.py
77+
```
78+
79+
This example matches Python strings using the JavaScript regular expression object
80+
and Python reads the captured group from the JavaScript result and prints: `Here
81+
is what we found: 'This string was matched by Graal.js'`.
82+
83+
As a more complex example, we can read a file using R, process the data in
84+
Python, and use R again to display the resulting data image, using both R and
85+
Python libraries in conjunction. To run it, first install the
86+
required R library:
87+
```shell
88+
$ R -e 'install.packages("https://www.rforge.net/src/contrib/jpeg_0.1-8.tar.gz", repos=NULL)'
89+
```
90+
91+
This example also uses [image_magix.py](http://graalvm.org/docs/examples/image_magix.py) and works
92+
on a JPEG image input (you can try with [this image](https://www.graalvm.org/resources/img/python_demo_picture.jpg)). These files have to be in the same folder the script below is located in and executed from.
93+
94+
```python
95+
import polyglot
96+
import sys
97+
import time
98+
sys.path.insert(0, ".")
99+
from image_magix import Image
100+
101+
load_jpeg = polyglot.eval(string="""function(file.name) {
102+
library(jpeg)
103+
jimg <- readJPEG(file.name)
104+
jimg <- jimg*255
105+
jimg
106+
}""", language="R")
107+
108+
raw_data = load_jpeg("python_demo_picture.jpg")
109+
110+
# the dimensions are R attributes; define function to access them
111+
getDim = polyglot.eval(string="function(v, pos) dim(v)[[pos]]", language="R")
112+
113+
# Create object of Python class 'Image' with loaded JPEG data
114+
image = Image(getDim(raw_data, 2), getDim(raw_data, 1), raw_data)
115+
116+
# Run Sobel filter
117+
result = image.sobel()
118+
119+
draw = polyglot.eval(string="""function(processedImgObj) {
120+
require(grDevices)
121+
require(grid)
122+
mx <- matrix(processedImgObj$`@data`/255, nrow=processedImgObj$`@height`, ncol=processedImgObj$`@width`)
123+
grDevices:::awt()
124+
grid.raster(mx, height=unit(nrow(mx),"points"))
125+
}""", language="R")
126+
127+
draw(result)
128+
time.sleep(10)
129+
```
130+
131+
## Java Interoperability
132+
49133
Finally, to interoperate with Java (only when running on the JVM), you can use
50134
the `java` module:
51135
```python
@@ -94,3 +178,6 @@ print(java.is_object(ArrayList)) # prints True, symbols are also host objects
94178
print(java.is_function(my_list.add))# prints True, the add method of ArrayList
95179
print(java.instanceof(my_list, ArrayList)) # prints True
96180
```
181+
182+
See the [Polyglot Programming](https://www.graalvm.org/docs/reference-manual/polyglot-programming/) and the [Embed Languages](https://www.graalvm.org/docs/reference-manual/embed-languages/#Function_Python) reference
183+
for more information about interoperability with other programming languages.
Lines changed: 49 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# About Jython Compatibility
1+
# Jython Compatibility
22

33
Full Jython compatibility is not a goal of this project. One major reason for
44
this is that most Jython code that uses Java integration will be based on a
@@ -21,23 +21,22 @@ features of Jython are more expensive at runtime, and thus are hidden behind a
2121
command line flag on Graal: `--python.EmulateJython`.
2222

2323
### Importing
24-
2524
Import statements allow you to import Java classes, but (unlike Jython), only
26-
packages in the `java` namespace can be directly imported. So this works:
27-
28-
import java.lang as lang
29-
30-
But this doesn't:
31-
32-
import javax.swing as swing
33-
from javax.swing import *
34-
35-
Instead, you'll have to import one of the classes you're interested in directly:
36-
37-
import javax.swing.Window as Window
25+
packages in the `java` namespace can be directly imported. This will work:
26+
```
27+
import java.lang as lang
28+
```
29+
But this will not:
30+
```
31+
import javax.swing as swing
32+
from javax.swing import *
33+
```
34+
Instead, you will have to import one of the classes you are interested in directly:
35+
```
36+
import javax.swing.Window as Window
37+
```
3838

3939
### Basic Object Usage
40-
4140
Constructing and working with Java objects and classes is done with natural
4241
Python syntax. The methods of Java objects can also be retrieved and passed
4342
around as first class objects (bound to their instance) the same as Python
@@ -52,7 +51,6 @@ methods:
5251
1672896916
5352

5453
### Java-to-Python Types: Automatic Conversion
55-
5654
Method overloads are resolved by matching the Python arguments in a best-effort
5755
manner to the available parameter types. This is also when data conversion
5856
happens. The goal here is to make using Java from Python as smooth as
@@ -76,16 +74,15 @@ when the elements fit into those Java primitive types.
7674
| java.lang.Object | Any object |
7775

7876
### Special Jython Modules
79-
80-
We do not offer any of the special Jython modules. For example, the `jarray`
77+
Any of the special Jython modules are not available. For example, the `jarray`
8178
module on Jython allows construction of primitive Java arrays. This can be
8279
achieved as follows on GraalPython:
8380

8481
>>> import java
8582
>>> java.type("int[]")(10)
8683

87-
Code that only needs to pass a Java array can also use Python types. However,
88-
implicitly this may entail a copy of the array data, which can be deceiving when
84+
The code that only needs to pass a Java array can also use Python types. However,
85+
implicitly, this may entail a copy of the array data, which can be deceiving when
8986
using Java arrays as output parameters:
9087

9188
>>> i = java.io.ByteArrayInputStream(b"foobar")
@@ -101,8 +98,7 @@ using Java arrays as output parameters:
10198
[98, 97, 122]
10299

103100
### Exceptions from Java
104-
105-
Catching all kinds of Java exceptions comes with a performance penalty, and is
101+
Catching all kinds of Java exceptions comes with a performance penalty and is
106102
only enabled with the `--python.EmulateJython` flag.
107103

108104
>>> import java
@@ -115,7 +111,6 @@ only enabled with the `--python.EmulateJython` flag.
115111
7 >= 0
116112

117113
### Java Collections
118-
119114
There is no automatic mapping of the Python syntax for accessing dictionary
120115
elements to the `java.util` mapping and list classes' ` get`, `set`, or `put`
121116
methods. To use these mapping and list clases, you must call the Java methods:
@@ -125,48 +120,48 @@ methods. To use these mapping and list clases, you must call the Java methods:
125120
>>> ht.get("foo")
126121
'bar'
127122

128-
We also do not support Python-style iteration of Java `java.util.Enumerable`,
129-
`java.util.Iterator`, or `java.lang.Iterable`. For these, you'll have to use a
123+
The Python-style iteration of Java `java.util.Enumerable`,
124+
`java.util.Iterator`, or `java.lang.Iterable` is not supported. For these, you will have to use a
130125
`while` loop and use the `hasNext()` and `next()` (or equivalent) methods.
131126

132127
### No Inheriting from Java
133-
134128
Python classes cannot inherit from Java classes. A workaround can be to create a
135-
flexible subclass in Java, compile it, and use delegation instead. Take this
129+
flexible subclass in Java, compile it and use delegation instead. Take this
136130
example:
131+
```
132+
import java.util.logging.Handler;
137133
138-
import java.util.logging.Handler;
139-
140-
public class PythonHandler extends Handler {
141-
private final Value pythonDelegate;
142-
143-
public PythonHandler(Value pythonDelegate) {
144-
this.pythonDelegate = pythonDelegate;
145-
}
134+
public class PythonHandler extends Handler {
135+
private final Value pythonDelegate;
146136
147-
public void publish(LogRecord record) {
148-
pythonDelegate.invokeMember("publish", record);
149-
}
137+
public PythonHandler(Value pythonDelegate) {
138+
this.pythonDelegate = pythonDelegate;
139+
}
150140
151-
public void flush() {
152-
pythonDelegate.invokeMember("flush");
153-
}
141+
public void publish(LogRecord record) {
142+
pythonDelegate.invokeMember("publish", record);
143+
}
154144
155-
public void close() {
156-
pythonDelegate.invokeMember("close");
157-
}
145+
public void flush() {
146+
pythonDelegate.invokeMember("flush");
158147
}
159148
149+
public void close() {
150+
pythonDelegate.invokeMember("close");
151+
}
152+
}
153+
```
160154
Then you can use it like this in Python:
155+
```
156+
from java.util.logging import LogManager, Logger
161157
162-
from java.util.logging import LogManager, Logger
163-
164-
class MyHandler():
165-
def publish(self, logRecord): print("[python]", logRecord.toString())​
166-
def flush(): pass​
167-
def close(): pass
168-
169-
LogManager.getLogManager().addLogger(Logger('my.python.logger', None, MyHandler()))
158+
class MyHandler():
159+
def publish(self, logRecord): print("[python]", logRecord.toString())​
160+
def flush(): pass​
161+
def close(): pass
162+
163+
LogManager.getLogManager().addLogger(Logger('my.python.logger', None, MyHandler()))
164+
```
170165

171166
## Embedding Python into Java
172167

@@ -176,11 +171,8 @@ do not offer any in this case. Existing code using Jython depends directly on
176171
the Jython package (for example, in the Maven configuration), because the Java
177172
code has references to Jython internal classes such as `PythonInterpreter`.
178173

179-
For Graal Python, no dependency other than on the [GraalVM
180-
SDK](https://mvnrepository.com/artifact/org.graalvm.sdk/graal-sdk) is
174+
For Graal Python, no dependency other than on the [GraalVM SDK](https://mvnrepository.com/artifact/org.graalvm.sdk/graal-sdk) is
181175
required. There are no APIs particular to Python that are exposed, and
182176
everything is done through the GraalVM API. Important to know is that as long as
183177
your application is executed on a GraalVM with the Python language installed,
184-
you can embed Python in your programs. Please refer to [our embedding
185-
documentation](https://www.graalvm.org/docs/reference-manual/embed/#Function_Python)
186-
for more details.
178+
you can embed Python in your programs. For more detail, refer to the [Embed Languages](https://www.graalvm.org/docs/reference-manual/embed-languages/#Function_Python) reference.

0 commit comments

Comments
 (0)