Skip to content

Commit 62e1e11

Browse files
committed
[GR-68461][GR-68422] Cython 3.1.2; downstream test for pydantic-core
PullRequest: graalpython/3937
2 parents efca839 + 23f7555 commit 62e1e11

File tree

6 files changed

+333
-26
lines changed

6 files changed

+333
-26
lines changed

.github/workflows/downstream-tests.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
- pybind11
1414
- virtualenv
1515
- pyo3
16+
- pydantic-core
1617
os:
1718
- id: ubuntu-latest
1819
platform: linux
@@ -35,11 +36,19 @@ jobs:
3536
run: brew install cmake
3637

3738
- name: Install Rust toolchain
38-
if: ${{ matrix.name == 'pyo3' }}
39+
if: ${{ matrix.name == 'pyo3' || matrix.name == 'pydantic-core' }}
3940
run: |
4041
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
4142
echo "${HOME}/.cargo/bin" >> $GITHUB_PATH
4243
44+
- name: Install uv
45+
if: ${{ matrix.name == 'pydantic-core' }}
46+
run: |
47+
# XXX: Using my fork of uv until https://github.com/astral-sh/uv/pull/15013 is merged and released
48+
# curl -LsSf https://astral.sh/uv/install.sh | sh
49+
cargo install --git https://github.com/msimacek/uv --branch msimacek/graalpy uv
50+
echo "$HOME/.local/bin" >> $GITHUB_PATH
51+
4352
- name: Checkout main repository
4453
uses: actions/checkout@v4
4554

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
diff --git a/Cython/Includes/cpython/array.pxd b/Cython/Includes/cpython/array.pxd
2+
index b5e8880..d420401 100644
3+
--- a/Cython/Includes/cpython/array.pxd
4+
+++ b/Cython/Includes/cpython/array.pxd
5+
@@ -99,7 +99,10 @@ cdef extern from *: # Hard-coded utility code hack.
6+
cdef:
7+
Py_ssize_t ob_size
8+
arraydescr* ob_descr # struct arraydescr *ob_descr;
9+
- __data_union data
10+
+
11+
+ @property
12+
+ cdef inline __data_union data(self) nogil:
13+
+ return __Pyx_PyArray_Data(self)
14+
15+
def __getbuffer__(self, Py_buffer* info, int flags):
16+
# This implementation of getbuffer is geared towards Cython
17+
@@ -131,6 +134,7 @@ cdef extern from *: # Hard-coded utility code hack.
18+
19+
array newarrayobject(PyTypeObject* type, Py_ssize_t size, arraydescr *descr)
20+
21+
+ __data_union __Pyx_PyArray_Data(array self) nogil
22+
# fast resize/realloc
23+
# not suitable for small increments; reallocation 'to the point'
24+
int resize(array self, Py_ssize_t n) except -1
25+
diff --git a/Cython/Includes/cpython/datetime.pxd b/Cython/Includes/cpython/datetime.pxd
26+
index da988dc..b8c822e 100644
27+
--- a/Cython/Includes/cpython/datetime.pxd
28+
+++ b/Cython/Includes/cpython/datetime.pxd
29+
@@ -373,15 +373,15 @@ cdef inline int datetime_fold(object o) noexcept:
30+
31+
# Get days of timedelta
32+
cdef inline int timedelta_days(object o) noexcept:
33+
- return (<PyDateTime_Delta*>o).days
34+
+ return PyDateTime_DELTA_GET_DAYS(o)
35+
36+
# Get seconds of timedelta
37+
cdef inline int timedelta_seconds(object o) noexcept:
38+
- return (<PyDateTime_Delta*>o).seconds
39+
+ return PyDateTime_DELTA_GET_SECONDS(o)
40+
41+
# Get microseconds of timedelta
42+
cdef inline int timedelta_microseconds(object o) noexcept:
43+
- return (<PyDateTime_Delta*>o).microseconds
44+
+ return PyDateTime_DELTA_GET_MICROSECONDS(o)
45+
46+
cdef inline double total_seconds(timedelta obj) noexcept:
47+
# Mirrors the "timedelta.total_seconds()" method.
48+
diff --git a/Cython/Utility/Builtins.c b/Cython/Utility/Builtins.c
49+
index 15ba067..fdef8e5 100644
50+
--- a/Cython/Utility/Builtins.c
51+
+++ b/Cython/Utility/Builtins.c
52+
@@ -764,8 +764,13 @@ static {{out_type}} __Pyx_PyMemoryView_Get_{{name}}(PyObject *obj) {
53+
#define __Pyx_PySlice_Start(o) PyObject_GetAttr(o, PYIDENT("start"))
54+
#define __Pyx_PySlice_Stop(o) PyObject_GetAttr(o, PYIDENT("stop"))
55+
#define __Pyx_PySlice_Step(o) PyObject_GetAttr(o, PYIDENT("step"))
56+
-#elif CYTHON_COMPILING_IN_GRAAL
57+
+#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000
58+
// Graal defines it's own accessor functions
59+
+#define __Pyx_PySlice_Start(o) GraalPySlice_Start(o)
60+
+#define __Pyx_PySlice_Stop(o) GraalPySlice_Stop(o)
61+
+#define __Pyx_PySlice_Step(o) GraalPySlice_Step(o)
62+
+#elif CYTHON_COMPILING_IN_GRAAL
63+
+// Remove when GraalPy 24 goes EOL
64+
#define __Pyx_PySlice_Start(o) __Pyx_NewRef(PySlice_Start((PySliceObject*)o))
65+
#define __Pyx_PySlice_Stop(o) __Pyx_NewRef(PySlice_Stop((PySliceObject*)o))
66+
#define __Pyx_PySlice_Step(o) __Pyx_NewRef(PySlice_Step((PySliceObject*)o))
67+
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
68+
index 685d287..1b27dd5 100644
69+
--- a/Cython/Utility/CythonFunction.c
70+
+++ b/Cython/Utility/CythonFunction.c
71+
@@ -1755,8 +1755,12 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
72+
"This is most likely a classmethod in a cdef class method with binding=False. "
73+
"Try setting 'binding' to True.",
74+
method);
75+
-#elif CYTHON_COMPILING_IN_GRAAL
76+
+#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000
77+
// cdef classes
78+
+ PyTypeObject *d_type = GraalPyDescrObject_GetType(method);
79+
+ return PyDescr_NewClassMethod(d_type, GraalPyMethodDescrObject_GetMethod(method));
80+
+#elif CYTHON_COMPILING_IN_GRAAL
81+
+ // Remove when GraalPy 24 goes EOL
82+
PyTypeObject *d_type = PyDescrObject_GetType(method);
83+
return PyDescr_NewClassMethod(d_type, PyMethodDescrObject_GetMethod(method));
84+
#else
85+
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
86+
index 165a7ef..d88e279 100644
87+
--- a/Cython/Utility/Exceptions.c
88+
+++ b/Cython/Utility/Exceptions.c
89+
@@ -13,7 +13,7 @@ if (likely(__Pyx_init_assertions_enabled() == 0)); else
90+
91+
/////////////// AssertionsEnabled.proto ///////////////
92+
93+
-#if CYTHON_COMPILING_IN_LIMITED_API || (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030C0000)
94+
+#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000
95+
// Py_OptimizeFlag is deprecated in Py3.12+ and not available in the Limited API.
96+
static int __pyx_assertions_enabled_flag;
97+
#define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag)
98+
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
99+
index 6e29634..11f423e 100644
100+
--- a/Cython/Utility/ModuleSetupCode.c
101+
+++ b/Cython/Utility/ModuleSetupCode.c
102+
@@ -81,7 +81,7 @@
103+
#undef CYTHON_AVOID_BORROWED_REFS
104+
#define CYTHON_AVOID_BORROWED_REFS 1
105+
#undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS
106+
- #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1
107+
+ #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0
108+
#undef CYTHON_ASSUME_SAFE_MACROS
109+
#define CYTHON_ASSUME_SAFE_MACROS 0
110+
#undef CYTHON_ASSUME_SAFE_SIZE
111+
@@ -860,7 +860,11 @@ static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(vo
112+
#if CYTHON_COMPILING_IN_LIMITED_API
113+
// __Pyx_PyCode_HasFreeVars isn't easily emulated in the limited API (but isn't really necessary)
114+
#define __Pyx_PyFrame_SetLineNumber(frame, lineno)
115+
+#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000
116+
+ #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0)
117+
+ #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno))
118+
#elif CYTHON_COMPILING_IN_GRAAL
119+
+ // Remove when GraalPy 24 goes EOL
120+
#define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0)
121+
#define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno))
122+
#else
123+
@@ -1592,7 +1596,9 @@ static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) {
124+
#if !CYTHON_USE_MODULE_STATE
125+
static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) {
126+
static PY_INT64_T main_interpreter_id = -1;
127+
-#if CYTHON_COMPILING_IN_GRAAL
128+
+#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000
129+
+ PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get());
130+
+#elif CYTHON_COMPILING_IN_GRAAL
131+
PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get());
132+
#elif CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x03090000
133+
PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get());
134+
diff --git a/Cython/Utility/arrayarray.h b/Cython/Utility/arrayarray.h
135+
index d410e66..e006a20 100644
136+
--- a/Cython/Utility/arrayarray.h
137+
+++ b/Cython/Utility/arrayarray.h
138+
@@ -30,33 +30,34 @@ typedef struct arraydescr {
139+
char *formats;
140+
} arraydescr;
141+
142+
+typedef union {
143+
+ char *ob_item;
144+
+ float *as_floats;
145+
+ double *as_doubles;
146+
+ int *as_ints;
147+
+ unsigned int *as_uints;
148+
+ unsigned char *as_uchars;
149+
+ signed char *as_schars;
150+
+ char *as_chars;
151+
+ unsigned long *as_ulongs;
152+
+ long *as_longs;
153+
+ unsigned long long *as_ulonglongs;
154+
+ long long *as_longlongs;
155+
+ short *as_shorts;
156+
+ unsigned short *as_ushorts;
157+
+ // Don't use Py_UNICODE ourselves in the union. This avoids deprecation warnings
158+
+ // for anyone who uses array.array but doesn't use this field.
159+
+ #if PY_VERSION_HEX >= 0x030d0000
160+
+ Py_DEPRECATED(3.13)
161+
+ #endif
162+
+ wchar_t *as_pyunicodes;
163+
+ void *as_voidptr;
164+
+} __data_union;
165+
166+
struct arrayobject {
167+
PyObject_HEAD
168+
Py_ssize_t ob_size;
169+
- union {
170+
- char *ob_item;
171+
- float *as_floats;
172+
- double *as_doubles;
173+
- int *as_ints;
174+
- unsigned int *as_uints;
175+
- unsigned char *as_uchars;
176+
- signed char *as_schars;
177+
- char *as_chars;
178+
- unsigned long *as_ulongs;
179+
- long *as_longs;
180+
- unsigned long long *as_ulonglongs;
181+
- long long *as_longlongs;
182+
- short *as_shorts;
183+
- unsigned short *as_ushorts;
184+
- // Don't use Py_UNICODE ourselves in the union. This avoids deprecation warnings
185+
- // for anyone who uses array.array but doesn't use this field.
186+
- #if PY_VERSION_HEX >= 0x030d0000
187+
- Py_DEPRECATED(3.13)
188+
- #endif
189+
- wchar_t *as_pyunicodes;
190+
- void *as_voidptr;
191+
- } data;
192+
+ __data_union data;
193+
Py_ssize_t allocated;
194+
struct arraydescr *ob_descr;
195+
PyObject *weakreflist; /* List of weak references */
196+
@@ -105,9 +106,20 @@ PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size,
197+
struct arraydescr *descr);
198+
#endif /* ifndef NO_NEWARRAY_INLINE */
199+
200+
+static CYTHON_INLINE __data_union __Pyx_PyArray_Data(arrayobject *self) {
201+
+#if !CYTHON_COMPILING_IN_GRAAL
202+
+ return self->data;
203+
+#else
204+
+ __data_union data;
205+
+ data.ob_item = GraalPyArray_Data((PyObject*)self);
206+
+ return data;
207+
+#endif
208+
+}
209+
+
210+
// fast resize (reallocation to the point)
211+
// not designed for filing small increments (but for fast opaque array apps)
212+
static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) {
213+
+#if !CYTHON_COMPILING_IN_GRAAL
214+
void *items = (void*) self->data.ob_item;
215+
PyMem_Resize(items, char, (size_t)(n * self->ob_descr->itemsize));
216+
if (items == NULL) {
217+
@@ -118,10 +130,14 @@ static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) {
218+
__Pyx_SET_SIZE(self, n);
219+
self->allocated = n;
220+
return 0;
221+
+#else
222+
+ return GraalPyArray_Resize((PyObject*)self, n);
223+
+#endif
224+
}
225+
226+
// suitable for small increments; over allocation 50% ;
227+
static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) {
228+
+#if !CYTHON_COMPILING_IN_GRAAL
229+
void *items = (void*) self->data.ob_item;
230+
Py_ssize_t newsize;
231+
if (n < self->allocated && n*4 > self->allocated) {
232+
@@ -142,6 +158,9 @@ static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) {
233+
__Pyx_SET_SIZE(self, n);
234+
self->allocated = newsize;
235+
return 0;
236+
+#else
237+
+ return GraalPyArray_Resize((PyObject*)self, n);
238+
+#endif
239+
}
240+
241+
#endif
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
diff --git a/setupinfo.py b/setupinfo.py
2+
index 6417fb9..324bea0 100644
3+
--- a/setupinfo.py
4+
+++ b/setupinfo.py
5+
@@ -535,7 +535,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings')
6+
OPTION_WITHOUT_ASSERT = has_option('without-assert')
7+
OPTION_WITHOUT_THREADING = has_option('without-threading')
8+
OPTION_WITHOUT_CYTHON = has_option('without-cython')
9+
-OPTION_WITH_CYTHON = has_option('with-cython')
10+
+OPTION_WITH_CYTHON = True
11+
OPTION_WITH_CYTHON_GDB = has_option('cython-gdb')
12+
OPTION_WITH_REFNANNY = has_option('with-refnanny')
13+
OPTION_WITH_COVERAGE = has_option('with-coverage')

graalpython/lib-graalpython/patches/metadata.toml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,22 @@ license = 'Apache-2.0 OR BSD-3-Clause'
109109
version = '>= 43.0.0'
110110
note = "Versions newer than 43 do not need a patch."
111111

112-
[[Cython.rules]]
112+
[[cython.rules]]
113+
version = '>= 3.1, <= 3.1.2'
114+
patch = 'cython-3.1.2.patch'
115+
license = 'Apache-2.0'
116+
117+
[[cython.rules]]
113118
version = '>= 3.0.10, <= 3.0.12'
114119
patch = 'Cython-3.0.10.patch'
115120
license = 'Apache-2.0'
116121

117-
[[Cython.rules]]
122+
[[cython.rules]]
118123
version = '== 0.29.37'
119124
patch = 'Cython-0.29.37.patch'
120125
license = 'Apache-2.0'
121126

122-
[[Cython.rules]]
127+
[[cython.rules]]
123128
version = '== 0.29.32'
124129
# Also referenced outside of pip in ray patches
125130
# Also referenced outside of pip in tensorflow patches
@@ -178,27 +183,28 @@ patch = 'hmmlearn.patch'
178183
license = 'BSD-3-Clause'
179184

180185
[[hypothesis.rules]]
181-
# can be removed once [GR-65570] is done
186+
# Upstreamed
182187
patch = 'hypothesis-6.135.0.patch'
183-
version = '>= 6.120.0'
188+
version = '>= 6.120.0, < 6.136.7'
189+
install-priority = 0
184190
license = 'MPL-2.0'
185191

186192
[[hypothesis.rules]]
187-
# can be removed once [GR-65570] is done
188193
patch = 'hypothesis-6.118.5.patch'
189194
version = '>= 6.118.5, < 6.120.0'
195+
install-priority = 0
190196
license = 'MPL-2.0'
191197

192198
[[hypothesis.rules]]
193-
# can be removed once [GR-65570] is done
194199
patch = 'hypothesis-6.105.2.patch'
195200
version = '>= 6.105.2, < 6.118.5'
201+
install-priority = 0
196202
license = 'MPL-2.0'
197203

198204
[[hypothesis.rules]]
199-
# can be removed once [GR-65570] is done
200205
patch = 'hypothesis-6.104.1.patch'
201206
version = '>= 6.99.0, < 6.105.2'
207+
install-priority = 0
202208
license = 'MPL-2.0'
203209

204210
[[hypothesis.rules]]
@@ -282,6 +288,11 @@ license = 'MIT'
282288
patch = 'llvmlite.patch'
283289
license = 'BSD-2-Clause'
284290

291+
[[lxml.rules]]
292+
version = '>= 6'
293+
patch = 'lxml-6.patch'
294+
license = 'BSD-3-Clause'
295+
285296
[[lxml.rules]]
286297
version = '>= 5.3.2, <= 5.4.0'
287298
patch = 'lxml-5.4.0.patch'
@@ -348,6 +359,10 @@ url = 'https://github.com/ml-explore/mlx/archive/refs/tags/v0.16.2.tar.gz'
348359
version = '0.16.1'
349360
url = 'https://github.com/ml-explore/mlx/archive/refs/tags/v0.16.1.tar.gz'
350361

362+
[[msgpack.rules]]
363+
patch = 'msgpack.patch'
364+
license = 'Apache-2.0'
365+
351366
[[nanobind.rules]]
352367
patch = 'nanobind.patch'
353368
license = 'BSD-3-Clause'
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
diff --git a/setup.py b/setup.py
2+
index 4029e9e..14095fc 100644
3+
--- a/setup.py
4+
+++ b/setup.py
5+
@@ -5,6 +5,7 @@ import sys
6+
from setuptools import Extension, setup
7+
8+
PYPY = hasattr(sys, "pypy_version_info")
9+
+GRAALPY = sys.implementation.name == 'graalpy'
10+
11+
libraries = []
12+
macros = []
13+
@@ -14,7 +15,7 @@ if sys.platform == "win32":
14+
libraries.append("ws2_32")
15+
macros = [("__LITTLE_ENDIAN__", "1")]
16+
17+
-if not PYPY and not os.environ.get("MSGPACK_PUREPYTHON"):
18+
+if not PYPY and not GRAALPY and not os.environ.get("MSGPACK_PUREPYTHON"):
19+
ext_modules.append(
20+
Extension(
21+
"msgpack._cmsgpack",

0 commit comments

Comments
 (0)