Skip to content

Commit a4c3b64

Browse files
committed
[GR-52297][GR-52501] Update numpy and cython
PullRequest: graalpython/3229
2 parents ecb56b5 + c9dbfb4 commit a4c3b64

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1281
-3617
lines changed

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,6 @@ _Py_c_abs(Py_complex z)
221221
return result;
222222
}
223223

224-
#if 0 // GraalPy change
225224
static PyObject *
226225
complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
227226
{
@@ -232,7 +231,6 @@ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
232231
((PyComplexObject *)op)->cval = cval;
233232
return op;
234233
}
235-
#endif // GraalPy change
236234

237235
PyObject *
238236
PyComplex_FromCComplex(Py_complex cval)
@@ -241,8 +239,7 @@ PyComplex_FromCComplex(Py_complex cval)
241239
return GraalPyComplex_FromDoubles(cval.real, cval.imag);
242240
}
243241

244-
#if 0 // GraalPy change
245-
static PyObject *
242+
PyAPI_FUNC(PyObject *) // GraalPy change: expose the function for downcalls
246243
complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
247244
{
248245
Py_complex c;
@@ -251,6 +248,7 @@ complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
251248
return complex_subtype_from_c_complex(type, c);
252249
}
253250

251+
#if 0 // GraalPy change
254252
PyObject *
255253
PyComplex_FromDoubles(double real, double imag)
256254
{
@@ -259,29 +257,33 @@ PyComplex_FromDoubles(double real, double imag)
259257
c.imag = imag;
260258
return PyComplex_FromCComplex(c);
261259
}
260+
#endif // GraalPy change
262261

263262
double
264263
PyComplex_RealAsDouble(PyObject *op)
265264
{
266-
if (PyComplex_Check(op)) {
265+
// GraalPy change: different implementation
266+
if (!points_to_py_handle_space(op) && PyComplex_Check(op)) {
267267
return ((PyComplexObject *)op)->cval.real;
268268
}
269269
else {
270-
return PyFloat_AsDouble(op);
270+
return GraalPyTruffleComplex_RealAsDouble(op);
271271
}
272272
}
273273

274274
double
275275
PyComplex_ImagAsDouble(PyObject *op)
276276
{
277-
if (PyComplex_Check(op)) {
277+
// GraalPy change: different implementation
278+
if (!points_to_py_handle_space(op) && PyComplex_Check(op)) {
278279
return ((PyComplexObject *)op)->cval.imag;
279280
}
280281
else {
281-
return 0.0;
282+
return GraalPyTruffleComplex_ImagAsDouble(op);
282283
}
283284
}
284285

286+
#if 0 // GraalPy change
285287
static PyObject *
286288
try_complex_special_method(PyObject *op)
287289
{
@@ -320,6 +322,10 @@ Py_complex
320322
PyComplex_AsCComplex(PyObject *op)
321323
{
322324
// GraalPy change: different implementation
325+
/* If op is already of type PyComplex_Type, return its value */
326+
if (!points_to_py_handle_space(op) && PyComplex_Check(op)) {
327+
return ((PyComplexObject *)op)->cval;
328+
}
323329
PyObject* parts = GraalPyTruffleComplex_AsCComplex(op);
324330
Py_complex result;
325331
if(parts != NULL) {

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -73,3 +73,21 @@ _Py_HashPointer(const void *p)
7373
}
7474
return x;
7575
}
76+
77+
/* taken from CPython */
78+
Py_hash_t
79+
_Py_HashDouble(PyObject *inst, double v)
80+
{
81+
int e, sign;
82+
double m;
83+
Py_uhash_t x, y;
84+
85+
if (!Py_IS_FINITE(v)) {
86+
if (Py_IS_INFINITY(v))
87+
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
88+
else
89+
return _Py_HashPointer(inst);
90+
}
91+
// GraalPy change: different implementation
92+
return Graal_PyTruffle_HashDouble(v);
93+
}

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_complex.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@
3636
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
39+
import operator
40+
41+
from . import CPyExtTestCase, CPyExtFunction, unhandled_error_compare, CPyExtType, is_native_object
3942

40-
import sys
41-
from . import CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare, GRAALPYTHON
4243
__dir__ = __file__.rpartition("/")[0]
4344

4445

@@ -84,13 +85,30 @@ class DummyComplexSubclass(complex):
8485
pass
8586

8687

88+
NativeComplexSubclass = CPyExtType(
89+
"NativeComplexSubclass",
90+
'',
91+
struct_base='PyComplexObject base;',
92+
tp_base='&PyComplex_Type',
93+
tp_new='0',
94+
tp_alloc='0',
95+
tp_free='0',
96+
)
97+
98+
99+
class ManagedNativeComplexSubclass(NativeComplexSubclass):
100+
pass
101+
102+
87103
class TestPyComplex(CPyExtTestCase):
88104

89105
test_PyComplex_AsCComplex = CPyExtFunction(
90106
lambda args: True,
91107
lambda: (
92108
(complex(1.0, 2.0), 1.0, 2.0),
93109
(DummyComplexSubclass(2.0, 3.0), 2.0, 3.0),
110+
(NativeComplexSubclass(1.0, 2.0), 1.0, 2.0),
111+
(ManagedNativeComplexSubclass(1.0, 2.0), 1.0, 2.0),
94112
),
95113
code='''int isNaN(double d) {
96114
return d != d;
@@ -122,6 +140,8 @@ class TestPyComplex(CPyExtTestCase):
122140
lambda: (
123141
(complex(1.0, 2.0), ),
124142
(DummyComplexSubclass(2.0, 3.0), ),
143+
(NativeComplexSubclass(1.0, 2.0),),
144+
(ManagedNativeComplexSubclass(1.0, 2.0),),
125145
),
126146
code='''
127147
PyObject* wrap_PyComplex_cval(PyObject* obj) {
@@ -143,6 +163,8 @@ class TestPyComplex(CPyExtTestCase):
143163
(complex(0.0, 2.0), ),
144164
(complex(1.0, 2.0), ),
145165
(DummyComplexSubclass(2.0, 3.0), ),
166+
(NativeComplexSubclass(1.0, 2.0),),
167+
(ManagedNativeComplexSubclass(1.0, 2.0),),
146168
("10.0", ),
147169
),
148170
resultspec="f",
@@ -157,6 +179,8 @@ class TestPyComplex(CPyExtTestCase):
157179
(complex(0.0, 2.0), ),
158180
(complex(1.0, 2.0), ),
159181
(DummyComplexSubclass(2.0, 3.0), ),
182+
(NativeComplexSubclass(1.0, 2.0),),
183+
(ManagedNativeComplexSubclass(1.0, 2.0),),
160184
("10.0", ),
161185
),
162186
resultspec="f",
@@ -176,3 +200,35 @@ class TestPyComplex(CPyExtTestCase):
176200
arguments=["double r", "double i"],
177201
cmpfunc=unhandled_error_compare
178202
)
203+
204+
205+
class TestNativeComplex:
206+
def test_builtins_on_subclass(self):
207+
for t in [NativeComplexSubclass, ManagedNativeComplexSubclass]:
208+
c = t(2, 3)
209+
assert is_native_object(c)
210+
assert type(c) is t
211+
assert c.real == 2
212+
assert c.imag == 3
213+
assert type(complex(c)) is complex
214+
assert complex(c) == 2 + 3j
215+
assert c == 2 + 3j
216+
assert t(2) == 2
217+
assert t(2.4) == 2.4
218+
219+
def assert_op_same(f):
220+
assert f(t(2, 3)) == f(2 + 3j)
221+
222+
assert_op_same(abs)
223+
assert_op_same(repr)
224+
assert_op_same(format)
225+
assert_op_same(bool)
226+
assert_op_same(hash)
227+
assert_op_same(operator.pos)
228+
assert_op_same(operator.neg)
229+
assert_op_same(lambda x: x + (1 + 2j))
230+
assert_op_same(lambda x: x - (1 + 2j))
231+
assert_op_same(lambda x: x * (1 + 2j))
232+
assert_op_same(lambda x: x / (1 + 2j))
233+
assert_op_same(lambda x: x ** (1 + 2j))
234+
assert_op_same(lambda x: x.conjugate())

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -62,6 +62,42 @@ def test_int_subclassing():
6262
assert str(MAXREPEAT) == "MAXREPEAT"
6363

6464

65+
def test_abs():
66+
assert abs(True) == 1
67+
assert abs(False) == 0
68+
assert abs(0) == 0
69+
assert abs(1) == 1
70+
assert abs(-1) == 1
71+
assert abs(-2147483647-1) == 2147483648 # Smallest int
72+
assert abs(-2147483647) == 2147483647
73+
assert abs(-9223372036854775807-1) == 9223372036854775808 # Smallest long
74+
assert abs(-9223372036854775807) == 9223372036854775807
75+
assert abs(-BIG_NUMBER) == BIG_NUMBER
76+
assert abs(-50.0) == 50.0
77+
assert repr(abs(-0.0)) == '0.0'
78+
79+
class CustomInt(int):
80+
def __int__(self):
81+
return 100
82+
83+
def __index__(self):
84+
return 100
85+
86+
class CustomFloat(float):
87+
def __float__(self):
88+
return 100.0
89+
assert abs(CustomInt(-3)) == 3
90+
assert abs(CustomFloat(-3.0)) == 3.0
91+
92+
try:
93+
abs(object())
94+
except TypeError:
95+
pass
96+
else:
97+
assert False, "Expected TypeError"
98+
99+
100+
65101
def test_bigint():
66102
i = int(BIG_NUMBER)
67103
assert isinstance(i, int)

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -36,9 +36,12 @@
3636
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
39+
from pathlib import Path
40+
3941
import sys
4042

41-
from pathlib import Path
43+
SECTIONS = frozenset({'rules', 'add-sources'})
44+
RULE_KEYS = frozenset({'version', 'patch', 'subdir', 'dist-type', 'install-priority', 'ignore-rule-on-llvm'})
4245

4346
if sys.implementation.name == 'graalpy':
4447
import ensurepip
@@ -53,12 +56,12 @@
5356

5457

5558
def validate_metadata(package_dir, metadata):
56-
if unexpected_keys := set(metadata) - {'rules', 'add-sources'}:
59+
if unexpected_keys := set(metadata) - SECTIONS:
5760
assert False, f"Unexpected top-level metadata keys: {unexpected_keys}"
5861
patches = set()
5962
if rules := metadata.get('rules'):
6063
for rule in rules:
61-
if unexpected_keys := set(rule) - {'version', 'patch', 'subdir', 'dist-type', 'install-priority'}:
64+
if unexpected_keys := set(rule) - RULE_KEYS:
6265
assert False, f"Unexpected rule keys: {unexpected_keys}"
6366
if patch := rule.get('patch'):
6467
patch_path = package_dir / patch
@@ -71,6 +74,8 @@ def validate_metadata(package_dir, metadata):
7174
if version := rule.get('version'):
7275
# Just try that it doesn't raise
7376
SpecifierSet(version)
77+
if ignore_on_llvm := rule.get('ignore-rule-on-llvm'):
78+
assert isinstance(ignore_on_llvm, bool)
7479
for file in package_dir.iterdir():
7580
assert file.name == 'metadata.toml' or file in patches, f"Dangling file in patch directory: {file}"
7681
if add_sources := metadata.get('add-sources'):

0 commit comments

Comments
 (0)