Skip to content

Commit c281c0a

Browse files
committed
Merge remote-tracking branch 'origin/master' into tim/GR-9957/dynamic-cast
2 parents 597e9fd + e8343f9 commit c281c0a

File tree

9 files changed

+233
-73
lines changed

9 files changed

+233
-73
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
This changelog summarizes major changes between GraalVM versions of the Python
44
language runtime. The main focus is on user-observable behavior of the engine.
55

6+
## Version 1.0.0 RC3
7+
8+
* Support for more String encodings
9+
* Implement buffered I/O
10+
* Remove our random module substitute and use the standard library implementation
11+
* Fix a potential thread-safety problem with cached parse trees when multiple Python contexts are used from multiple threads
12+
* Complete support for math module builtins
13+
* C-API improvements to run simple scikit-learn and NumPy examples
14+
* Support the buffer protocol to wrap arbitrary Python sequences with no copy into NumPy arrays
15+
616
## Version 1.0.0 RC2
717

818
* Updates to the polyglot and embedding APIs

graalpython/com.oracle.graal.python.cext/src/object.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ static PyObject* wrap_setattrfunc(setattrfunc f, PyObject* obj, PyObject* unicod
201201
return f(obj, as_char_pointer(unicode), value);
202202
}
203203

204+
static PyObject* wrap_setattrofunc(setattrofunc f, PyObject* obj, PyObject* key, PyObject* item) {
205+
return PyLong_FromLong(f(explicit_cast(obj), explicit_cast(key), explicit_cast(item)));
206+
}
207+
204208
static PyObject* wrap_richcmpfunc(richcmpfunc f, PyObject* a, PyObject* b, PyObject* n) {
205209
return f(a, b, (int)PyLong_AsLong(n));
206210
}
@@ -213,10 +217,26 @@ static PyObject* wrap_objobjargproc(ssizeobjargproc f, PyObject* a, PyObject* id
213217
return PyLong_FromLong(f(a, idx, b));
214218
}
215219

220+
static PyObject* wrap_ssizeargfunc(ssizeargfunc f, PyObject* a, PyObject* size) {
221+
return PyLong_FromLong(f(explicit_cast(a), PyLong_AsSsize_t(size)));
222+
}
223+
216224
static PyObject* wrap_initproc(initproc f, PyObject* a, PyObject* b, PyObject* c) {
217225
return PyLong_FromLong(f(a, b, c));
218226
}
219227

228+
static PyObject* wrap_objobjargproc(objobjargproc f, PyObject* a, PyObject* b, PyObject* c) {
229+
return PyLong_FromLong(f(explicit_cast(a), explicit_cast(b), explicit_cast(c)));
230+
}
231+
232+
static PyObject* wrap_objobjproc(objobjproc f, PyObject* a, PyObject* b) {
233+
return PyLong_FromLong(f(explicit_cast(a), explicit_cast(b)));
234+
}
235+
236+
static PyObject* wrap_inquiry(inquiry f, PyObject* a) {
237+
return PyLong_FromLong(f(explicit_cast(a)));
238+
}
239+
220240
/* very special case: operator '**' has an optional third arg */
221241
static PyObject* wrap_pow(ternaryfunc f, ...) {
222242
int nargs = polyglot_get_arg_count();
@@ -231,6 +251,15 @@ static PyObject* wrap_pow(ternaryfunc f, ...) {
231251
return Py_NoValue;
232252
}
233253

254+
static PyObject* wrap_lenfunc(lenfunc f, PyObject* a) {
255+
return PyLong_FromSsize_t(f(explicit_cast(a)));
256+
}
257+
258+
static Py_hash_t wrap_hashfunc(hashfunc f, PyObject* a) {
259+
return PyLong_FromSsize_t(f(explicit_cast(a)));
260+
}
261+
262+
234263
int PyType_Ready(PyTypeObject* cls) {
235264
#define ADD_IF_MISSING(attr, def) if (!(attr)) { attr = def; }
236265
#define ADD_METHOD(m) ADD_METHOD_OR_SLOT(m.ml_name, get_method_flags_cwrapper(m.ml_flags), m.ml_meth, m.ml_flags, m.ml_doc)
@@ -382,11 +411,11 @@ int PyType_Ready(PyTypeObject* cls) {
382411
ADD_SLOT_CONV("__getattr__", wrap_getattrfunc, cls->tp_getattr, -2);
383412
ADD_SLOT_CONV("__setattr__", wrap_setattrfunc, cls->tp_setattr, -3);
384413
ADD_SLOT("__repr__", cls->tp_repr, -1);
385-
ADD_SLOT("__hash__", cls->tp_hash, -1);
414+
ADD_SLOT_CONV("__hash__", wrap_hashfunc, cls->tp_hash, -1);
386415
ADD_SLOT("__call__", cls->tp_call, METH_KEYWORDS | METH_VARARGS);
387416
ADD_SLOT("__str__", cls->tp_str, -1);
388417
ADD_SLOT("__getattr__", cls->tp_getattro, -2);
389-
ADD_SLOT("__setattr__", cls->tp_getattro, -3);
418+
ADD_SLOT_CONV("__setattr__", wrap_setattrofunc, cls->tp_setattro, -3);
390419
ADD_SLOT("__clear__", cls->tp_clear, -1);
391420
ADD_SLOT_CONV("__compare__", wrap_richcmpfunc, cls->tp_richcompare, -3);
392421
ADD_SLOT("__iter__", cls->tp_iter, -1);
@@ -411,7 +440,7 @@ int PyType_Ready(PyTypeObject* cls) {
411440
ADD_SLOT("__neg__", numbers->nb_negative, -1);
412441
ADD_SLOT("__pos__", numbers->nb_positive, -1);
413442
ADD_SLOT("__abs__", numbers->nb_absolute, -1);
414-
ADD_SLOT("__bool__", numbers->nb_bool, -1);
443+
ADD_SLOT_CONV("__bool__", wrap_inquiry, numbers->nb_bool, -1);
415444
ADD_SLOT("__invert__", numbers->nb_invert, -1);
416445
ADD_SLOT("__lshift__", numbers->nb_lshift, -2);
417446
ADD_SLOT("__rshift__", numbers->nb_rshift, -2);
@@ -441,19 +470,19 @@ int PyType_Ready(PyTypeObject* cls) {
441470

442471
PySequenceMethods* sequences = cls->tp_as_sequence;
443472
if (sequences) {
444-
ADD_SLOT("__len__", sequences->sq_length, -1);
473+
ADD_SLOT_CONV("__len__", wrap_lenfunc, sequences->sq_length, -1);
445474
ADD_SLOT("__add__", sequences->sq_concat, -2);
446-
ADD_SLOT("__mul__", sequences->sq_repeat, -2);
447-
ADD_SLOT("__getitem__", sequences->sq_item, -2);
475+
ADD_SLOT_CONV("__mul__", wrap_ssizeargfunc, sequences->sq_repeat, -2);
476+
ADD_SLOT_CONV("__getitem__", wrap_ssizeargfunc, sequences->sq_item, -2);
448477
ADD_SLOT_CONV("__setitem__", wrap_ssizeobjargproc, sequences->sq_ass_item, -3);
449-
ADD_SLOT("__contains__", sequences->sq_contains, -2);
478+
ADD_SLOT_CONV("__contains__", wrap_objobjproc, sequences->sq_contains, -2);
450479
ADD_SLOT("__iadd__", sequences->sq_inplace_concat, -2);
451-
ADD_SLOT("__imul__", sequences->sq_inplace_repeat, -2);
480+
ADD_SLOT_CONV("__imul__", wrap_ssizeargfunc, sequences->sq_inplace_repeat, -2);
452481
}
453482

454483
PyMappingMethods* mappings = cls->tp_as_mapping;
455484
if (mappings) {
456-
ADD_SLOT("__len__", mappings->mp_length, -1);
485+
ADD_SLOT_CONV("__len__", wrap_lenfunc, mappings->mp_length, -1);
457486
ADD_SLOT("__getitem__", mappings->mp_subscript, -2);
458487
ADD_SLOT_CONV("__setitem__", wrap_objobjargproc, mappings->mp_ass_subscript, -3);
459488
}
@@ -470,7 +499,6 @@ int PyType_Ready(PyTypeObject* cls) {
470499
// TODO ...
471500
}
472501

473-
// TODO link subclasses
474502
/* Link into each base class's list of subclasses */
475503
bases = cls->tp_bases;
476504
Py_ssize_t n = PyTuple_GET_SIZE(bases);

graalpython/com.oracle.graal.python.test/src/tests/test_interop.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@
4040
if sys.implementation.name == "graalpython":
4141
import polyglot
4242

43-
4443
def test_import():
4544
imported_cext = polyglot.import_value("python_cext")
4645
import python_cext
4746
assert imported_cext is python_cext
4847

49-
5048
class CustomObject():
5149
field = 42
5250

@@ -56,7 +54,6 @@ def __getitem__(self, item):
5654
def __len__(self):
5755
return 21
5856

59-
6057
class CustomMutable(CustomObject):
6158
_items = {}
6259

@@ -78,15 +75,13 @@ def __setitem__(self, key, item):
7875
def __delitem__(self, key):
7976
del self._items[key]
8077

81-
8278
def test_read():
8379
o = CustomObject()
8480
assert polyglot.__read__(o, "field") == o.field
8581
assert polyglot.__read__(o, 10) == o[10]
8682
assert polyglot.__read__(o, "@field") == o.field
8783
assert polyglot.__read__(o, "[field") == o["field"]
8884

89-
9085
def test_write():
9186
o = CustomMutable()
9287
o2 = CustomObject()
@@ -120,7 +115,6 @@ def test_write():
120115
polyglot.__write__(o2, non_string, 12)
121116
assert getattr(o2, non_string) == 12
122117

123-
124118
def test_remove():
125119
o = CustomMutable()
126120
o.direct_field = 111
@@ -141,26 +135,21 @@ def test_remove():
141135
polyglot.__remove__(o, "grrrr")
142136
assert "grrrr" not in list(o.keys())
143137

144-
145138
def test_execute():
146139
assert polyglot.__execute__(abs, -10) == 10
147140
o = CustomMutable()
148141
assert polyglot.__execute__(o.__getattribute__, "field") == o.field
149142

150-
151143
def test_invoke():
152144
o = CustomMutable()
153145
assert polyglot.__invoke__(o, "__getattribute__", "field") == o.field
154146

155-
156147
def test_new():
157148
assert isinstance(polyglot.__new__(CustomMutable), CustomMutable)
158149

159-
160150
def test_is_null():
161151
assert polyglot.__is_null__(None)
162152

163-
164153
def test_has_size():
165154
import array
166155

@@ -171,15 +160,16 @@ def test_has_size():
171160
assert polyglot.__has_size__(b"")
172161
assert polyglot.__has_size__("")
173162
assert polyglot.__has_size__(range(10))
163+
assert polyglot.__has_size__(CustomObject())
174164

175165
assert not polyglot.__has_size__({})
176166
assert not polyglot.__has_size__(object())
177-
assert not polyglot.__has_size__(CustomObject())
178-
179167

180168
def test_get_size():
181169
called = False
170+
182171
class LenObject():
172+
183173
def __getitem__(self, k):
184174
if k == 0:
185175
return 1
@@ -194,23 +184,20 @@ def __len__(self):
194184
assert polyglot.__get_size__(LenObject()) == 1
195185
assert called
196186

197-
198187
def test_has_keys():
199188
assert not polyglot.__has_keys__(True)
200189
assert polyglot.__has_keys__(None)
201190
assert polyglot.__has_keys__(NotImplemented)
202191
assert not polyglot.__has_keys__(False)
203192
assert polyglot.__has_keys__(object())
204193

205-
206194
def test_keys():
207195
o = CustomObject()
208196
assert len(polyglot.__keys__(o)) == 0
209197
o.my_field = 1
210198
assert len(polyglot.__keys__(o)) == 1
211199
assert "my_field" in polyglot.__keys__(o)
212200

213-
214201
def test_host_lookup():
215202
import java
216203
try:

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ protected void finalizeContext(PythonContext context) {
102102

103103
@Override
104104
protected boolean patchContext(PythonContext context, Env newEnv) {
105+
ensureSysExecutable(context);
105106
ensureHomeInOptions(newEnv);
106107
if (!optionsAllowPreInitializedContext(context, newEnv)) {
107108
// Incompatible options - cannot use pre-initialized context
@@ -114,6 +115,11 @@ protected boolean patchContext(PythonContext context, Env newEnv) {
114115
return true;
115116
}
116117

118+
private static void ensureSysExecutable(PythonContext context) {
119+
PythonModule sys = context.getCore().lookupBuiltinModule("sys");
120+
sys.setAttribute("executable", Compiler.command(new Object[]{"com.oracle.svm.core.posix.GetExecutableName"}));
121+
}
122+
117123
private static boolean optionsAllowPreInitializedContext(PythonContext context, Env newEnv) {
118124
// Verify that the option for using a shared core is the same as
119125
// at image building time

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LocaleModuleBuiltins.java

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.oracle.graal.python.builtins.objects.dict.PDict;
5656
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
5757
import com.oracle.graal.python.runtime.exception.PythonErrorType;
58+
import com.oracle.truffle.api.TruffleOptions;
5859
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5960
import com.oracle.truffle.api.dsl.Fallback;
6061
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -211,62 +212,76 @@ public abstract static class SetLocaleNode extends PythonBuiltinNode {
211212
@Specialization(guards = {"category >= 0", "category <= 6"})
212213
@TruffleBoundary
213214
public Object setLocale(int category, @SuppressWarnings("unused") PNone posixLocaleID) {
214-
Locale.Category displayCategory = Locale.Category.DISPLAY;
215-
Locale.Category formatCategory = Locale.Category.FORMAT;
216-
217-
switch (category) {
218-
case LC_COLLATE:
219-
case LC_CTYPE:
220-
case LC_MESSAGES:
221-
formatCategory = null;
222-
break;
223-
case LC_MONETARY:
224-
case LC_NUMERIC:
225-
case LC_TIME:
226-
displayCategory = null;
227-
break;
228-
case LC_ALL:
229-
default:
230-
}
231-
232215
Locale defaultLocale;
233-
if (displayCategory != null) {
234-
defaultLocale = Locale.getDefault(displayCategory);
216+
Locale.Category displayCategory = null;
217+
Locale.Category formatCategory = null;
218+
if (!TruffleOptions.AOT) {
219+
displayCategory = Locale.Category.DISPLAY;
220+
formatCategory = Locale.Category.FORMAT;
221+
222+
switch (category) {
223+
case LC_COLLATE:
224+
case LC_CTYPE:
225+
case LC_MESSAGES:
226+
formatCategory = null;
227+
break;
228+
case LC_MONETARY:
229+
case LC_NUMERIC:
230+
case LC_TIME:
231+
displayCategory = null;
232+
break;
233+
case LC_ALL:
234+
default:
235+
}
236+
if (displayCategory != null) {
237+
defaultLocale = Locale.getDefault(displayCategory);
238+
} else {
239+
defaultLocale = Locale.getDefault(formatCategory);
240+
}
235241
} else {
236-
defaultLocale = Locale.getDefault(formatCategory);
242+
defaultLocale = Locale.getDefault();
237243
}
244+
238245
return toPosix(defaultLocale);
239246
}
240247

241248
@SuppressWarnings("fallthrough")
242249
@Specialization(guards = {"category >= 0", "category <= 6"})
243250
@TruffleBoundary
244251
public Object setLocale(int category, String posixLocaleID) {
245-
Locale.Category displayCategory = Locale.Category.DISPLAY;
246-
Locale.Category formatCategory = Locale.Category.FORMAT;
247-
248-
switch (category) {
249-
case LC_COLLATE:
250-
case LC_CTYPE:
251-
case LC_MESSAGES:
252-
formatCategory = null;
253-
break;
254-
case LC_MONETARY:
255-
case LC_NUMERIC:
256-
case LC_TIME:
257-
displayCategory = null;
258-
break;
259-
case LC_ALL:
260-
default:
252+
Locale.Category displayCategory = null;
253+
Locale.Category formatCategory = null;
254+
if (!TruffleOptions.AOT) {
255+
displayCategory = Locale.Category.DISPLAY;
256+
formatCategory = Locale.Category.FORMAT;
257+
258+
switch (category) {
259+
case LC_COLLATE:
260+
case LC_CTYPE:
261+
case LC_MESSAGES:
262+
formatCategory = null;
263+
break;
264+
case LC_MONETARY:
265+
case LC_NUMERIC:
266+
case LC_TIME:
267+
displayCategory = null;
268+
break;
269+
case LC_ALL:
270+
default:
271+
}
261272
}
262273

263274
Locale newLocale = fromPosix(posixLocaleID);
264275
if (newLocale != null) {
265-
if (displayCategory != null) {
266-
Locale.setDefault(displayCategory, newLocale);
267-
}
268-
if (formatCategory != null) {
269-
Locale.setDefault(formatCategory, newLocale);
276+
if (!TruffleOptions.AOT) {
277+
if (displayCategory != null) {
278+
Locale.setDefault(displayCategory, newLocale);
279+
}
280+
if (formatCategory != null) {
281+
Locale.setDefault(formatCategory, newLocale);
282+
}
283+
} else {
284+
Locale.setDefault(newLocale);
270285
}
271286
} else {
272287
throw raise(PythonErrorType.ValueError, "unsupported locale setting");

0 commit comments

Comments
 (0)