Skip to content

Commit eb40b18

Browse files
timfelmsimacek
authored andcommitted
Add patch for ormsgpack
1 parent 479174b commit eb40b18

File tree

2 files changed

+369
-0
lines changed

2 files changed

+369
-0
lines changed

graalpython/lib-graalpython/patches/metadata.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ version = '== 3.10.5'
346346
patch = 'orjson-3.10.5.patch'
347347
license = 'Apache-2.0 OR MIT'
348348

349+
[[ormsgpack.rules]]
350+
version = '>= 1.8.0, <= 1.9.1'
351+
patch = 'ormsgpack-1.8.0-1.9.1.patch'
352+
license = 'Apache-2.0 OR MIT'
353+
349354
[[overrides.rules]]
350355
version = '== 7.4.0'
351356
# Important: This patch esentially breaks the package, it's not upstreamable. The package relies on bytecode parsing
Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
diff --git a/src/deserialize/deserializer.rs b/src/deserialize/deserializer.rs
2+
index 41cf7f1..99cd68e 100644
3+
--- a/src/deserialize/deserializer.rs
4+
+++ b/src/deserialize/deserializer.rs
5+
@@ -292,7 +292,10 @@ impl<'de> Deserializer<'de> {
6+
marker => Err(Error::InvalidType(marker)),
7+
}?;
8+
let value = self.deserialize()?;
9+
+ #[cfg(not(GraalPy))]
10+
let pyhash = unsafe { (*key.as_ptr().cast::<pyo3::ffi::PyASCIIObject>()).hash };
11+
+ #[cfg(GraalPy)]
12+
+ let pyhash = unsafe { pyo3::ffi::PyObject_Hash(key.as_ptr()) };
13+
let _ = ffi!(_PyDict_SetItem_KnownHash(
14+
dict_ptr,
15+
key.as_ptr(),
16+
@@ -471,7 +474,7 @@ impl<'de> Deserializer<'de> {
17+
let ptr = ffi!(PyTuple_New(len as pyo3::ffi::Py_ssize_t));
18+
for i in 0..len {
19+
let elem = self.deserialize_map_key()?;
20+
- ffi!(PyTuple_SET_ITEM(
21+
+ ffi!(PyTuple_SetItem(
22+
ptr,
23+
i as pyo3::ffi::Py_ssize_t,
24+
elem.as_ptr()
25+
diff --git a/src/ext.rs b/src/ext.rs
26+
index b2573b4..9668d4f 100644
27+
--- a/src/ext.rs
28+
+++ b/src/ext.rs
29+
@@ -22,7 +22,7 @@ unsafe extern "C" fn ext_new(
30+
);
31+
return null_mut();
32+
}
33+
- let tag = PyTuple_GET_ITEM(args, 0);
34+
+ let tag = PyTuple_GetItem(args, 0);
35+
if PyLong_Check(tag) == 0 {
36+
PyErr_SetString(
37+
PyExc_TypeError,
38+
@@ -30,7 +30,7 @@ unsafe extern "C" fn ext_new(
39+
);
40+
return null_mut();
41+
}
42+
- let data = PyTuple_GET_ITEM(args, 1);
43+
+ let data = PyTuple_GetItem(args, 1);
44+
if PyBytes_Check(data) == 0 {
45+
PyErr_SetString(
46+
PyExc_TypeError,
47+
diff --git a/src/ffi.rs b/src/ffi.rs
48+
index 4e5ddc3..20c9db4 100644
49+
--- a/src/ffi.rs
50+
+++ b/src/ffi.rs
51+
@@ -7,13 +7,16 @@ use std::ptr::NonNull;
52+
#[allow(non_snake_case)]
53+
#[inline(always)]
54+
pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char {
55+
- &(*op.cast::<PyBytesObject>()).ob_sval as *const c_char
56+
+ #[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
57+
+ return &(*op.cast::<PyBytesObject>()).ob_sval as *const c_char;
58+
+ #[cfg(any(PyPy, GraalPy, Py_LIMITED_API))]
59+
+ return crate::PyBytes_AsString(op);
60+
}
61+
62+
#[allow(non_snake_case)]
63+
#[inline(always)]
64+
pub unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
65+
- (*op.cast::<PyVarObject>()).ob_size
66+
+ Py_SIZE(op)
67+
}
68+
69+
#[repr(C)]
70+
@@ -63,11 +66,21 @@ pub fn pylong_is_positive(op: *mut PyObject) -> bool {
71+
unsafe { (*(op as *mut PyLongObject)).long_value.lv_tag & SIGN_MASK == 0 }
72+
}
73+
74+
-#[cfg(not(Py_3_12))]
75+
+#[cfg(not(any(Py_3_12, GraalPy)))]
76+
pub fn pylong_is_positive(op: *mut PyObject) -> bool {
77+
unsafe { (*(op as *mut PyVarObject)).ob_size > 0 }
78+
}
79+
80+
+extern "C" {
81+
+ #[cfg(not(PyPy))]
82+
+ pub fn _PyLong_Sign(v: *mut PyObject) -> c_int;
83+
+}
84+
+
85+
+#[cfg(GraalPy)]
86+
+pub fn pylong_is_positive(op: *mut PyObject) -> bool {
87+
+ unsafe { _PyLong_Sign(op) > 0 }
88+
+}
89+
+
90+
pub struct PyDictIter {
91+
op: *mut PyObject,
92+
pos: isize,
93+
diff --git a/src/lib.rs b/src/lib.rs
94+
index f10b1c4..1a9768b 100644
95+
--- a/src/lib.rs
96+
+++ b/src/lib.rs
97+
@@ -143,7 +143,7 @@ fn raise_unpackb_exception(msg: &str) -> *mut PyObject {
98+
let err_msg =
99+
PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize);
100+
let args = PyTuple_New(1);
101+
- PyTuple_SET_ITEM(args, 0, err_msg);
102+
+ PyTuple_SetItem(args, 0, err_msg);
103+
PyErr_SetObject(typeref::MsgpackDecodeError, args);
104+
Py_DECREF(args);
105+
};
106+
@@ -199,10 +199,10 @@ pub unsafe extern "C" fn unpackb(
107+
if !kwnames.is_null() {
108+
let tuple_size = PyTuple_GET_SIZE(kwnames);
109+
for i in 0..tuple_size {
110+
- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t);
111+
- if arg == typeref::EXT_HOOK {
112+
+ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t);
113+
+ if PyUnicode_Compare(arg, typeref::EXT_HOOK) == 0 {
114+
ext_hook = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
115+
- } else if arg == typeref::OPTION {
116+
+ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 {
117+
optsptr = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
118+
} else {
119+
return raise_unpackb_exception("unpackb() got an unexpected keyword argument");
120+
@@ -247,15 +247,15 @@ pub unsafe extern "C" fn packb(
121+
if !kwnames.is_null() {
122+
let tuple_size = PyTuple_GET_SIZE(kwnames);
123+
for i in 0..tuple_size {
124+
- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t);
125+
- if arg == typeref::DEFAULT {
126+
+ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t);
127+
+ if PyUnicode_Compare(arg, typeref::DEFAULT) == 0 {
128+
if unlikely!(default.is_some()) {
129+
return raise_packb_exception(
130+
"packb() got multiple values for argument: 'default'",
131+
);
132+
}
133+
default = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
134+
- } else if arg == typeref::OPTION {
135+
+ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 {
136+
if unlikely!(optsptr.is_some()) {
137+
return raise_packb_exception(
138+
"packb() got multiple values for argument: 'option'",
139+
diff --git a/src/serialize/datetime.rs b/src/serialize/datetime.rs
140+
index 63212d6..5ac2b2b 100644
141+
--- a/src/serialize/datetime.rs
142+
+++ b/src/serialize/datetime.rs
143+
@@ -61,9 +61,14 @@ pub struct Time {
144+
145+
impl Time {
146+
pub fn new(ptr: *mut pyo3::ffi::PyObject, opts: Opt) -> Result<Self, TimeError> {
147+
+ #[cfg(not(GraalPy))]
148+
if unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_Time)).hastzinfo != 0 } {
149+
return Err(TimeError::HasTimezone);
150+
}
151+
+ #[cfg(GraalPy)]
152+
+ if unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(ptr) != crate::typeref::NONE } {
153+
+ return Err(TimeError::HasTimezone);
154+
+ }
155+
Ok(Time {
156+
ptr: ptr,
157+
opts: opts,
158+
@@ -114,23 +119,28 @@ impl std::fmt::Display for DateTimeError {
159+
}
160+
161+
fn utcoffset(ptr: *mut pyo3::ffi::PyObject) -> Result<Offset, DateTimeError> {
162+
+ #[cfg(not(GraalPy))]
163+
if !unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } {
164+
return Ok(Offset::default());
165+
}
166+
167+
let tzinfo = ffi!(PyDateTime_DATE_GET_TZINFO(ptr));
168+
+ #[cfg(GraalPy)]
169+
+ if unsafe { tzinfo == crate::typeref::NONE } {
170+
+ return Ok(Offset::default());
171+
+ }
172+
let py_offset: *mut pyo3::ffi::PyObject;
173+
if ffi!(PyObject_HasAttr(tzinfo, CONVERT_METHOD_STR)) == 1 {
174+
// pendulum
175+
- py_offset = ffi!(PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR));
176+
+ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR) };
177+
} else if ffi!(PyObject_HasAttr(tzinfo, NORMALIZE_METHOD_STR)) == 1 {
178+
// pytz
179+
- let normalized = ffi!(PyObject_CallMethodOneArg(tzinfo, NORMALIZE_METHOD_STR, ptr));
180+
- py_offset = ffi!(PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR));
181+
+ let normalized = ffi!(PyObject_CallMethodObjArgs(tzinfo, NORMALIZE_METHOD_STR, ptr, std::ptr::null_mut::<crate::PyObject>()));
182+
+ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR) };
183+
ffi!(Py_DECREF(normalized));
184+
} else if ffi!(PyObject_HasAttr(tzinfo, DST_STR)) == 1 {
185+
// dateutil/arrow, datetime.timezone.utc
186+
- py_offset = ffi!(PyObject_CallMethodOneArg(tzinfo, UTCOFFSET_METHOD_STR, ptr));
187+
+ py_offset = ffi!(PyObject_CallMethodObjArgs(tzinfo, UTCOFFSET_METHOD_STR, ptr, std::ptr::null_mut::<crate::PyObject>()));
188+
} else {
189+
return Err(DateTimeError::LibraryUnsupported);
190+
}
191+
@@ -193,7 +203,10 @@ impl TimeLike for DateTime {
192+
193+
impl DateTimeLike for DateTime {
194+
fn has_tz(&self) -> bool {
195+
- unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 }
196+
+ #[cfg(not(GraalPy))]
197+
+ return unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 };
198+
+ #[cfg(GraalPy)]
199+
+ return unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(self.ptr) != crate::typeref::NONE };
200+
}
201+
202+
fn offset(&self) -> Offset {
203+
diff --git a/src/serialize/numpy.rs b/src/serialize/numpy.rs
204+
index afc5cdf..4d007bd 100644
205+
--- a/src/serialize/numpy.rs
206+
+++ b/src/serialize/numpy.rs
207+
@@ -392,8 +392,8 @@ impl NumpyDatetimeUnit {
208+
fn from_pyobject(ptr: *mut PyObject) -> Self {
209+
let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR));
210+
let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR));
211+
- let el0 = ffi!(PyList_GET_ITEM(descr, 0));
212+
- let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1));
213+
+ let el0 = ffi!(PyList_GetItem(descr, 0));
214+
+ let descr_str = ffi!(PyTuple_GetItem(el0, 1));
215+
let uni = crate::unicode::unicode_to_str(descr_str).unwrap();
216+
if uni.len() < 5 {
217+
return Self::NaT;
218+
diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs
219+
index 309e6e1..6f7dec7 100644
220+
--- a/src/serialize/serializer.rs
221+
+++ b/src/serialize/serializer.rs
222+
@@ -864,7 +864,7 @@ impl Serialize for DictTupleKey {
223+
let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize;
224+
let mut seq = serializer.serialize_seq(Some(len)).unwrap();
225+
for i in 0..len {
226+
- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize));
227+
+ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize));
228+
let value = DictKey::new(item, self.opts, self.recursion + 1);
229+
seq.serialize_element(&value)?;
230+
}
231+
diff --git a/src/serialize/tuple.rs b/src/serialize/tuple.rs
232+
index fa81cb6..9b66019 100644
233+
--- a/src/serialize/tuple.rs
234+
+++ b/src/serialize/tuple.rs
235+
@@ -41,7 +41,7 @@ impl Serialize for Tuple {
236+
let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize;
237+
let mut seq = serializer.serialize_seq(Some(len)).unwrap();
238+
for i in 0..len {
239+
- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize));
240+
+ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize));
241+
let value = PyObject::new(
242+
item,
243+
self.opts,
244+
diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs
245+
index a790bdd..35346d9 100644
246+
--- a/src/serialize/writer.rs
247+
+++ b/src/serialize/writer.rs
248+
@@ -27,7 +27,6 @@ impl BytesWriter {
249+
pub fn finish(&mut self) -> NonNull<PyObject> {
250+
unsafe {
251+
std::ptr::write(self.buffer_ptr(), 0);
252+
- (*self.bytes.cast::<PyVarObject>()).ob_size = self.len as Py_ssize_t;
253+
self.resize(self.len);
254+
NonNull::new_unchecked(self.bytes as *mut PyObject)
255+
}
256+
@@ -35,10 +34,14 @@ impl BytesWriter {
257+
258+
fn buffer_ptr(&self) -> *mut u8 {
259+
unsafe {
260+
- std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!(
261+
+ #[cfg(not(GraalPy))]
262+
+ return std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!(
263+
(*self.bytes).ob_sval
264+
))
265+
- .add(self.len)
266+
+ .add(self.len);
267+
+ #[cfg(GraalPy)]
268+
+ return std::mem::transmute::<*mut i8, *mut u8>(PyBytes_AsString(self.bytes.cast::<PyObject>()))
269+
+ .add(self.len);
270+
}
271+
}
272+
273+
diff --git a/src/unicode.rs b/src/unicode.rs
274+
index 53aca09..552fa6c 100644
275+
--- a/src/unicode.rs
276+
+++ b/src/unicode.rs
277+
@@ -6,6 +6,7 @@ use pyo3::ffi::*;
278+
279+
// see unicodeobject.h for documentation
280+
281+
+#[cfg(not(GraalPy))]
282+
pub fn unicode_from_str(buf: &str) -> *mut PyObject {
283+
if buf.is_empty() {
284+
ffi!(Py_INCREF(EMPTY_UNICODE));
285+
@@ -27,6 +28,13 @@ pub fn unicode_from_str(buf: &str) -> *mut PyObject {
286+
}
287+
}
288+
289+
+#[cfg(GraalPy)]
290+
+pub fn unicode_from_str(buf: &str) -> *mut PyObject {
291+
+ unsafe {
292+
+ PyUnicode_FromStringAndSize(buf.as_ptr() as *const i8, buf.len() as isize)
293+
+ }
294+
+}
295+
+
296+
fn pyunicode_ascii(buf: &str) -> *mut PyObject {
297+
unsafe {
298+
let ptr = ffi!(PyUnicode_New(buf.len() as isize, 127));
299+
@@ -80,6 +88,7 @@ fn pyunicode_fourbyte(buf: &str, num_chars: usize) -> *mut PyObject {
300+
301+
#[inline]
302+
pub fn hash_str(op: *mut PyObject) -> Py_hash_t {
303+
+ #[cfg(not(GraalPy))]
304+
unsafe {
305+
let data_ptr: *mut c_void = if (*op.cast::<PyASCIIObject>()).compact() == 1
306+
&& (*op.cast::<PyASCIIObject>()).ascii() == 1
307+
@@ -92,7 +101,11 @@ pub fn hash_str(op: *mut PyObject) -> Py_hash_t {
308+
(*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize;
309+
let hash = _Py_HashBytes(data_ptr, num_bytes);
310+
(*op.cast::<PyASCIIObject>()).hash = hash;
311+
- hash
312+
+ return hash;
313+
+ }
314+
+ #[cfg(GraalPy)]
315+
+ unsafe {
316+
+ return PyObject_Hash(op);
317+
}
318+
}
319+
320+
@@ -109,19 +122,24 @@ pub fn unicode_to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> {
321+
322+
#[inline]
323+
pub fn unicode_to_str(op: *mut PyObject) -> Option<&'static str> {
324+
+ #[cfg(not(GraalPy))]
325+
unsafe {
326+
if unlikely!((*op.cast::<PyASCIIObject>()).compact() == 0) {
327+
- unicode_to_str_via_ffi(op)
328+
+ return unicode_to_str_via_ffi(op);
329+
} else if (*op.cast::<PyASCIIObject>()).ascii() == 1 {
330+
let ptr = op.cast::<PyASCIIObject>().offset(1) as *const u8;
331+
let len = (*op.cast::<PyASCIIObject>()).length as usize;
332+
- Some(str_from_slice!(ptr, len))
333+
+ return Some(str_from_slice!(ptr, len));
334+
} else if (*op.cast::<PyCompactUnicodeObject>()).utf8_length != 0 {
335+
let ptr = (*op.cast::<PyCompactUnicodeObject>()).utf8 as *const u8;
336+
let len = (*op.cast::<PyCompactUnicodeObject>()).utf8_length as usize;
337+
- Some(str_from_slice!(ptr, len))
338+
+ return Some(str_from_slice!(ptr, len));
339+
} else {
340+
- unicode_to_str_via_ffi(op)
341+
+ return unicode_to_str_via_ffi(op);
342+
}
343+
}
344+
+ #[cfg(GraalPy)]
345+
+ unsafe {
346+
+ return unicode_to_str_via_ffi(op);
347+
+ }
348+
}
349+
diff --git a/src/util.rs b/src/util.rs
350+
index 2bcc32d..89faf1a 100644
351+
--- a/src/util.rs
352+
+++ b/src/util.rs
353+
@@ -8,7 +8,7 @@ macro_rules! py_is {
354+
355+
macro_rules! ob_type {
356+
($obj:expr) => {
357+
- unsafe { (*($obj as *mut pyo3::ffi::PyObject)).ob_type }
358+
+ unsafe { pyo3::ffi::Py_TYPE($obj as *mut pyo3::ffi::PyObject) }
359+
};
360+
}
361+
362+
--
363+
2.43.0
364+

0 commit comments

Comments
 (0)