Skip to content

Commit

Permalink
Declare the Python type of Rust primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
CLOVIS-AI committed Aug 1, 2022
1 parent b0c5692 commit 279d4ca
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 1 deletion.
68 changes: 67 additions & 1 deletion src/inspect/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ impl Display for TypeInfo {
mod test {
use crate::inspect::types::{ModuleName, TypeInfo};

fn assert_display(t: &TypeInfo, expected: &str) {
pub fn assert_display(t: &TypeInfo, expected: &str) {
assert_eq!(format!("{}", t), expected)
}

Expand Down Expand Up @@ -394,3 +394,69 @@ mod test {
);
}
}

#[cfg(test)]
mod conversion {
use crate::inspect::types::test::assert_display;
use crate::{FromPyObject, IntoPy};

#[test]
fn unsigned_int() {
assert_display(&usize::type_output(), "int");
assert_display(&usize::type_input(), "int");

assert_display(&u8::type_output(), "int");
assert_display(&u8::type_input(), "int");

assert_display(&u16::type_output(), "int");
assert_display(&u16::type_input(), "int");

assert_display(&u32::type_output(), "int");
assert_display(&u32::type_input(), "int");

assert_display(&u64::type_output(), "int");
assert_display(&u64::type_input(), "int");
}

#[test]
fn signed_int() {
assert_display(&isize::type_output(), "int");
assert_display(&isize::type_input(), "int");

assert_display(&i8::type_output(), "int");
assert_display(&i8::type_input(), "int");

assert_display(&i16::type_output(), "int");
assert_display(&i16::type_input(), "int");

assert_display(&i32::type_output(), "int");
assert_display(&i32::type_input(), "int");

assert_display(&i64::type_output(), "int");
assert_display(&i64::type_input(), "int");
}

#[test]
fn float() {
assert_display(&f32::type_output(), "float");
assert_display(&f32::type_input(), "float");

assert_display(&f64::type_output(), "float");
assert_display(&f64::type_input(), "float");
}

#[test]
fn bool() {
assert_display(&bool::type_output(), "bool");
assert_display(&bool::type_input(), "bool");
}

#[test]
fn text() {
assert_display(&String::type_output(), "str");
assert_display(&String::type_input(), "str");

assert_display(&<&[u8]>::type_output(), "bytes");
assert_display(&<&[u8]>::type_input(), "bytes");
}
}
9 changes: 9 additions & 0 deletions src/types/boolobject.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::inspect::types::TypeInfo;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, PyTryFrom, Python,
ToPyObject,
Expand Down Expand Up @@ -46,6 +47,10 @@ impl IntoPy<PyObject> for bool {
fn into_py(self, py: Python<'_>) -> PyObject {
PyBool::new(py, self).into()
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("bool")
}
}

/// Converts a Python `bool` to a Rust `bool`.
Expand All @@ -55,6 +60,10 @@ impl<'source> FromPyObject<'source> for bool {
fn extract(obj: &'source PyAny) -> PyResult<Self> {
Ok(<PyBool as PyTryFrom>::try_from(obj)?.is_true())
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}

#[cfg(test)]
Expand Down
10 changes: 10 additions & 0 deletions src/types/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::inspect::types::TypeInfo;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, PyTryFrom, Python,
ToPyObject,
Expand Down Expand Up @@ -128,13 +129,22 @@ impl<'a> IntoPy<PyObject> for &'a [u8] {
fn into_py(self, py: Python<'_>) -> PyObject {
PyBytes::new(py, self).to_object(py)
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("bytes")
}
}

impl<'a> FromPyObject<'a> for &'a [u8] {
fn extract(obj: &'a PyAny) -> PyResult<Self> {
Ok(<PyBytes as PyTryFrom>::try_from(obj)?.as_bytes())
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}

#[cfg(test)]
mod tests {
use super::PyBytes;
Expand Down
17 changes: 17 additions & 0 deletions src/types/floatob.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
//
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
use crate::inspect::types::TypeInfo;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
};
Expand Down Expand Up @@ -44,6 +45,10 @@ impl IntoPy<PyObject> for f64 {
fn into_py(self, py: Python<'_>) -> PyObject {
PyFloat::new(py, self).into()
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("float")
}
}

impl<'source> FromPyObject<'source> for f64 {
Expand All @@ -60,6 +65,10 @@ impl<'source> FromPyObject<'source> for f64 {

Ok(v)
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}

impl ToPyObject for f32 {
Expand All @@ -72,12 +81,20 @@ impl IntoPy<PyObject> for f32 {
fn into_py(self, py: Python<'_>) -> PyObject {
PyFloat::new(py, f64::from(self)).into()
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("float")
}
}

impl<'source> FromPyObject<'source> for f32 {
fn extract(obj: &'source PyAny) -> PyResult<Self> {
Ok(obj.extract::<f64>()? as f32)
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}

#[cfg(test)]
Expand Down
41 changes: 41 additions & 0 deletions src/types/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython

use crate::inspect::types::TypeInfo;
use crate::{
exceptions, ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python,
ToPyObject,
Expand All @@ -22,6 +23,10 @@ macro_rules! int_fits_larger_int {
fn into_py(self, py: Python<'_>) -> PyObject {
(self as $larger_type).into_py(py)
}

fn type_output() -> TypeInfo {
<$larger_type>::type_output()
}
}

impl<'source> FromPyObject<'source> for $rust_type {
Expand All @@ -30,6 +35,10 @@ macro_rules! int_fits_larger_int {
<$rust_type>::try_from(val)
.map_err(|e| exceptions::PyOverflowError::new_err(e.to_string()))
}

fn type_input() -> TypeInfo {
<$larger_type>::type_input()
}
}
};
}
Expand All @@ -56,6 +65,10 @@ macro_rules! int_fits_c_long {
fn into_py(self, py: Python<'_>) -> PyObject {
unsafe { PyObject::from_owned_ptr(py, ffi::PyLong_FromLong(self as c_long)) }
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("int")
}
}

impl<'source> FromPyObject<'source> for $rust_type {
Expand All @@ -74,6 +87,10 @@ macro_rules! int_fits_c_long {
<$rust_type>::try_from(val)
.map_err(|e| exceptions::PyOverflowError::new_err(e.to_string()))
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}
};
}
Expand All @@ -91,6 +108,10 @@ macro_rules! int_convert_u64_or_i64 {
fn into_py(self, py: Python<'_>) -> PyObject {
unsafe { PyObject::from_owned_ptr(py, $pylong_from_ll_or_ull(self)) }
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("int")
}
}
impl<'source> FromPyObject<'source> for $rust_type {
fn extract(ob: &'source PyAny) -> PyResult<$rust_type> {
Expand All @@ -106,6 +127,10 @@ macro_rules! int_convert_u64_or_i64 {
}
}
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}
};
}
Expand Down Expand Up @@ -170,6 +195,10 @@ mod fast_128bit_int_conversion {
PyObject::from_owned_ptr(py, obj)
}
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("int")
}
}

impl<'source> FromPyObject<'source> for $rust_type {
Expand All @@ -192,6 +221,10 @@ mod fast_128bit_int_conversion {
Ok(<$rust_type>::from_le_bytes(buffer))
}
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}
};
}
Expand Down Expand Up @@ -234,6 +267,10 @@ mod slow_128bit_int_conversion {
)
}
}

fn type_output() -> TypeInfo {
TypeInfo::builtin("int")
}
}

impl<'source> FromPyObject<'source> for $rust_type {
Expand All @@ -253,6 +290,10 @@ mod slow_128bit_int_conversion {
Ok((<$rust_type>::from(upper) << SHIFT) | lower)
}
}

fn type_input() -> TypeInfo {
Self::type_output()
}
}
};
}
Expand Down
Loading

0 comments on commit 279d4ca

Please sign in to comment.