You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[GR-42711] Inherit from single-trait classes directly
* Avoids Foreign*Type classes.
* It means ForeignException is now inherited by all foreign exceptions.
* Expose polyglot.ForeignObject and all single-trait classes on the polyglot module.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ language runtime. The main focus is on user-observable behavior of the engine.
9
9
* When calling a method on a foreign object in Python code, Python methods are now prioritized over foreign members.
10
10
* Added `polyglot.register_interop_type` and `@polyglot.interop_type` to define custom Python methods for a given foreign class/type. See [the documentation](https://github.com/oracle/graalpython/blob/master/docs/user/Interoperability.md#the-interoperability-extension-api) for more information.
11
11
* Foreign objects are now given a Python class corresponding to their interop traits.
12
-
* Foreign lists now inherit from Python `list`, foreign dictionaries from `dict`, foreign strings from `str`, foreign iterators from `iterator`, foreign exceptions from `BaseException`, foreign numbers from `ForeignNumberType` and foreign none/null from `NoneType`.
12
+
* Foreign lists now inherit from Python `list`, foreign dictionaries from `dict`, foreign strings from `str`, foreign iterators from `iterator`, foreign exceptions from `BaseException`, foreign numbers from `polyglot.ForeignNumber` and foreign none/null from `NoneType`.
13
13
* This means all Python methods of these types are available on the corresponding foreign objects, which behave as close as possible as if they were Python objects.
14
14
* See [the documentation](https://github.com/oracle/graalpython/blob/master/docs/user/Interoperability.md#interacting-with-foreign-objects-from-python-scripts) for more information.
15
15
* Remove support for running with Sulong managed both in embeddings as well as through the `graalpy-managed` launcher.
This means all Python methods of these types are available on the corresponding foreign objects, which behave as close as possible as if they were Python objects:
@@ -89,18 +89,7 @@ h |= {3: 6} # {1: 2, 3: 6}
89
89
h == {1: 2, 3: 6} # True
90
90
```
91
91
92
-
Specifically:
93
-
* Foreign lists inherit from Python `list`
94
-
* Foreign dictionaries inherit from `dict`
95
-
* Foreign strings inherit from `str`
96
-
* Foreign iterators inherit from `iterator`
97
-
* Foreign exceptions inherit from `BaseException`
98
-
* Foreign numbers inherit from `ForeignNumberType` (since `InteropLibrary` has no way to differentiate integers and floats, but see below)
99
-
* Foreign none/null inherit from `NoneType`
100
-
* Other foreign objects inherit from `foreign`
101
-
102
-
Note that Java primitives `byte`, `short`, `int`, `long` and `BigInteger` values are considered Python `int` objects,
103
-
and Java primitives `float`, `double` values are considered Python `float` objects.
92
+
See [this section](#interop-types-to-python) for more interop traits and how they map to Python types.
104
93
105
94
## Interacting with other dynamic languages from Python scripts
106
95
@@ -226,35 +215,34 @@ The `polyglot` module can be used to expose Python objects to JVM languages and
226
215
227
216
## Mapping Types between Python and Other Languages
228
217
229
-
The interop protocol defines different "types" which can overlap in all kinds of ways and have restrictions on how they can interact with Python.
218
+
The interop protocol defines different "types/traits" which can overlap in all kinds of ways and have restrictions on how they can interact with Python.
230
219
231
220
### Interop Types to Python
232
221
233
-
Most importantly and upfront: all foreign objects passed into Python have the Python type `foreign`.
234
-
There is no emulation of (for example) objects that are of interop type "boolean" to have the Python type `bool`.
235
-
This is because interop types can overlap in ways that the Python built-in types cannot, and we have yet to define which type should take precedence and such situations.
236
-
We do expect to change this in the future, however.
237
-
For now, the `foreign` type defines all of the Python special methods for type conversion that are used throughout the interpreter (methods such as `__add__`, `__int__`, `__str__`, `__getitem__`, and so on)
238
-
and these try to "do the right thing" based on the interop type (or raise an exception).
222
+
All foreign objects passed into Python have the Python type `polyglot.ForeignObject` or a subclass.
239
223
240
224
Types not listed in the table below have no special interpretation in Python.
| `null` | `null` is like `None`. Important to know: interop `null` values are all identical to `None`. JavaScript defines two "null-like" values; `undefined` and `null`, which are *not* identical, but when passed to Python, they are treated so. |
245
-
| `boolean` | `boolean` behaves like Python booleans, including the fact that in Python, all booleans are also integers (1 and 0 for true and false, respectively). |
246
-
| `number` | `number` Behaves like Python numbers. Python only has one integer and one floating point type, but ranges are imported in some places such as typed arrays. |
247
-
| `string` | Behaves in the same way as a Python string. |
248
-
| `buffer` | Buffers are also a concept in Python's native API (albeit slightly different). Interop buffers are treated in the same was as Python buffers in some places (such as `memoryview`) to avoid copies of data. |
249
-
|`array`| An `array` can be used with subscript access in the same way as Python lists, with integers and slices as indices. |
250
-
|`hash`|A`hash` can be used with subscript access in the same way as Python dictionaries, with any "hashable" object as a key. "Hashable" follows Python semantics: generally every interop type with an identity is deemed "hashable". Note that if an interop object is of type `Array`**and**`Hash`, the behavior of subscript access is undefined. |
251
-
|`members`| An object of type `members` can be read using conventional Python `.` notation or `getattr` and related functions. |
252
-
|`iterable`| An `iterable` is treated in the same way as any Python object with an `__iter__`method. That is, it can be used in a loop and other places that accept Python iterables. |
253
-
|`iterator`| An `iterator` is treated in the same way as any Python object with a `__next__` method. |
254
-
|`exception`| An `exception` can be caught in a generic `except` clause. |
255
-
|`MetaObject`| Meta objects can be used in subtype and `isinstance` checks. |
256
-
|`executable`| An `executable` object can be executed as a function, but never with keyword arguments. |
257
-
| `instantiable` | An `instantiable` object can be called just like a Python type, but never with keyword arguments. |
226
+
| Interop Type | Inherits from | Python Interpretation |
| `null` | ForeignNone, `NoneType` | `null` is like `None`. Important to know: interop `null` values are all identical to `None`. JavaScript defines two "null-like" values; `undefined` and `null`, which are *not* identical, but when passed to Python, they are treated so. |
229
+
| `boolean` | ForeignBoolean | `boolean` behaves like Python booleans, including the fact that in Python, all booleans are also integers (1 and 0 for true and false, respectively). |
230
+
| `number` | ForeignNumber | `number` behaves like Python numbers. Python only has one integer and one floating point type, but ranges are imported in some places such as typed arrays. |
231
+
| `string` | ForeignString, `str` | Behaves in the same way as a Python string. |
232
+
| `buffer` | ForeignObject | Buffers are also a concept in Python's native API (albeit slightly different). Interop buffers are treated in the same was as Python buffers in some places (such as `memoryview`) to avoid copies of data. |
233
+
|`array`| ForeignList, `list`| An `array` behaves like a Python `list`. |
234
+
|`hash`| ForeignDict, `dict`|A`hash` behaves like a Python `dict`, with any "hashable" object as a key. "Hashable" follows Python semantics: generally every interop type with an identity is deemed "hashable". |
235
+
|`members`| ForeignObject | An object of type `members` can be read using conventional Python `.` notation or `getattr` and related functions. |
236
+
|`iterable`| ForeignIterable | An `iterable` is treated in the same way as any Python object with an `__iter__`method. That is, it can be used in a loop and other places that accept Python iterables. |
237
+
|`iterator`| ForeignIterator, `iterator`| An `iterator` is treated in the same way as any Python object with a `__next__` method. |
238
+
|`exception`| ForeignException, `BaseException`| An `exception` can be caught in a generic `except` clause. |
239
+
|`MetaObject`| ForeignAbstractClass | Meta objects can be used in subtype and `isinstance` checks. |
240
+
|`executable`| ForeignExecutable | An `executable` object can be executed as a function, but never with keyword arguments. |
241
+
| `instantiable` | ForeignInstantiable | An `instantiable` object can be called just like a Python type, but never with keyword arguments. |
242
+
243
+
Foreign numbers inherit from `polyglot.ForeignNumber` and not `int` or `float` because `InteropLibrary` has currently no way to differentiate integers and floats.
244
+
However, when foreign numbers are represented as Java primitives `byte`, `short`, `int`, `long`, they are considered Python `int` objects,
245
+
and when foreign numbers are represented as Java primitives `float`, `double`, they are considered Python `float` objects.
258
246
259
247
### Python to Interop Types
260
248
@@ -360,8 +348,8 @@ class Main {
360
348
```
361
349
#### Interop Types
362
350
The `register_interop_type` API allows the usage of python classes for foreign objects.
363
-
The type of such a foreign object will no longer be `foreign`.
364
-
Instead, it will be a generated class with the registered python classes and `foreign` and as super classes.
351
+
The class of such a foreign object will no longer be `polyglot.ForeignObject` or `polyglot.Foreign*`.
352
+
Instead, it will be a generated class with the registered python classes and `polyglot.ForeignObject`as super class.
365
353
This allows custom mapping of foreign methods and attributes to Python's magic methods or more idiomatic Python code.
0 commit comments