rust 1.50: clippy and lint fixes

This commit is contained in:
David Hewitt 2021-02-11 21:37:38 +00:00
parent 83f71d85fa
commit b2675b11fe
22 changed files with 154 additions and 172 deletions

View File

@ -192,12 +192,12 @@ impl TzClass {
PyDelta::new(py, 0, 3600, 0, true) PyDelta::new(py, 0, 3600, 0, true)
} }
fn tzname(&self, _py: Python<'_>, _dt: &PyDateTime) -> PyResult<String> { fn tzname(&self, _py: Python<'_>, _dt: &PyDateTime) -> String {
Ok(String::from("+01:00")) String::from("+01:00")
} }
fn dst(&self, _py: Python<'_>, _dt: &PyDateTime) -> PyResult<Option<&PyDelta>> { fn dst(&self, _py: Python<'_>, _dt: &PyDateTime) -> Option<&PyDelta> {
Ok(None) None
} }
} }

View File

@ -2,11 +2,10 @@ use pyo3::prelude::*;
use pyo3::wrap_pyfunction; use pyo3::wrap_pyfunction;
#[pyfunction] #[pyfunction]
fn issue_219() -> PyResult<()> { fn issue_219() {
// issue 219: acquiring GIL inside #[pyfunction] deadlocks. // issue 219: acquiring GIL inside #[pyfunction] deadlocks.
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let _py = gil.python(); let _py = gil.python();
Ok(())
} }
#[pymodule] #[pymodule]

View File

@ -663,7 +663,7 @@ pub fn impl_py_method_def_call(spec: &FnSpec, wrapper: &TokenStream) -> TokenStr
pyo3::class::PyMethodDefType::Call({ pyo3::class::PyMethodDefType::Call({
#wrapper #wrapper
pyo3::class::PyMethodDef::cfunction_with_keywords( pyo3::class::PyMethodDef::call_func(
concat!(stringify!(#python_name), "\0"), concat!(stringify!(#python_name), "\0"),
__wrap, __wrap,
pyo3::ffi::METH_STATIC, pyo3::ffi::METH_STATIC,

View File

@ -10,15 +10,15 @@ use std::os::raw::c_int;
#[derive(Debug)] #[derive(Debug)]
pub enum PyMethodDefType { pub enum PyMethodDefType {
/// Represents class `__new__` method /// Represents class `__new__` method
New(PyMethodDef), New(PyMethodDef<ffi::newfunc>),
/// Represents class `__call__` method /// Represents class `__call__` method
Call(PyMethodDef), Call(PyMethodDef<ffi::PyCFunctionWithKeywords>),
/// Represents class method /// Represents class method
Class(PyMethodDef), Class(PyMethodDef<PyMethodType>),
/// Represents static method /// Represents static method
Static(PyMethodDef), Static(PyMethodDef<PyMethodType>),
/// Represents normal method /// Represents normal method
Method(PyMethodDef), Method(PyMethodDef<PyMethodType>),
/// Represents class attribute, used by `#[attribute]` /// Represents class attribute, used by `#[attribute]`
ClassAttribute(PyClassAttributeDef), ClassAttribute(PyClassAttributeDef),
/// Represents getter descriptor, used by `#[getter]` /// Represents getter descriptor, used by `#[getter]`
@ -31,14 +31,12 @@ pub enum PyMethodDefType {
pub enum PyMethodType { pub enum PyMethodType {
PyCFunction(ffi::PyCFunction), PyCFunction(ffi::PyCFunction),
PyCFunctionWithKeywords(ffi::PyCFunctionWithKeywords), PyCFunctionWithKeywords(ffi::PyCFunctionWithKeywords),
PyNewFunc(ffi::newfunc),
PyInitFunc(ffi::initproc),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PyMethodDef { pub struct PyMethodDef<MethodT> {
pub(crate) ml_name: &'static CStr, pub(crate) ml_name: &'static CStr,
pub(crate) ml_meth: PyMethodType, pub(crate) ml_meth: MethodT,
pub(crate) ml_flags: c_int, pub(crate) ml_flags: c_int,
pub(crate) ml_doc: &'static CStr, pub(crate) ml_doc: &'static CStr,
} }
@ -63,7 +61,9 @@ pub struct PySetterDef {
doc: &'static CStr, doc: &'static CStr,
} }
unsafe impl Sync for PyMethodDef {} // Safe because ml_meth (the T) cannot be accessed outside of the crate, so only safe-to-sync values
// are stored in this structure.
unsafe impl<T> Sync for PyMethodDef<T> {}
unsafe impl Sync for ffi::PyMethodDef {} unsafe impl Sync for ffi::PyMethodDef {}
@ -82,23 +82,36 @@ fn get_doc(doc: &str) -> &CStr {
CStr::from_bytes_with_nul(doc.as_bytes()).expect("Document must be terminated with NULL byte") CStr::from_bytes_with_nul(doc.as_bytes()).expect("Document must be terminated with NULL byte")
} }
impl PyMethodDef { impl PyMethodDef<ffi::newfunc> {
pub(crate) fn get_new_func(&self) -> Option<ffi::newfunc> { /// Define a `__new__` function.
if let PyMethodType::PyNewFunc(new_func) = self.ml_meth { pub fn new_func(name: &'static str, newfunc: ffi::newfunc, doc: &'static str) -> Self {
Some(new_func) Self {
} else { ml_name: get_name(name),
None ml_meth: newfunc,
ml_flags: ffi::METH_VARARGS | ffi::METH_KEYWORDS,
ml_doc: get_doc(doc),
} }
} }
}
pub(crate) fn get_cfunction_with_keywords(&self) -> Option<ffi::PyCFunctionWithKeywords> { impl PyMethodDef<ffi::PyCFunctionWithKeywords> {
if let PyMethodType::PyCFunctionWithKeywords(func) = self.ml_meth { /// Define a `__call__` function.
Some(func) pub fn call_func(
} else { name: &'static str,
None callfunc: ffi::PyCFunctionWithKeywords,
flags: c_int,
doc: &'static str,
) -> Self {
Self {
ml_name: get_name(name),
ml_meth: callfunc,
ml_flags: flags | ffi::METH_VARARGS | ffi::METH_KEYWORDS,
ml_doc: get_doc(doc),
} }
} }
}
impl PyMethodDef<PyMethodType> {
/// Define a function with no `*args` and `**kwargs`. /// Define a function with no `*args` and `**kwargs`.
pub fn cfunction(name: &'static str, cfunction: ffi::PyCFunction, doc: &'static str) -> Self { pub fn cfunction(name: &'static str, cfunction: ffi::PyCFunction, doc: &'static str) -> Self {
Self { Self {
@ -109,16 +122,6 @@ impl PyMethodDef {
} }
} }
/// Define a `__new__` function.
pub fn new_func(name: &'static str, newfunc: ffi::newfunc, doc: &'static str) -> Self {
Self {
ml_name: get_name(name),
ml_meth: PyMethodType::PyNewFunc(newfunc),
ml_flags: ffi::METH_VARARGS | ffi::METH_KEYWORDS,
ml_doc: get_doc(doc),
}
}
/// Define a function that can take `*args` and `**kwargs`. /// Define a function that can take `*args` and `**kwargs`.
pub fn cfunction_with_keywords( pub fn cfunction_with_keywords(
name: &'static str, name: &'static str,
@ -139,8 +142,6 @@ impl PyMethodDef {
let meth = match self.ml_meth { let meth = match self.ml_meth {
PyMethodType::PyCFunction(meth) => meth, PyMethodType::PyCFunction(meth) => meth,
PyMethodType::PyCFunctionWithKeywords(meth) => unsafe { std::mem::transmute(meth) }, PyMethodType::PyCFunctionWithKeywords(meth) => unsafe { std::mem::transmute(meth) },
PyMethodType::PyNewFunc(meth) => unsafe { std::mem::transmute(meth) },
PyMethodType::PyInitFunc(meth) => unsafe { std::mem::transmute(meth) },
}; };
ffi::PyMethodDef { ffi::PyMethodDef {

View File

@ -51,6 +51,6 @@ extern "C" {
pub fn PyCodec_ReplaceErrors(exc: *mut PyObject) -> *mut PyObject; pub fn PyCodec_ReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_XMLCharRefReplaceErrors(exc: *mut PyObject) -> *mut PyObject; pub fn PyCodec_XMLCharRefReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_BackslashReplaceErrors(exc: *mut PyObject) -> *mut PyObject; pub fn PyCodec_BackslashReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
// skipped non-limited PyCodec_NameReplaceErrors from Include/codecs.h // skipped non-limited PyCodec_NameReplaceErrors from Include/codecs.h
// skipped non-limited Py_hexdigits from Include/codecs.h // skipped non-limited Py_hexdigits from Include/codecs.h
} }

View File

@ -80,8 +80,8 @@ extern "C" {
#[cfg(Py_3_8)] #[cfg(Py_3_8)]
pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int; pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int;
// skipped non-limited _PyASTOptimizeState // skipped non-limited _PyASTOptimizeState
// skipped non-limited _PyAST_Optimize // skipped non-limited _PyAST_Optimize
} }
pub const Py_single_input: c_int = 256; pub const Py_single_input: c_int = 256;

View File

@ -56,6 +56,6 @@ extern "C" {
pub fn PyComplex_RealAsDouble(op: *mut PyObject) -> c_double; pub fn PyComplex_RealAsDouble(op: *mut PyObject) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyComplex_ImagAsDouble")] #[cfg_attr(PyPy, link_name = "PyPyComplex_ImagAsDouble")]
pub fn PyComplex_ImagAsDouble(op: *mut PyObject) -> c_double; pub fn PyComplex_ImagAsDouble(op: *mut PyObject) -> c_double;
// skipped non-limited PyComplex_AsCComplex // skipped non-limited PyComplex_AsCComplex
// skipped non-limited _PyComplex_FormatAdvancedWriter // skipped non-limited _PyComplex_FormatAdvancedWriter
} }

View File

@ -7,7 +7,7 @@ extern "C" {
pub static mut PyContextVar_Type: PyTypeObject; pub static mut PyContextVar_Type: PyTypeObject;
// skipped non-limited opaque PyContextVar // skipped non-limited opaque PyContextVar
pub static mut PyContextToken_Type: PyTypeObject; pub static mut PyContextToken_Type: PyTypeObject;
// skipped non-limited opaque PyContextToken // skipped non-limited opaque PyContextToken
} }
#[inline] #[inline]
@ -41,5 +41,5 @@ extern "C" {
) -> c_int; ) -> c_int;
pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject; pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int; pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int;
// skipped non-limited _PyContext_NewHamtForTests // skipped non-limited _PyContext_NewHamtForTests
} }

View File

@ -48,7 +48,7 @@ extern "C" {
pub static mut PyWrapperDescr_Type: PyTypeObject; pub static mut PyWrapperDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyDictProxy_Type")] #[cfg_attr(PyPy, link_name = "PyPyDictProxy_Type")]
pub static mut PyDictProxy_Type: PyTypeObject; pub static mut PyDictProxy_Type: PyTypeObject;
// skipped non-limited _PyMethodWrapper_Type // skipped non-limited _PyMethodWrapper_Type
} }
extern "C" { extern "C" {

View File

@ -64,7 +64,7 @@ extern "C" {
) -> c_int; ) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_DelItemString")] #[cfg_attr(PyPy, link_name = "PyPyDict_DelItemString")]
pub fn PyDict_DelItemString(dp: *mut PyObject, key: *const c_char) -> c_int; pub fn PyDict_DelItemString(dp: *mut PyObject, key: *const c_char) -> c_int;
// skipped 3.10 / ex-non-limited PyObject_GenericGetDict // skipped 3.10 / ex-non-limited PyObject_GenericGetDict
} }
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]

View File

@ -22,6 +22,6 @@ extern "C" {
closure: *mut PyObject, closure: *mut PyObject,
) -> *mut PyObject; ) -> *mut PyObject;
// skipped non-limited _PyEval_EvalCodeWithName // skipped non-limited _PyEval_EvalCodeWithName
// skipped non-limited _PyEval_CallTracing // skipped non-limited _PyEval_CallTracing
} }

View File

@ -29,7 +29,7 @@ extern "C" {
pub static mut Py_FileSystemDefaultEncoding: *const c_char; pub static mut Py_FileSystemDefaultEncoding: *const c_char;
pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char; pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char;
pub static mut Py_HasFileSystemDefaultEncoding: c_int; pub static mut Py_HasFileSystemDefaultEncoding: c_int;
// skipped Python 3.7 / ex-non-limited Py_UTF8Mode // skipped Python 3.7 / ex-non-limited Py_UTF8Mode
} }
// skipped _PyIsSelectable_fd // skipped _PyIsSelectable_fd

View File

@ -79,9 +79,9 @@ pub unsafe fn PyCoroWrapper_Check(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" { extern "C" {
pub static mut PyAsyncGen_Type: PyTypeObject; pub static mut PyAsyncGen_Type: PyTypeObject;
// skipped _PyAsyncGenASend_Type // skipped _PyAsyncGenASend_Type
// skipped _PyAsyncGenWrappedValue_Type // skipped _PyAsyncGenWrappedValue_Type
// skipped _PyAsyncGenAThrow_Type // skipped _PyAsyncGenAThrow_Type
} }
// skipped PyAsyncGen_New // skipped PyAsyncGen_New

View File

@ -20,6 +20,6 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyOS_AfterFork")] #[cfg_attr(PyPy, link_name = "PyPyOS_AfterFork")]
pub fn PyOS_AfterFork(); pub fn PyOS_AfterFork();
// skipped non-limited _PyOS_IsMainThread // skipped non-limited _PyOS_IsMainThread
// skipped non-limited Windows _PyOS_SigintEvent // skipped non-limited Windows _PyOS_SigintEvent
} }

View File

@ -102,16 +102,13 @@ pub trait PyClassAlloc: PyTypeInfo + Sized {
} }
} }
fn tp_dealloc<T: PyClassAlloc>() -> Option<ffi::destructor> { unsafe extern "C" fn tp_dealloc<T>(obj: *mut ffi::PyObject)
unsafe extern "C" fn dealloc<T>(obj: *mut ffi::PyObject) where
where T: PyClassAlloc,
T: PyClassAlloc, {
{ let pool = crate::GILPool::new();
let pool = crate::GILPool::new(); let py = pool.python();
let py = pool.python(); <T as PyClassAlloc>::dealloc(py, (obj as *mut T::Layout) as _)
<T as PyClassAlloc>::dealloc(py, (obj as *mut T::Layout) as _)
}
Some(dealloc::<T>)
} }
pub(crate) unsafe fn tp_free_fallback(ty: *mut ffi::PyTypeObject) -> ffi::freefunc { pub(crate) unsafe fn tp_free_fallback(ty: *mut ffi::PyTypeObject) -> ffi::freefunc {
@ -152,11 +149,6 @@ impl TypeSlots {
fn push(&mut self, slot: c_int, pfunc: *mut c_void) { fn push(&mut self, slot: c_int, pfunc: *mut c_void) {
self.0.push(ffi::PyType_Slot { slot, pfunc }); self.0.push(ffi::PyType_Slot { slot, pfunc });
} }
pub(crate) fn maybe_push(&mut self, slot: c_int, value: Option<*mut c_void>) {
if let Some(pfunc) = value {
self.push(slot, pfunc);
}
}
} }
fn tp_doc<T: PyClass>() -> PyResult<Option<*mut c_void>> { fn tp_doc<T: PyClass>() -> PyResult<Option<*mut c_void>> {
@ -189,12 +181,16 @@ where
let mut slots = TypeSlots::default(); let mut slots = TypeSlots::default();
slots.push(ffi::Py_tp_base, T::BaseType::type_object_raw(py) as _); slots.push(ffi::Py_tp_base, T::BaseType::type_object_raw(py) as _);
slots.maybe_push(ffi::Py_tp_doc, tp_doc::<T>()?); slots.push(ffi::Py_tp_dealloc, tp_dealloc::<T> as _);
slots.maybe_push(ffi::Py_tp_dealloc, tp_dealloc::<T>().map(|v| v as _)); if let Some(doc) = tp_doc::<T>()? {
slots.push(ffi::Py_tp_doc, doc);
}
let (new, call, methods) = py_class_method_defs::<T>(); let (new, call, methods) = py_class_method_defs::<T>();
slots.maybe_push(ffi::Py_tp_new, new.map(|v| v as _)); slots.push(ffi::Py_tp_new, new as _);
slots.maybe_push(ffi::Py_tp_call, call.map(|v| v as _)); if let Some(call_meth) = call {
slots.push(ffi::Py_tp_call, call_meth as _);
}
if cfg!(Py_3_9) { if cfg!(Py_3_9) {
let members = py_class_members::<T>(); let members = py_class_members::<T>();
@ -315,39 +311,34 @@ pub(crate) fn py_class_attributes<T: PyMethods>() -> impl Iterator<Item = PyClas
}) })
} }
fn fallback_new() -> Option<ffi::newfunc> { unsafe extern "C" fn fallback_new(
unsafe extern "C" fn fallback_new( _subtype: *mut ffi::PyTypeObject,
_subtype: *mut ffi::PyTypeObject, _args: *mut ffi::PyObject,
_args: *mut ffi::PyObject, _kwds: *mut ffi::PyObject,
_kwds: *mut ffi::PyObject, ) -> *mut ffi::PyObject {
) -> *mut ffi::PyObject { crate::callback_body!(py, {
crate::callback_body!(py, { Err::<(), _>(crate::exceptions::PyTypeError::new_err(
Err::<(), _>(crate::exceptions::PyTypeError::new_err( "No constructor defined",
"No constructor defined", ))
)) })
})
}
Some(fallback_new)
} }
fn py_class_method_defs<T: PyMethods>() -> ( fn py_class_method_defs<T: PyMethods>() -> (
Option<ffi::newfunc>, ffi::newfunc,
Option<ffi::PyCFunctionWithKeywords>, Option<ffi::PyCFunctionWithKeywords>,
Vec<ffi::PyMethodDef>, Vec<ffi::PyMethodDef>,
) { ) {
let mut defs = Vec::new(); let mut defs = Vec::new();
let mut call = None; let mut call = None;
let mut new = fallback_new(); let mut new = fallback_new as ffi::newfunc;
for def in T::py_methods() { for def in T::py_methods() {
match def { match def {
PyMethodDefType::New(def) => { PyMethodDefType::New(def) => {
new = def.get_new_func(); new = def.ml_meth;
debug_assert!(new.is_some());
} }
PyMethodDefType::Call(def) => { PyMethodDefType::Call(def) => {
call = def.get_cfunction_with_keywords(); call = Some(def.ml_meth);
debug_assert!(call.is_some());
} }
PyMethodDefType::Method(def) PyMethodDefType::Method(def)
| PyMethodDefType::Class(def) | PyMethodDefType::Class(def)

View File

@ -11,19 +11,18 @@ struct ClassWithProperties {
#[pymethods] #[pymethods]
impl ClassWithProperties { impl ClassWithProperties {
fn get_num(&self) -> PyResult<i32> { fn get_num(&self) -> i32 {
Ok(self.num) self.num
} }
#[getter(DATA)] #[getter(DATA)]
/// a getter for data /// a getter for data
fn get_data(&self) -> PyResult<i32> { fn get_data(&self) -> i32 {
Ok(self.num) self.num
} }
#[setter(DATA)] #[setter(DATA)]
fn set_data(&mut self, value: i32) -> PyResult<()> { fn set_data(&mut self, value: i32) {
self.num = value; self.num = value;
Ok(())
} }
#[getter] #[getter]
@ -79,8 +78,8 @@ struct GetterSetter {
#[pymethods] #[pymethods]
impl GetterSetter { impl GetterSetter {
fn get_num2(&self) -> PyResult<i32> { fn get_num2(&self) -> i32 {
Ok(self.num) self.num
} }
} }

View File

@ -13,8 +13,8 @@ struct InstanceMethod {
#[pymethods] #[pymethods]
impl InstanceMethod { impl InstanceMethod {
/// Test method /// Test method
fn method(&self) -> PyResult<i32> { fn method(&self) -> i32 {
Ok(self.member) self.member
} }
// Checks that &Self works // Checks that &Self works
@ -30,7 +30,7 @@ fn instance_method() {
let obj = PyCell::new(py, InstanceMethod { member: 42 }).unwrap(); let obj = PyCell::new(py, InstanceMethod { member: 42 }).unwrap();
let obj_ref = obj.borrow(); let obj_ref = obj.borrow();
assert_eq!(obj_ref.method().unwrap(), 42); assert_eq!(obj_ref.method(), 42);
py_assert!(py, obj, "obj.method() == 42"); py_assert!(py, obj, "obj.method() == 42");
py_assert!(py, obj, "obj.add_other(obj) == 84"); py_assert!(py, obj, "obj.add_other(obj) == 84");
py_assert!(py, obj, "obj.method.__doc__ == 'Test method'"); py_assert!(py, obj, "obj.method.__doc__ == 'Test method'");
@ -43,8 +43,8 @@ struct InstanceMethodWithArgs {
#[pymethods] #[pymethods]
impl InstanceMethodWithArgs { impl InstanceMethodWithArgs {
fn method(&self, multiplier: i32) -> PyResult<i32> { fn method(&self, multiplier: i32) -> i32 {
Ok(self.member * multiplier) self.member * multiplier
} }
} }
@ -56,7 +56,7 @@ fn instance_method_with_args() {
let obj = PyCell::new(py, InstanceMethodWithArgs { member: 7 }).unwrap(); let obj = PyCell::new(py, InstanceMethodWithArgs { member: 7 }).unwrap();
let obj_ref = obj.borrow(); let obj_ref = obj.borrow();
assert_eq!(obj_ref.method(6).unwrap(), 42); assert_eq!(obj_ref.method(6), 42);
let d = [("obj", obj)].into_py_dict(py); let d = [("obj", obj)].into_py_dict(py);
py.run("assert obj.method(3) == 21", None, Some(d)).unwrap(); py.run("assert obj.method(3) == 21", None, Some(d)).unwrap();
py.run("assert obj.method(multiplier=6) == 42", None, Some(d)) py.run("assert obj.method(multiplier=6) == 42", None, Some(d))
@ -134,8 +134,8 @@ impl StaticMethod {
#[staticmethod] #[staticmethod]
/// Test static method. /// Test static method.
fn method(_py: Python) -> PyResult<&'static str> { fn method(_py: Python) -> &'static str {
Ok("StaticMethod.method()!") "StaticMethod.method()!"
} }
} }
@ -144,7 +144,7 @@ fn static_method() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
assert_eq!(StaticMethod::method(py).unwrap(), "StaticMethod.method()!"); assert_eq!(StaticMethod::method(py), "StaticMethod.method()!");
let d = [("C", py.get_type::<StaticMethod>())].into_py_dict(py); let d = [("C", py.get_type::<StaticMethod>())].into_py_dict(py);
let run = |code| { let run = |code| {
@ -164,8 +164,8 @@ struct StaticMethodWithArgs {}
#[pymethods] #[pymethods]
impl StaticMethodWithArgs { impl StaticMethodWithArgs {
#[staticmethod] #[staticmethod]
fn method(_py: Python, input: i32) -> PyResult<String> { fn method(_py: Python, input: i32) -> String {
Ok(format!("0x{:x}", input)) format!("0x{:x}", input)
} }
} }
@ -174,7 +174,7 @@ fn static_method_with_args() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
assert_eq!(StaticMethodWithArgs::method(py, 1234).unwrap(), "0x4d2"); assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2");
let d = [("C", py.get_type::<StaticMethodWithArgs>())].into_py_dict(py); let d = [("C", py.get_type::<StaticMethodWithArgs>())].into_py_dict(py);
py.run("assert C.method(1337) == '0x539'", None, Some(d)) py.run("assert C.method(1337) == '0x539'", None, Some(d))
@ -187,41 +187,36 @@ struct MethArgs {}
#[pymethods] #[pymethods]
impl MethArgs { impl MethArgs {
#[args(test)] #[args(test)]
fn get_optional(&self, test: Option<i32>) -> PyResult<i32> { fn get_optional(&self, test: Option<i32>) -> i32 {
Ok(test.unwrap_or(10)) test.unwrap_or(10)
} }
fn get_optional2(&self, test: Option<i32>) -> PyResult<Option<i32>> { fn get_optional2(&self, test: Option<i32>) -> Option<i32> {
Ok(test) test
} }
#[args(test = "None")] #[args(test = "None")]
fn get_optional3(&self, test: Option<i32>) -> PyResult<Option<i32>> { fn get_optional3(&self, test: Option<i32>) -> Option<i32> {
Ok(test) test
} }
fn get_optional_positional( fn get_optional_positional(
&self, &self,
_t1: Option<i32>, _t1: Option<i32>,
t2: Option<i32>, t2: Option<i32>,
_t3: Option<i32>, _t3: Option<i32>,
) -> PyResult<Option<i32>> { ) -> Option<i32> {
Ok(t2) t2
} }
#[args(test = "10")] #[args(test = "10")]
fn get_default(&self, test: i32) -> PyResult<i32> { fn get_default(&self, test: i32) -> i32 {
Ok(test) test
} }
#[args("*", test = 10)] #[args("*", test = 10)]
fn get_kwarg(&self, test: i32) -> PyResult<i32> { fn get_kwarg(&self, test: i32) -> i32 {
Ok(test) test
} }
#[args(args = "*", kwargs = "**")] #[args(args = "*", kwargs = "**")]
fn get_kwargs( fn get_kwargs(&self, py: Python, args: &PyTuple, kwargs: Option<&PyDict>) -> PyObject {
&self, [args.into(), kwargs.to_object(py)].to_object(py)
py: Python,
args: &PyTuple,
kwargs: Option<&PyDict>,
) -> PyResult<PyObject> {
Ok([args.into(), kwargs.to_object(py)].to_object(py))
} }
#[args(args = "*", kwargs = "**")] #[args(args = "*", kwargs = "**")]
@ -236,28 +231,28 @@ impl MethArgs {
} }
#[args("*", a = 2, b = 3)] #[args("*", a = 2, b = 3)]
fn get_kwargs_only_with_defaults(&self, a: i32, b: i32) -> PyResult<i32> { fn get_kwargs_only_with_defaults(&self, a: i32, b: i32) -> i32 {
Ok(a + b) a + b
} }
#[args("*", a, b)] #[args("*", a, b)]
fn get_kwargs_only(&self, a: i32, b: i32) -> PyResult<i32> { fn get_kwargs_only(&self, a: i32, b: i32) -> i32 {
Ok(a + b) a + b
} }
#[args("*", a = 1, b)] #[args("*", a = 1, b)]
fn get_kwargs_only_with_some_default(&self, a: i32, b: i32) -> PyResult<i32> { fn get_kwargs_only_with_some_default(&self, a: i32, b: i32) -> i32 {
Ok(a + b) a + b
} }
#[args(a, b = 2, "*", c = 3)] #[args(a, b = 2, "*", c = 3)]
fn get_pos_arg_kw_sep1(&self, a: i32, b: i32, c: i32) -> PyResult<i32> { fn get_pos_arg_kw_sep1(&self, a: i32, b: i32, c: i32) -> i32 {
Ok(a + b + c) a + b + c
} }
#[args(a, "*", b = 2, c = 3)] #[args(a, "*", b = 2, c = 3)]
fn get_pos_arg_kw_sep2(&self, a: i32, b: i32, c: i32) -> PyResult<i32> { fn get_pos_arg_kw_sep2(&self, a: i32, b: i32, c: i32) -> i32 {
Ok(a + b + c) a + b + c
} }
#[args(kwargs = "**")] #[args(kwargs = "**")]
@ -417,14 +412,14 @@ struct MethDocs {
#[pymethods] #[pymethods]
impl MethDocs { impl MethDocs {
/// A method with "documentation" as well. /// A method with "documentation" as well.
fn method(&self) -> PyResult<i32> { fn method(&self) -> i32 {
Ok(0) 0
} }
#[getter] #[getter]
/// `int`: a very "important" member of 'this' instance. /// `int`: a very "important" member of 'this' instance.
fn get_x(&self) -> PyResult<i32> { fn get_x(&self) -> i32 {
Ok(self.x) self.x
} }
} }

View File

@ -39,14 +39,13 @@ fn module_with_functions(_py: Python, m: &PyModule) -> PyResult<()> {
use pyo3::wrap_pyfunction; use pyo3::wrap_pyfunction;
#[pyfn(m, "sum_as_string")] #[pyfn(m, "sum_as_string")]
fn sum_as_string_py(_py: Python, a: i64, b: i64) -> PyResult<String> { fn sum_as_string_py(_py: Python, a: i64, b: i64) -> String {
let out = sum_as_string(a, b); sum_as_string(a, b)
Ok(out)
} }
#[pyfn(m, "no_parameters")] #[pyfn(m, "no_parameters")]
fn no_parameters() -> PyResult<usize> { fn no_parameters() -> usize {
Ok(42) 42
} }
#[pyfn(m, "with_module", pass_module)] #[pyfn(m, "with_module", pass_module)]
@ -106,7 +105,8 @@ fn test_module_with_functions() {
} }
#[pymodule(other_name)] #[pymodule(other_name)]
fn some_name(_: Python, _: &PyModule) -> PyResult<()> { fn some_name(_: Python, m: &PyModule) -> PyResult<()> {
m.add("other_name", "other_name")?;
Ok(()) Ok(())
} }

View File

@ -22,12 +22,12 @@ impl Reader {
fn clone_ref_with_py<'py>(slf: &'py PyCell<Self>, _py: Python<'py>) -> &'py PyCell<Self> { fn clone_ref_with_py<'py>(slf: &'py PyCell<Self>, _py: Python<'py>) -> &'py PyCell<Self> {
slf slf
} }
fn get_iter(slf: &PyCell<Self>, keys: Py<PyBytes>) -> PyResult<Iter> { fn get_iter(slf: &PyCell<Self>, keys: Py<PyBytes>) -> Iter {
Ok(Iter { Iter {
reader: slf.into(), reader: slf.into(),
keys, keys,
idx: 0, idx: 0,
}) }
} }
fn get_iter_and_reset( fn get_iter_and_reset(
mut slf: PyRefMut<Self>, mut slf: PyRefMut<Self>,

View File

@ -4,9 +4,7 @@ use pyo3::wrap_pyfunction;
mod common; mod common;
#[pyfunction] #[pyfunction]
fn take_str(_s: &str) -> PyResult<()> { fn take_str(_s: &str) {}
Ok(())
}
#[test] #[test]
fn test_unicode_encode_error() { fn test_unicode_encode_error() {

View File

@ -10,14 +10,14 @@ struct MyClass {}
impl MyClass { impl MyClass {
#[staticmethod] #[staticmethod]
#[args(args = "*")] #[args(args = "*")]
fn test_args(args: &PyTuple) -> PyResult<&PyTuple> { fn test_args(args: &PyTuple) -> &PyTuple {
Ok(args) args
} }
#[staticmethod] #[staticmethod]
#[args(kwargs = "**")] #[args(kwargs = "**")]
fn test_kwargs(kwargs: Option<&PyDict>) -> PyResult<Option<&PyDict>> { fn test_kwargs(kwargs: Option<&PyDict>) -> Option<&PyDict> {
Ok(kwargs) kwargs
} }
} }

View File

@ -14,12 +14,11 @@ struct MutRefArg {
#[pymethods] #[pymethods]
impl MutRefArg { impl MutRefArg {
fn get(&self) -> PyResult<i32> { fn get(&self) -> i32 {
Ok(self.n) self.n
} }
fn set_other(&self, mut other: PyRefMut<MutRefArg>) -> PyResult<()> { fn set_other(&self, mut other: PyRefMut<MutRefArg>) {
other.n = 100; other.n = 100;
Ok(())
} }
} }
@ -44,8 +43,8 @@ struct PyUsize {
} }
#[pyfunction] #[pyfunction]
fn get_zero() -> PyResult<PyUsize> { fn get_zero() -> PyUsize {
Ok(PyUsize { value: 0 }) PyUsize { value: 0 }
} }
#[test] #[test]
@ -56,7 +55,7 @@ fn return_custom_class() {
let py = gil.python(); let py = gil.python();
// Using from rust // Using from rust
assert_eq!(get_zero().unwrap().value, 0); assert_eq!(get_zero().value, 0);
// Using from python // Using from python
let get_zero = wrap_pyfunction!(get_zero)(py).unwrap(); let get_zero = wrap_pyfunction!(get_zero)(py).unwrap();