forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlongobject.rs
More file actions
89 lines (77 loc) · 2.49 KB
/
Copy pathlongobject.rs
File metadata and controls
89 lines (77 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::PyObject;
use crate::object::define_py_check;
use crate::pystate::with_vm;
use core::ffi::{c_long, c_longlong, c_ulong, c_ulonglong};
use rustpython_vm::PyResult;
use rustpython_vm::builtins::PyInt;
define_py_check!(fn PyLong_Check, types.int_type);
define_py_check!(exact fn PyLong_CheckExact, types.int_type);
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromLong(value: c_long) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromLongLong(value: c_longlong) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromSsize_t(value: isize) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromSize_t(value: usize) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromUnsignedLong(value: c_ulong) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub extern "C" fn PyLong_FromUnsignedLongLong(value: c_ulonglong) -> *mut PyObject {
with_vm(|vm| vm.ctx.new_int(value))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyLong_AsLong(obj: *mut PyObject) -> c_long {
with_vm::<PyResult<c_long>, _>(|vm| {
unsafe { &*obj }
.to_owned()
.try_index(vm)?
.as_bigint()
.try_into()
.map_err(|_| vm.new_overflow_error("Python int too large to convert to C long"))
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn PyLong_AsUnsignedLongLong(obj: *mut PyObject) -> c_ulonglong {
with_vm::<PyResult<c_ulonglong>, _>(|vm| {
unsafe { &*obj }
.to_owned()
.try_downcast::<PyInt>(vm)?
.as_bigint()
.try_into()
.map_err(|_| {
vm.new_overflow_error("Python int too large to convert to C unsigned long long")
})
})
}
#[cfg(false)]
mod tests {
use pyo3::prelude::*;
use pyo3::types::PyInt;
#[test]
fn test_py_int_u32() {
Python::attach(|py| {
let number = PyInt::new(py, 123);
assert!(number.is_instance_of::<PyInt>());
assert_eq!(number.extract::<i32>().unwrap(), 123);
})
}
#[test]
fn test_py_int_u64() {
Python::attach(|py| {
let number = PyInt::new(py, 123u64);
assert!(number.is_instance_of::<PyInt>());
assert_eq!(number.extract::<u64>().unwrap(), 123);
})
}
}