Remove some transmute

This commit is contained in:
konstin 2018-11-12 21:36:08 +01:00
parent 531f9db99e
commit 3614f38154
10 changed files with 58 additions and 39 deletions

View File

@ -661,6 +661,7 @@ impl_element!(f64, Float);
#[cfg(test)]
mod test {
use super::PyBuffer;
use crate::ffi;
use crate::python::Python;
use std;
@ -671,7 +672,7 @@ mod test {
fn test_compatible_size() {
// for the cast in PyBuffer::shape()
assert_eq!(
std::mem::size_of::<crate::ffi::Py_ssize_t>(),
std::mem::size_of::<ffi::Py_ssize_t>(),
std::mem::size_of::<usize>()
);
}

View File

@ -70,18 +70,10 @@ impl PyMethodDef {
pub fn as_method_def(&self) -> ffi::PyMethodDef {
let meth = match self.ml_meth {
PyMethodType::PyCFunction(meth) => meth,
PyMethodType::PyCFunctionWithKeywords(meth) => unsafe {
std::mem::transmute::<ffi::PyCFunctionWithKeywords, ffi::PyCFunction>(meth)
},
PyMethodType::PyNoArgsFunction(meth) => unsafe {
std::mem::transmute::<ffi::PyNoArgsFunction, ffi::PyCFunction>(meth)
},
PyMethodType::PyNewFunc(meth) => unsafe {
std::mem::transmute::<ffi::newfunc, ffi::PyCFunction>(meth)
},
PyMethodType::PyInitFunc(meth) => unsafe {
std::mem::transmute::<ffi::initproc, ffi::PyCFunction>(meth)
},
PyMethodType::PyCFunctionWithKeywords(meth) => unsafe { std::mem::transmute(meth) },
PyMethodType::PyNoArgsFunction(meth) => unsafe { std::mem::transmute(meth) },
PyMethodType::PyNewFunc(meth) => unsafe { std::mem::transmute(meth) },
PyMethodType::PyInitFunc(meth) => unsafe { std::mem::transmute(meth) },
};
ffi::PyMethodDef {

View File

@ -1,6 +1,7 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use std;
use std::mem;
use std::ptr::NonNull;
use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
@ -9,7 +10,7 @@ use crate::ffi;
use crate::instance;
use crate::object::PyObject;
use crate::objectprotocol::ObjectProtocol;
use crate::python::{IntoPyPointer, NonNullPyObject, Python, ToPyPointer};
use crate::python::{IntoPyPointer, Python, ToPyPointer};
use crate::pythonrun;
use crate::typeob::PyTypeCreate;
use crate::typeob::{PyTypeInfo, PyTypeObject};
@ -85,10 +86,12 @@ pub trait AsPyRef<T>: Sized {
/// Safe wrapper around unsafe `*mut ffi::PyObject` pointer with specified type information.
#[derive(Debug)]
pub struct Py<T>(NonNullPyObject, std::marker::PhantomData<T>);
#[repr(transparent)]
pub struct Py<T>(NonNull<ffi::PyObject>, std::marker::PhantomData<T>);
// `Py<T>` is thread-safe, because any python related operations require a Python<'p> token.
unsafe impl<T> Send for Py<T> {}
unsafe impl<T> Sync for Py<T> {}
impl<T> Py<T> {
@ -152,6 +155,15 @@ impl<T> Py<T> {
pub fn clone_ref(&self, _py: Python) -> Py<T> {
unsafe { Py::from_borrowed_ptr(self.0.as_ptr()) }
}
/// Returns the inner pointer without decreasing the refcount
///
/// This will eventually move into its own trait
pub(crate) fn into_non_null(self) -> NonNull<ffi::PyObject> {
let pointer = self.0;
mem::forget(self);
pointer
}
}
impl<T> Py<T>
@ -251,8 +263,8 @@ impl<T> IntoPyObject for Py<T> {
/// Converts `Py` instance -> PyObject.
/// Consumes `self` without calling `Py_DECREF()`
#[inline]
fn into_object(self, _py: Python) -> PyObject {
unsafe { std::mem::transmute(self) }
fn into_object(self, py: Python) -> PyObject {
unsafe { PyObject::from_owned_ptr(py, self.into_ptr()) }
}
}
@ -294,7 +306,7 @@ impl<T> Drop for Py<T> {
impl<T> std::convert::From<Py<T>> for PyObject {
#[inline]
fn from(ob: Py<T>) -> Self {
unsafe { std::mem::transmute(ob) }
unsafe { PyObject::from_not_null(ob.into_non_null()) }
}
}

View File

@ -9,7 +9,7 @@ use crate::conversion::{
use crate::err::{PyDowncastError, PyErr, PyResult};
use crate::ffi;
use crate::instance::{AsPyRef, PyObjectWithGIL};
use crate::python::{IntoPyPointer, NonNullPyObject, Python, ToPyPointer};
use crate::python::{IntoPyPointer, Python, ToPyPointer};
use crate::pythonrun;
use crate::types::{PyDict, PyObjectRef, PyTuple};
@ -21,13 +21,18 @@ use crate::types::{PyDict, PyObjectRef, PyTuple};
/// Technically, it is a safe wrapper around the unsafe `*mut ffi::PyObject` pointer.
#[derive(Debug)]
#[repr(transparent)]
pub struct PyObject(NonNullPyObject);
pub struct PyObject(NonNull<ffi::PyObject>);
// `PyObject` is thread-safe, any python related operations require a Python<'p> token.
unsafe impl Send for PyObject {}
unsafe impl Sync for PyObject {}
impl PyObject {
/// For internal conversions
pub(crate) unsafe fn from_not_null(ptr: NonNull<ffi::PyObject>) -> PyObject {
PyObject(ptr)
}
/// Creates a `PyObject` instance for the given FFI pointer.
/// This moves ownership over the pointer into the `PyObject`.
/// Undefined behavior if the pointer is NULL or invalid.

View File

@ -2,6 +2,7 @@
use crate::conversion::{FromPyObject, IntoPyTuple, PyTryFrom, ToBorrowedObject, ToPyObject};
use crate::err::{self, PyDowncastError, PyErr, PyResult};
use crate::exceptions::TypeError;
use crate::ffi;
use crate::instance::PyObjectWithGIL;
use crate::object::PyObject;
@ -279,7 +280,7 @@ where
} else if result < 0 {
return Err(PyErr::fetch(py));
}
Err(crate::exceptions::TypeError::py_err(
Err(TypeError::py_err(
"ObjectProtocol::compare(): All comparisons returned false",
))
}

View File

@ -15,9 +15,6 @@ use std;
use std::ffi::CString;
use std::marker::PhantomData;
use std::os::raw::c_int;
use std::ptr::NonNull;
pub type NonNullPyObject = NonNull<ffi::PyObject>;
/// Marker type that indicates that the GIL is currently held.
///

View File

@ -1,8 +1,9 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::ffi;
use crate::python::{NonNullPyObject, Python};
use crate::python::Python;
use crate::types::PyObjectRef;
use spin;
use std::ptr::NonNull;
use std::{any, marker, rc, sync};
static START: sync::Once = sync::ONCE_INIT;
@ -230,7 +231,7 @@ pub unsafe fn register_any<'p, T: 'static>(obj: T) -> &'p T {
.unwrap()
}
pub unsafe fn register_pointer(obj: NonNullPyObject) {
pub unsafe fn register_pointer(obj: NonNull<ffi::PyObject>) {
let pool: &'static mut ReleasePool = &mut *POOL;
let mut v = pool.p.lock();

View File

@ -6,10 +6,10 @@ pub use self::boolobject::PyBool;
pub use self::bytearray::PyByteArray;
pub use self::complex::PyComplex;
pub use self::datetime::PyDeltaAccess;
pub use self::datetime::{PyDate, PyDateTime, PyDelta, PyTime, PyTzInfo};
pub use self::datetime::{PyDateAccess, PyTimeAccess};
pub use self::dict::IntoPyDict;
pub use self::dict::PyDict;
pub use self::datetime::{
PyDate, PyDateAccess, PyDateTime, PyDelta, PyTime, PyTimeAccess, PyTzInfo,
};
pub use self::dict::{IntoPyDict, PyDict};
pub use self::floatob::PyFloat;
pub use self::iterator::PyIterator;
pub use self::list::PyList;
@ -31,6 +31,7 @@ pub use self::tuple::PyTuple;
pub use self::typeobject::PyType;
use crate::ffi;
use crate::python::ToPyPointer;
use crate::PyObject;
/// Implements a typesafe conversions throught [FromPyObject], given a typecheck function as second
/// parameter
@ -170,7 +171,7 @@ macro_rules! pyobject_native_type_convert(
/// Represents general python instance.
#[repr(transparent)]
pub struct PyObjectRef(crate::PyObject);
pub struct PyObjectRef(PyObject);
pyobject_native_type_named!(PyObjectRef);
pyobject_native_type_convert!(PyObjectRef, ffi::PyBaseObject_Type, ffi::PyObject_Check);

View File

@ -1,8 +1,9 @@
//! common macros for num2.rs and num3.rs
use std::os::raw::c_int;
use crate::err::{PyErr, PyResult};
use crate::python::Python;
use std::os::raw::c_int;
pub(super) fn err_if_invalid_value<T: PartialEq>(
py: Python,
@ -17,7 +18,7 @@ pub(super) fn err_if_invalid_value<T: PartialEq>(
}
#[macro_export]
macro_rules! int_fits_larger_int(
macro_rules! int_fits_larger_int (
($rust_type:ty, $larger_type:ty) => (
impl ToPyObject for $rust_type {
#[inline]
@ -56,6 +57,9 @@ macro_rules! int_convert_bignum (
impl IntoPyObject for $rust_type {
fn into_object(self, py: Python) -> PyObject {
unsafe {
// TODO: Replace this with functions from the from_bytes family
// Once they are stabilized
// https://github.com/rust-lang/rust/issues/52963
let bytes = ::std::mem::transmute::<_, [c_uchar; $byte_size]>(self);
let obj = ffi::_PyLong_FromByteArray(
bytes.as_ptr() as *const c_uchar,
@ -101,9 +105,10 @@ pub(super) const IS_LITTLE_ENDIAN: c_int = 0;
#[cfg(test)]
mod test {
use std;
use crate::conversion::ToPyObject;
use crate::python::Python;
use std;
#[test]
fn test_u32_max() {

View File

@ -7,15 +7,17 @@ use std::borrow::Cow;
use std::os::raw::c_char;
use std::str;
use super::PyObjectRef;
use err::{PyErr, PyResult};
use ffi;
use instance::{Py, PyObjectWithGIL};
use object::PyObject;
use objectprotocol::ObjectProtocol;
use python::IntoPyPointer;
use python::{Python, ToPyPointer};
use types::exceptions;
use super::PyObjectRef;
/// Represents a Python `string`.
#[repr(transparent)]
pub struct PyString(PyObject);
@ -190,7 +192,7 @@ impl PyUnicode {
impl std::convert::From<Py<PyBytes>> for Py<PyString> {
#[inline]
fn from(ob: Py<PyBytes>) -> Py<PyString> {
unsafe { std::mem::transmute(ob) }
unsafe { Py::from_owned_ptr(ob.into_ptr()) }
}
}
@ -198,18 +200,20 @@ impl std::convert::From<Py<PyBytes>> for Py<PyString> {
impl std::convert::From<Py<PyUnicode>> for Py<PyString> {
#[inline]
fn from(ob: Py<PyUnicode>) -> Py<PyString> {
unsafe { std::mem::transmute(ob) }
unsafe { Py::from_owned_ptr(ob.into_ptr()) }
}
}
#[cfg(test)]
mod test {
use super::PyString;
use std::borrow::Cow;
use conversion::{FromPyObject, PyTryFrom, ToPyObject};
use instance::AsPyRef;
use object::PyObject;
use python::Python;
use std::borrow::Cow;
use super::PyString;
#[test]
fn test_non_bmp() {