From aadde4cd0c3dc8162cf374d93b0a2e264d8f6064 Mon Sep 17 00:00:00 2001 From: konstin Date: Mon, 18 Jun 2018 15:45:15 +0200 Subject: [PATCH 1/6] Fix a scope in the macro output --- pyo3-derive-backend/src/py_method.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyo3-derive-backend/src/py_method.rs b/pyo3-derive-backend/src/py_method.rs index 3325da73..170f81f3 100644 --- a/pyo3-derive-backend/src/py_method.rs +++ b/pyo3-derive-backend/src/py_method.rs @@ -50,8 +50,7 @@ fn check_generic(name: &syn::Ident, sig: &syn::MethodSig) { pub fn body_to_result(body: &TokenStream, spec: &FnSpec) -> TokenStream { let output = &spec.output; quote! { - use pyo3::ReturnTypeIntoPyResult; - let _result: PyResult<<#output as ReturnTypeIntoPyResult>::Inner> = { + let _result: ::pyo3::PyResult<<#output as ::pyo3::ReturnTypeIntoPyResult>::Inner> = { #body }; } From 3ec49b586fa9fccb06f061f195457fb74835c781 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Sun, 1 Jul 2018 23:51:56 +0900 Subject: [PATCH 2/6] Modify pyobject_native_type to take path instead of ident So that we can use this macro outside this crate. --- src/objects/boolobject.rs | 2 +- src/objects/bytearray.rs | 2 +- src/objects/dict.rs | 2 +- src/objects/floatob.rs | 2 +- src/objects/list.rs | 2 +- src/objects/mod.rs | 18 +++++++++--------- src/objects/module.rs | 2 +- src/objects/num2.rs | 4 ++-- src/objects/num3.rs | 2 +- src/objects/sequence.rs | 2 +- src/objects/set.rs | 3 ++- src/objects/slice.rs | 2 +- src/objects/string.rs | 4 ++-- src/objects/string2.rs | 6 +++--- src/objects/tuple.rs | 2 +- src/objects/typeobject.rs | 2 +- 16 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/objects/boolobject.rs b/src/objects/boolobject.rs index 4f45912b..ba83718c 100644 --- a/src/objects/boolobject.rs +++ b/src/objects/boolobject.rs @@ -7,7 +7,7 @@ use conversion::{ToPyObject, IntoPyObject, ToBorrowedObject, PyTryFrom}; /// Represents a Python `bool`. pub struct PyBool(PyObject); -pyobject_native_type!(PyBool, PyBool_Type, PyBool_Check); +pyobject_native_type!(PyBool, ffi::PyBool_Type, ffi::PyBool_Check); impl PyBool { diff --git a/src/objects/bytearray.rs b/src/objects/bytearray.rs index 58f164df..b75a6837 100644 --- a/src/objects/bytearray.rs +++ b/src/objects/bytearray.rs @@ -11,7 +11,7 @@ use err::{PyResult, PyErr}; /// Represents a Python `bytearray`. pub struct PyByteArray(PyObject); -pyobject_native_type!(PyByteArray, PyByteArray_Type, PyByteArray_Check); +pyobject_native_type!(PyByteArray, ffi::PyByteArray_Type, ffi::PyByteArray_Check); impl PyByteArray { /// Creates a new Python bytearray object. diff --git a/src/objects/dict.rs b/src/objects/dict.rs index 7a9c523a..0eb5b99d 100644 --- a/src/objects/dict.rs +++ b/src/objects/dict.rs @@ -14,7 +14,7 @@ use err::{self, PyResult, PyErr}; /// Represents a Python `dict`. pub struct PyDict(PyObject); -pyobject_native_type!(PyDict, PyDict_Type, PyDict_Check); +pyobject_native_type!(PyDict, ffi::PyDict_Type, ffi::PyDict_Check); impl PyDict { diff --git a/src/objects/floatob.rs b/src/objects/floatob.rs index dfc8c55b..75943587 100644 --- a/src/objects/floatob.rs +++ b/src/objects/floatob.rs @@ -20,7 +20,7 @@ use objectprotocol::ObjectProtocol; /// with `f32`/`f64`. pub struct PyFloat(PyObject); -pyobject_native_type!(PyFloat, PyFloat_Type, PyFloat_Check); +pyobject_native_type!(PyFloat, ffi::PyFloat_Type, ffi::PyFloat_Check); impl PyFloat { diff --git a/src/objects/list.rs b/src/objects/list.rs index 3c493615..f5585469 100644 --- a/src/objects/list.rs +++ b/src/objects/list.rs @@ -15,7 +15,7 @@ use conversion::{ToPyObject, IntoPyObject, ToBorrowedObject}; /// Represents a Python `list`. pub struct PyList(PyObject); -pyobject_native_type!(PyList, PyList_Type, PyList_Check); +pyobject_native_type!(PyList, ffi::PyList_Type, ffi::PyList_Check); impl PyList { /// Construct a new list with the given elements. diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 9ffe3c55..3a35d73b 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -35,7 +35,7 @@ pub use self::num2::{PyInt, PyLong}; /// parameter #[macro_export] macro_rules! pyobject_downcast( - ($name: ident, $checkfunction: ident) => ( + ($name: ident, $checkfunction: path) => ( impl<'a> $crate::FromPyObject<'a> for &'a $name { /// Extracts `Self` from the source `PyObject`. @@ -43,7 +43,7 @@ macro_rules! pyobject_downcast( fn extract(ob: &'a $crate::PyObjectRef) -> $crate::PyResult { unsafe { - if $crate::ffi::$checkfunction(ob.as_ptr()) != 0 { + if $checkfunction(ob.as_ptr()) != 0 { Ok($crate::std::mem::transmute(ob)) } else { Err($crate::PyDowncastError.into()) @@ -92,7 +92,7 @@ macro_rules! pyobject_native_type_named( #[macro_export] macro_rules! pyobject_native_type( - ($name: ident, $typeobject: ident, $checkfunction: ident) => { + ($name: ident, $typeobject: path, $checkfunction: path) => { pyobject_native_type_named!($name); pyobject_native_type_convert!($name, $typeobject, $checkfunction); pyobject_downcast!($name, $checkfunction); @@ -107,7 +107,7 @@ macro_rules! pyobject_native_type( #[macro_export] macro_rules! pyobject_native_type_convert( - ($name: ident, $typeobject: ident, $checkfunction: ident) => { + ($name: ident, $typeobject: path, $checkfunction: path) => { impl $crate::typeob::PyTypeInfo for $name { type Type = (); type BaseType = $crate::PyObjectRef; @@ -118,13 +118,13 @@ macro_rules! pyobject_native_type_convert( #[inline] unsafe fn type_object() -> &'static mut $crate::ffi::PyTypeObject { - &mut $crate::ffi::$typeobject + &mut $typeobject } #[cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))] fn is_instance(ptr: *mut $crate::ffi::PyObject) -> bool { #[allow(unused_unsafe)] - unsafe { $crate::ffi::$checkfunction(ptr) > 0 } + unsafe { $checkfunction(ptr) > 0 } } } @@ -207,12 +207,12 @@ macro_rules! pyobject_extract( use python::ToPyPointer; - +use ffi; /// Represents general python instance. pub struct PyObjectRef(::PyObject); pyobject_native_type_named!(PyObjectRef); -pyobject_native_type_convert!(PyObjectRef, PyBaseObject_Type, PyObject_Check); -pyobject_downcast!(PyObjectRef, PyObject_Check); +pyobject_native_type_convert!(PyObjectRef, ffi::PyBaseObject_Type, ffi::PyObject_Check); +pyobject_downcast!(PyObjectRef, ffi::PyObject_Check); mod typeobject; mod module; diff --git a/src/objects/module.rs b/src/objects/module.rs index 8234d921..3f15c5aa 100644 --- a/src/objects/module.rs +++ b/src/objects/module.rs @@ -19,7 +19,7 @@ use err::{PyResult, PyErr}; /// Represents a Python `module` object. pub struct PyModule(PyObject); -pyobject_native_type!(PyModule, PyModule_Type, PyModule_Check); +pyobject_native_type!(PyModule, ffi::PyModule_Type, ffi::PyModule_Check); impl PyModule { diff --git a/src/objects/num2.rs b/src/objects/num2.rs index cea2fcef..abab7d29 100644 --- a/src/objects/num2.rs +++ b/src/objects/num2.rs @@ -26,7 +26,7 @@ use super::num_common::{err_if_invalid_value, IS_LITTLE_ENDIAN}; /// with the primitive Rust integer types. pub struct PyInt(PyObject); -pyobject_native_type!(PyInt, PyInt_Type, PyInt_Check); +pyobject_native_type!(PyInt, ffi::PyInt_Type, ffi::PyInt_Check); /// In Python 2.x, represents a Python `long` object. /// Both `PyInt` and `PyLong` refer to the same type on Python 3.x. @@ -37,7 +37,7 @@ pyobject_native_type!(PyInt, PyInt_Type, PyInt_Check); /// with the primitive Rust integer types. pub struct PyLong(PyObject); -pyobject_native_type!(PyLong, PyLong_Type, PyLong_Check); +pyobject_native_type!(PyLong, ffi::PyLong_Type, ffi::PyLong_Check); impl PyInt { /// Creates a new Python 2.7 `int` object. diff --git a/src/objects/num3.rs b/src/objects/num3.rs index 259f1c7c..c3f255c9 100644 --- a/src/objects/num3.rs +++ b/src/objects/num3.rs @@ -23,7 +23,7 @@ use super::num_common::{err_if_invalid_value, IS_LITTLE_ENDIAN}; /// with the primitive Rust integer types. pub struct PyLong(PyObject); -pyobject_native_type!(PyLong, PyLong_Type, PyLong_Check); +pyobject_native_type!(PyLong, ffi::PyLong_Type, ffi::PyLong_Check); macro_rules! int_fits_c_long( ($rust_type:ty) => ( diff --git a/src/objects/sequence.rs b/src/objects/sequence.rs index b5450dae..b4e9e91f 100644 --- a/src/objects/sequence.rs +++ b/src/objects/sequence.rs @@ -16,7 +16,7 @@ use objectprotocol::ObjectProtocol; /// Represents a reference to a python object supporting the sequence protocol. pub struct PySequence(PyObject); pyobject_native_type_named!(PySequence); -pyobject_downcast!(PySequence, PySequence_Check); +pyobject_downcast!(PySequence, ffi::PySequence_Check); #[cfg_attr(feature = "cargo-clippy", allow(len_without_is_empty))] diff --git a/src/objects/set.rs b/src/objects/set.rs index 6f7ef917..02a4d58a 100644 --- a/src/objects/set.rs +++ b/src/objects/set.rs @@ -17,7 +17,8 @@ pub struct PySet(PyObject); pub struct PyFrozenSet(PyObject); -pyobject_native_type!(PySet, PySet_Type, PySet_Check);pyobject_native_type!(PyFrozenSet, PyFrozenSet_Type, PyFrozenSet_Check); +pyobject_native_type!(PySet, ffi::PySet_Type, ffi::PySet_Check); +pyobject_native_type!(PyFrozenSet, ffi::PyFrozenSet_Type, ffi::PyFrozenSet_Check); impl PySet { /// Creates a new set. diff --git a/src/objects/slice.rs b/src/objects/slice.rs index 49da9431..00817b7f 100644 --- a/src/objects/slice.rs +++ b/src/objects/slice.rs @@ -14,7 +14,7 @@ use conversion::ToPyObject; /// Only `c_long` indeces supprted at the moment by `PySlice` object. pub struct PySlice(PyObject); -pyobject_native_type!(PySlice, PySlice_Type, PySlice_Check); +pyobject_native_type!(PySlice, ffi::PySlice_Type, ffi::PySlice_Check); /// Represents a Python `slice` indices diff --git a/src/objects/string.rs b/src/objects/string.rs index 4d55c5d5..ab1b4a4d 100644 --- a/src/objects/string.rs +++ b/src/objects/string.rs @@ -16,7 +16,7 @@ use super::PyStringData; /// Represents a Python `string`. pub struct PyString(PyObject); -pyobject_native_type!(PyString, PyUnicode_Type, PyUnicode_Check); +pyobject_native_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check); /// Represents a Python `unicode string`. /// Corresponds to `unicode` in Python 2, and `str` in Python 3. @@ -25,7 +25,7 @@ pub use PyString as PyUnicode; /// Represents a Python `byte` string. pub struct PyBytes(PyObject); -pyobject_native_type!(PyBytes, PyBytes_Type, PyBytes_Check); +pyobject_native_type!(PyBytes, ffi::PyBytes_Type, ffi::PyBytes_Check); impl PyString { diff --git a/src/objects/string2.rs b/src/objects/string2.rs index cd3b77c5..5657f5a0 100644 --- a/src/objects/string2.rs +++ b/src/objects/string2.rs @@ -18,17 +18,17 @@ use super::{PyObjectRef, PyStringData}; /// Represents a Python `string`. pub struct PyString(PyObject); -pyobject_native_type!(PyString, PyBaseString_Type, PyBaseString_Check); +pyobject_native_type!(PyString, ffi::PyBaseString_Type, ffi::PyBaseString_Check); /// Represents a Python `unicode string`. pub struct PyUnicode(PyObject); -pyobject_native_type!(PyUnicode, PyUnicode_Type, PyUnicode_Check); +pyobject_native_type!(PyUnicode, ffi::PyUnicode_Type, ffi::PyUnicode_Check); /// Represents a Python `byte` string. Corresponds to `str` in Python 2 pub struct PyBytes(PyObject); -pyobject_native_type!(PyBytes, PyBaseString_Type, PyString_Check); +pyobject_native_type!(PyBytes, ffi::PyBaseString_Type, ffi::PyString_Check); impl PyString { diff --git a/src/objects/tuple.rs b/src/objects/tuple.rs index 5fd47c3c..81dd4d26 100644 --- a/src/objects/tuple.rs +++ b/src/objects/tuple.rs @@ -15,7 +15,7 @@ use super::exc; /// Represents a Python `tuple` object. pub struct PyTuple(PyObject); -pyobject_native_type!(PyTuple, PyTuple_Type, PyTuple_Check); +pyobject_native_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check); impl PyTuple { diff --git a/src/objects/typeobject.rs b/src/objects/typeobject.rs index 832063d1..5b5dc581 100644 --- a/src/objects/typeobject.rs +++ b/src/objects/typeobject.rs @@ -15,7 +15,7 @@ use typeob::{PyTypeInfo, PyTypeObject}; /// Represents a reference to a Python `type object`. pub struct PyType(PyObject); -pyobject_native_type!(PyType, PyType_Type, PyType_Check); +pyobject_native_type!(PyType, ffi::PyType_Type, ffi::PyType_Check); impl PyType { From 70e1879d59855e134837126c45deb129c1e4b495 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 2 Jul 2018 00:06:01 +0900 Subject: [PATCH 3/6] Make python pub --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4652aee6..b2682fb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -204,7 +204,7 @@ macro_rules! wrap_function ( }; ); -mod python; +pub mod python; mod err; mod conversion; mod instance; From 41f4d1d673b4aff136c794b773ba9e80bf1d423c Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 2 Jul 2018 00:06:08 +0900 Subject: [PATCH 4/6] $crate::std to ::std So that we can use these macros in outer crates --- src/objects/mod.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 3a35d73b..d07a75e1 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -44,7 +44,7 @@ macro_rules! pyobject_downcast( { unsafe { if $checkfunction(ob.as_ptr()) != 0 { - Ok($crate::std::mem::transmute(ob)) + Ok(::std::mem::transmute(ob)) } else { Err($crate::PyDowncastError.into()) } @@ -59,10 +59,10 @@ macro_rules! pyobject_native_type_named( ($name: ident) => { impl $crate::PyNativeType for $name {} - impl $crate::std::convert::AsRef<$crate::PyObjectRef> for $name { + impl ::std::convert::AsRef<$crate::PyObjectRef> for $name { #[cfg_attr(feature = "cargo-clippy", allow(useless_transmute))] fn as_ref(&self) -> &$crate::PyObjectRef { - unsafe{$crate::std::mem::transmute(self)} + unsafe{::std::mem::transmute(self)} } } @@ -97,9 +97,9 @@ macro_rules! pyobject_native_type( pyobject_native_type_convert!($name, $typeobject, $checkfunction); pyobject_downcast!($name, $checkfunction); - impl<'a> $crate::std::convert::From<&'a $name> for &'a $crate::PyObjectRef { + impl<'a> ::std::convert::From<&'a $name> for &'a $crate::PyObjectRef { fn from(ob: &'a $name) -> Self { - unsafe{$crate::std::mem::transmute(ob)} + unsafe{::std::mem::transmute(ob)} } } }; @@ -113,7 +113,7 @@ macro_rules! pyobject_native_type_convert( type BaseType = $crate::PyObjectRef; const NAME: &'static str = stringify!($name); - const SIZE: usize = $crate::std::mem::size_of::<$crate::ffi::PyObject>(); + const SIZE: usize = ::std::mem::size_of::<$crate::ffi::PyObject>(); const OFFSET: isize = 0; #[inline] @@ -156,22 +156,22 @@ macro_rules! pyobject_native_type_convert( } } - impl $crate::std::fmt::Debug for $name { - fn fmt(&self, f: &mut $crate::std::fmt::Formatter) - -> Result<(), $crate::std::fmt::Error> + impl ::std::fmt::Debug for $name { + fn fmt(&self, f: &mut ::std::fmt::Formatter) + -> Result<(), ::std::fmt::Error> { use $crate::ObjectProtocol; - let s = try!(self.repr().map_err(|_| $crate::std::fmt::Error)); + let s = try!(self.repr().map_err(|_| ::std::fmt::Error)); f.write_str(&s.to_string_lossy()) } } - impl $crate::std::fmt::Display for $name { - fn fmt(&self, f: &mut $crate::std::fmt::Formatter) - -> Result<(), $crate::std::fmt::Error> + impl ::std::fmt::Display for $name { + fn fmt(&self, f: &mut ::std::fmt::Formatter) + -> Result<(), ::std::fmt::Error> { use $crate::ObjectProtocol; - let s = try!(self.str().map_err(|_| $crate::std::fmt::Error)); + let s = try!(self.str().map_err(|_| ::std::fmt::Error)); f.write_str(&s.to_string_lossy()) } } @@ -193,7 +193,7 @@ macro_rules! pyobject_extract( } #[cfg(feature = "try_from")] - impl<'source> $crate::std::convert::TryFrom<&'source $crate::PyObjectRef> for $t + impl<'source> ::std::convert::TryFrom<&'source $crate::PyObjectRef> for $t { type Error = $crate::PyErr; From 9ce5e8cf28fe567d019be4b791f1797ddffebfd4 Mon Sep 17 00:00:00 2001 From: konstin Date: Sun, 1 Jul 2018 17:15:29 +0200 Subject: [PATCH 5/6] Update README.md Thanks to @mre in https://github.com/PyO3/pyo3/issues/172#issuecomment-401612673 --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2edea9f9..e15f5060 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,15 @@ fn sum_as_string(a:i64, b:i64) -> String { ``` -**To build**: `cargo rustc --release` +On windows and linux, you can build normally with `cargo build --release`. On Mac Os, you need to set additional linker arguments. One option is to compile with `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config` with the following content: -**On a Mac**: `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup` +```toml +[target.x86_64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] +``` Also on macOS, you will need to rename the output from \*.dylib to \*.so. On Windows, you will need to rename the output from \*.dll to \*.pyd. From 7d7c1ede497917ffd6f98a763927e6c83fa093da Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 2 Jul 2018 16:31:36 +0900 Subject: [PATCH 6/6] Modify pyobject_native_type to take expr To use deref(*) expression --- src/objects/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects/mod.rs b/src/objects/mod.rs index d07a75e1..1117253e 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -92,7 +92,7 @@ macro_rules! pyobject_native_type_named( #[macro_export] macro_rules! pyobject_native_type( - ($name: ident, $typeobject: path, $checkfunction: path) => { + ($name: ident, $typeobject: expr, $checkfunction: path) => { pyobject_native_type_named!($name); pyobject_native_type_convert!($name, $typeobject, $checkfunction); pyobject_downcast!($name, $checkfunction); @@ -107,7 +107,7 @@ macro_rules! pyobject_native_type( #[macro_export] macro_rules! pyobject_native_type_convert( - ($name: ident, $typeobject: path, $checkfunction: path) => { + ($name: ident, $typeobject: expr, $checkfunction: path) => { impl $crate::typeob::PyTypeInfo for $name { type Type = (); type BaseType = $crate::PyObjectRef;