Skip to content

Commit b6d7748

Browse files
committed
[GR-47946] Fix more pandas failures
2 parents c6e2bf8 + 35b3e3a commit b6d7748

File tree

6 files changed

+121
-2
lines changed

6 files changed

+121
-2
lines changed

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

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2023, 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
@@ -229,6 +229,58 @@ def test_compare(self):
229229
self.assertTrue(i > f)
230230
self.assertTrue(i >= f)
231231

232+
def test_compare_infinite(self):
233+
nan = float('nan')
234+
inf = float('inf')
235+
ninf = float('-inf')
236+
positives = [0.0, 1.0, 1, 1125899906842624, 1 << 100]
237+
negatives = [-x for x in positives]
238+
for num in [nan, inf, ninf, *positives, *negatives]:
239+
self.assertFalse(nan == num)
240+
self.assertTrue(nan != num)
241+
self.assertFalse(nan < num)
242+
self.assertFalse(nan <= num)
243+
self.assertFalse(nan > num)
244+
self.assertFalse(nan >= num)
245+
self.assertFalse(num == nan)
246+
self.assertTrue(num != nan)
247+
self.assertFalse(num < nan)
248+
self.assertFalse(num <= nan)
249+
self.assertFalse(num > nan)
250+
self.assertFalse(num >= nan)
251+
252+
self.assertTrue(inf == inf)
253+
self.assertFalse(inf != inf)
254+
for num in [ninf, *positives, *negatives]:
255+
self.assertFalse(inf == num)
256+
self.assertFalse(num == inf)
257+
self.assertTrue(inf != num)
258+
self.assertTrue(num != inf)
259+
self.assertTrue(inf > num)
260+
self.assertTrue(inf >= num)
261+
self.assertFalse(inf < num)
262+
self.assertFalse(inf <= num)
263+
self.assertFalse(num > inf)
264+
self.assertFalse(num >= inf)
265+
self.assertTrue(num < inf)
266+
self.assertTrue(num <= inf)
267+
268+
self.assertTrue(ninf == ninf)
269+
self.assertFalse(ninf != ninf)
270+
for num in [*positives, *negatives]:
271+
self.assertFalse(ninf == num)
272+
self.assertFalse(num == ninf)
273+
self.assertTrue(ninf != num)
274+
self.assertTrue(num != ninf)
275+
self.assertFalse(ninf > num)
276+
self.assertFalse(ninf >= num)
277+
self.assertTrue(ninf < num)
278+
self.assertTrue(ninf <= num)
279+
self.assertTrue(num > ninf)
280+
self.assertTrue(num >= ninf)
281+
self.assertFalse(num < ninf)
282+
self.assertFalse(num <= ninf)
283+
232284

233285
fromHex = float.fromhex
234286

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@
4444

4545
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ClearNativeWrapperNode;
4646
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
47+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
4748
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
4849
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleReleaser;
4950
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
51+
import com.oracle.graal.python.runtime.PythonContext;
5052
import com.oracle.graal.python.util.PythonUtils;
5153
import com.oracle.truffle.api.TruffleLogger;
5254
import com.oracle.truffle.api.dsl.Cached;
@@ -117,6 +119,7 @@ static void doNativeWrapper(PythonNativeWrapper nativeWrapper,
117119
if (HandlePointerConverter.pointsToPyHandleSpace(nativePointer)) {
118120
HandleReleaser.release(nativePointer);
119121
} else {
122+
CApiTransitions.nativeLookupRemove(PythonContext.get(callReleaseHandleNode).nativeContext, nativePointer);
120123
callReleaseHandleNode.call(NativeCAPISymbol.FUN_PY_TRUFFLE_FREE, nativePointer);
121124
}
122125
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,9 @@ public static double compareDoubleToLargeInt(double v, PInt w) {
792792

793793
@TruffleBoundary
794794
private static double compareUsingBigDecimal(double v, BigInteger w) {
795+
if (!Double.isFinite(v)) {
796+
return v;
797+
}
795798
return new BigDecimal(v).compareTo(new BigDecimal(w));
796799
}
797800
}

graalpython/lib-graalpython/modules/autopatch_capi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def consume_whitespace_forward(idx):
154154
# avoid direct access:
155155
r'\W(ob_type)\W': (replace_field_access, 'Py_TYPE(%receiver)'),
156156
r'\W(ob_refcnt)\W': (replace_field_access, 'Py_REFCNT(%receiver)'),
157-
r'\W(ob_item)\W': (replace_field_access, 'PySequence_Fast_ITEMS(%receiver)'),
157+
r'\W(ob_item)\W': (replace_field_access, 'PySequence_Fast_ITEMS((PyObject*)%receiver)'),
158158
r'^\s*()(std::)?free\((const_cast<char \*>)?\(?\w+->m_ml->ml_doc\)?\);': (simple_replace, '//'),
159159
r'\W(m_ml\s*->\s*ml_doc)\W': (replace_field_access, 'PyObject_GetDoc((PyObject*)(%receiver))', 'PyObject_SetDoc((PyObject*)(%receiver), %value)'),
160160
# already defined by GraalPy:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
[[rules]]
22
version = '== 1.4.3'
33
patch = 'pandas-1.4.3.patch'
4+
dist-type = 'sdist'
45

56
[[rules]]
67
# pin to 1.5.2
78
install-priority = 10
89
version = '== 1.5.2'
910
patch = 'pandas-1.5.2.patch'
11+
dist-type = 'sdist'

graalpython/lib-graalpython/patches/pandas/pandas-1.5.2.patch

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,62 @@
1+
diff --git a/pandas/_libs/src/klib/khash_python.h b/pandas/_libs/src/klib/khash_python.h
2+
index 5ae3c19..b9c6784 100644
3+
--- a/pandas/_libs/src/klib/khash_python.h
4+
+++ b/pandas/_libs/src/klib/khash_python.h
5+
@@ -178,28 +178,30 @@ int PANDAS_INLINE floatobject_cmp(PyFloatObject* a, PyFloatObject* b){
6+
// PyObject_RichCompareBool for complexobjects has a different behavior
7+
// needs to be replaced
8+
int PANDAS_INLINE complexobject_cmp(PyComplexObject* a, PyComplexObject* b){
9+
+ Py_complex a_cval = PyComplex_AsCComplex((PyObject*)a);
10+
+ Py_complex b_cval = PyComplex_AsCComplex((PyObject*)b);
11+
return (
12+
- Py_IS_NAN(a->cval.real) &&
13+
- Py_IS_NAN(b->cval.real) &&
14+
- Py_IS_NAN(a->cval.imag) &&
15+
- Py_IS_NAN(b->cval.imag)
16+
+ Py_IS_NAN(a_cval.real) &&
17+
+ Py_IS_NAN(b_cval.real) &&
18+
+ Py_IS_NAN(a_cval.imag) &&
19+
+ Py_IS_NAN(b_cval.imag)
20+
)
21+
||
22+
(
23+
- Py_IS_NAN(a->cval.real) &&
24+
- Py_IS_NAN(b->cval.real) &&
25+
- a->cval.imag == b->cval.imag
26+
+ Py_IS_NAN(a_cval.real) &&
27+
+ Py_IS_NAN(b_cval.real) &&
28+
+ a_cval.imag == b_cval.imag
29+
)
30+
||
31+
(
32+
- a->cval.real == b->cval.real &&
33+
- Py_IS_NAN(a->cval.imag) &&
34+
- Py_IS_NAN(b->cval.imag)
35+
+ a_cval.real == b_cval.real &&
36+
+ Py_IS_NAN(a_cval.imag) &&
37+
+ Py_IS_NAN(b_cval.imag)
38+
)
39+
||
40+
(
41+
- a->cval.real == b->cval.real &&
42+
- a->cval.imag == b->cval.imag
43+
+ a_cval.real == b_cval.real &&
44+
+ a_cval.imag == b_cval.imag
45+
);
46+
}
47+
48+
@@ -276,8 +278,9 @@ Py_hash_t PANDAS_INLINE floatobject_hash(PyFloatObject* key) {
49+
50+
// replaces _Py_HashDouble with _Pandas_HashDouble
51+
Py_hash_t PANDAS_INLINE complexobject_hash(PyComplexObject* key) {
52+
- Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(key->cval.real);
53+
- Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(key->cval.imag);
54+
+ Py_complex cval = PyComplex_AsCComplex((PyObject*)key);
55+
+ Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(cval.real);
56+
+ Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(cval.imag);
57+
if (realhash == (Py_uhash_t)-1 || imaghash == (Py_uhash_t)-1) {
58+
return -1;
59+
}
160
diff --git a/pandas/io/common.py b/pandas/io/common.py
261
index f31de63..1858912 100644
362
--- a/pandas/io/common.py

0 commit comments

Comments
 (0)