Some api improvements
This commit is contained in:
parent
0cd72ac213
commit
ad590bd158
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -20,3 +20,4 @@ examples/*/py*
|
|||
*.egg-info
|
||||
extensions/stamps/
|
||||
pip-wheel-metadata
|
||||
valgrind-python.supp
|
||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
* Added a `wrap_pymodule!` macro similar to the existing `wrap_pyfunction!` macro. Only available on python 3
|
||||
* Added support for cross compiling (e.g. to arm v7) by mtp401 in [#327](https://github.com/PyO3/pyo3/pull/327). See the "Cross Compiling" section in the "Building and Distribution" chapter of the guide for more details.
|
||||
* The `PyRef` and `PyRefMut` types, which allow to differentiate between an instance of a rust struct on the rust heap and an instance that is embedded inside a python object. By kngwyu in [#335](https://github.com/PyO3/pyo3/pull/335)
|
||||
* Added `FromPy<T>` and `IntoPy<T>` which are equivalent to `From<T>` and `Into<T>` except that they require a gil token.
|
||||
* Added `ManagedPyRef`, which should eventually replace `ToBorrowedObject`.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -27,14 +29,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
* `#[pyfunction]` now supports the same arguments as `#[pyfn()]`
|
||||
* Some macros now emit proper spanned errors instead of panics.
|
||||
* Migrated to the 2018 edition
|
||||
* Replace `IntoPyTuple` with `IntoPy<Py<PyTuple>>`. Eventually `IntoPy<T>` should replace `ToPyObject` and be itself implemented through `FromPy<T>`
|
||||
* `crate::types::exceptions` moved to `crate::exceptions`
|
||||
* Replace `IntoPyTuple` with `IntoPy<Py<PyTuple>>`.
|
||||
* `IntoPyPointer` and `ToPyPointer` moved into the crate root.
|
||||
* `class::CompareOp` moved into `class::basic::CompareOp`
|
||||
* PyTypeObject is now a direct subtrait PyTypeCreate, removing the old cyclical implementation in [#350](https://github.com/PyO3/pyo3/pull/350)
|
||||
* Add `PyList::{sort, reverse}` by chr1sj0nes in [#357](https://github.com/PyO3/pyo3/pull/357) and [#358](https://github.com/PyO3/pyo3/pull/358)
|
||||
* Renamed the `typeob` module to `type_object`
|
||||
|
||||
### Removed
|
||||
|
||||
* `PyToken` was removed due to unsoundness (See [#94](https://github.com/PyO3/pyo3/issues/94)).
|
||||
* Removed the unnecessary type parameter from `PyObjectAlloc`
|
||||
* `NoArgs`. Just use an empty tuple
|
||||
* `PyObjectWithGIL`. `PyNativeType` is sufficient now that PyToken is removed.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ provides two methods:
|
|||
* `call` - call callable python object.
|
||||
* `call_method` - call specific method on the object.
|
||||
|
||||
Both methods accept `args` and `kwargs` arguments. The `NoArgs` object represents an empty tuple object.
|
||||
Both methods accept `args` and `kwargs` arguments.
|
||||
|
||||
```rust
|
||||
use pyo3::prelude::*;
|
||||
|
@ -87,16 +87,16 @@ fn main() {
|
|||
// call object with PyDict
|
||||
let kwargs = PyDict::new(py);
|
||||
kwargs.set_item(key1, val1);
|
||||
obj.call(py, NoArgs, Some(kwargs));
|
||||
obj.call(py, (), Some(kwargs));
|
||||
|
||||
// pass arguments as Vec
|
||||
let kwargs = vec![(key1, val1), (key2, val2)];
|
||||
obj.call(py, NoArgs, Some(kwargs.into_py_dict(py)));
|
||||
obj.call(py, (), Some(kwargs.into_py_dict(py)));
|
||||
|
||||
// pass arguments as HashMap
|
||||
let mut kwargs = HashMap::<&str, i32>::new();
|
||||
kwargs.insert(key1, 1);
|
||||
obj.call(py, NoArgs, Some(kwargs.into_py_dict(py)));
|
||||
obj.call(py, (), Some(kwargs.into_py_dict(py)));
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -18,3 +18,14 @@ cargo rustc --profile=check -- -Z unstable-options --pretty=expanded -Z trace-ma
|
|||
|
||||
See [cargo expand](https://github.com/dtolnay/cargo-expand) for a more elaborate version of those commands.
|
||||
|
||||
## Running with Valgrind
|
||||
|
||||
Valgrind is a tool to detect memory managment bugs such as memory leaks.
|
||||
|
||||
You first need to installa debug build of python, otherwise valgrind won't produce usable results. In ubuntu there's e.g. a `python3-dbg` package.
|
||||
|
||||
Activate an environment with the debug interpreter and recompile. If you're on linux, use `ldd` with the name of you're binary and check that you're linking e.g. `libpython3.6dm.so.1.0` instead of `libpython3.6m.so.1.0`.
|
||||
|
||||
[Download the suppressions file for cpython](https://raw.githubusercontent.com/python/cpython/master/Misc/valgrind-python.supp).
|
||||
|
||||
Run valgrind with `valgrind --suppressions=valgrind-python.supp ./my-command --with-options`
|
||||
|
|
|
@ -101,7 +101,7 @@ To check the type of an exception, you can simply do:
|
|||
# fn main() {
|
||||
# let gil = Python::acquire_gil();
|
||||
# let py = gil.python();
|
||||
# let err = exceptions::TypeError::py_err(NoArgs);
|
||||
# let err = exceptions::TypeError::py_err(());
|
||||
err.is_instance::<exceptions::TypeError>(py);
|
||||
# }
|
||||
```
|
||||
|
@ -112,7 +112,7 @@ The vast majority of operations in this library will return [`PyResult<T>`](http
|
|||
This is an alias for the type `Result<T, PyErr>`.
|
||||
|
||||
A [`PyErr`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html) represents a Python exception.
|
||||
Errors within the `PyO3` library are also exposed as Python exceptions.
|
||||
Errors within the `Pyo3` library are also exposed as Python exceptions.
|
||||
|
||||
PyO3 library handles python exception in two stages. During first stage `PyErr` instance get
|
||||
created. At this stage python GIL is not required. During second stage, actual python
|
||||
|
|
|
@ -84,7 +84,7 @@ Currently, there are no conversions between `Fn`s in rust and callables in pytho
|
|||
|
||||
### Calling a python function in rust
|
||||
|
||||
You can use `ObjectProtocol::is_callable` to check if you got a callable, which is true for functions (including lambdas), methods and objects with a `__call__` method. You can call the object with `ObjectProtocol::call` with the args as first parameter and the kwargs (or `NoArgs`) as second parameter. There are also `ObjectProtocol::call0` with no args and `ObjectProtocol::call1` with only the args.
|
||||
You can use `ObjectProtocol::is_callable` to check if you got a callable, which is true for functions (including lambdas), methods and objects with a `__call__` method. You can call the object with `ObjectProtocol::call` with the args as first parameter and the kwargs (or `None`) as second parameter. There are also `ObjectProtocol::call0` with no args and `ObjectProtocol::call1` with only the args.
|
||||
|
||||
### Calling rust `Fn`s in python
|
||||
|
||||
|
|
|
@ -110,16 +110,16 @@ impl PyClassArgs {
|
|||
let flag = exp.path.segments.first().unwrap().value().ident.to_string();
|
||||
let path = match flag.as_str() {
|
||||
"gc" => {
|
||||
parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_GC}
|
||||
parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_GC}
|
||||
}
|
||||
"weakref" => {
|
||||
parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_WEAKREF}
|
||||
parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_WEAKREF}
|
||||
}
|
||||
"subclass" => {
|
||||
parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_BASETYPE}
|
||||
parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_BASETYPE}
|
||||
}
|
||||
"dict" => {
|
||||
parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_DICT}
|
||||
parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_DICT}
|
||||
}
|
||||
_ => {
|
||||
return Err(syn::Error::new_spanned(
|
||||
|
@ -250,7 +250,7 @@ fn impl_class(
|
|||
FREELIST = Box::into_raw(Box::new(
|
||||
::pyo3::freelist::FreeList::with_capacity(#freelist)));
|
||||
|
||||
<#cls as ::pyo3::typeob::PyTypeObject>::init_type();
|
||||
<#cls as ::pyo3::type_object::PyTypeObject>::init_type();
|
||||
}
|
||||
&mut *FREELIST
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ fn impl_class(
|
|||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl ::pyo3::typeob::PyObjectAlloc for #cls {}
|
||||
impl ::pyo3::type_object::PyObjectAlloc for #cls {}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -280,9 +280,9 @@ fn impl_class(
|
|||
let mut has_dict = false;
|
||||
for f in attr.flags.iter() {
|
||||
if let syn::Expr::Path(ref epath) = f {
|
||||
if epath.path == parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_WEAKREF} {
|
||||
if epath.path == parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_WEAKREF} {
|
||||
has_weakref = true;
|
||||
} else if epath.path == parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_DICT} {
|
||||
} else if epath.path == parse_quote! {::pyo3::type_object::PY_TYPE_FLAG_DICT} {
|
||||
has_dict = true;
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ fn impl_class(
|
|||
let flags = &attr.flags;
|
||||
|
||||
quote! {
|
||||
impl ::pyo3::typeob::PyTypeInfo for #cls {
|
||||
impl ::pyo3::type_object::PyTypeInfo for #cls {
|
||||
type Type = #cls;
|
||||
type BaseType = #base;
|
||||
|
||||
|
@ -319,7 +319,7 @@ fn impl_class(
|
|||
const OFFSET: isize = {
|
||||
// round base_size up to next multiple of align
|
||||
(
|
||||
(<#base as ::pyo3::typeob::PyTypeInfo>::SIZE +
|
||||
(<#base as ::pyo3::type_object::PyTypeInfo>::SIZE +
|
||||
::std::mem::align_of::<#cls>() - 1) /
|
||||
::std::mem::align_of::<#cls>() * ::std::mem::align_of::<#cls>()
|
||||
) as isize
|
||||
|
|
|
@ -62,7 +62,7 @@ pub fn impl_wrap(
|
|||
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
||||
|
||||
let _result = {
|
||||
::pyo3::IntoPyResult::into_py_result(#body)
|
||||
::pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
||||
};
|
||||
|
||||
::pyo3::callback::cb_convert(
|
||||
|
@ -136,12 +136,12 @@ pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> T
|
|||
_args: *mut ::pyo3::ffi::PyObject,
|
||||
_kwargs: *mut ::pyo3::ffi::PyObject) -> *mut ::pyo3::ffi::PyObject
|
||||
{
|
||||
use ::pyo3::typeob::PyTypeInfo;
|
||||
use ::pyo3::type_object::PyTypeInfo;
|
||||
|
||||
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
||||
let _pool = ::pyo3::GILPool::new();
|
||||
let _py = ::pyo3::Python::assume_gil_acquired();
|
||||
match ::pyo3::typeob::PyRawObject::new(_py, #cls::type_object(), _cls) {
|
||||
match ::pyo3::type_object::PyRawObject::new(_py, #cls::type_object(), _cls) {
|
||||
Ok(_obj) => {
|
||||
let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
|
||||
let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
||||
|
@ -355,7 +355,7 @@ pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream {
|
|||
if spec.args.is_empty() {
|
||||
return quote! {
|
||||
let _result = {
|
||||
::pyo3::IntoPyResult::into_py_result(#body)
|
||||
::pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream {
|
|||
|
||||
#(#param_conversion)*
|
||||
|
||||
::pyo3::IntoPyResult::into_py_result(#body)
|
||||
::pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use syn;
|
||||
|
||||
pub fn print_err(msg: String, t: TokenStream) {
|
||||
println!("Error: {} in '{}'", msg, t.to_string());
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
use crate::err::{self, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use libc;
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw;
|
||||
|
@ -661,7 +662,7 @@ impl_element!(f64, Float);
|
|||
mod test {
|
||||
use super::PyBuffer;
|
||||
use crate::ffi;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
//! Utilities for a Python callable object that invokes a Rust function.
|
||||
|
||||
use crate::conversion::IntoPyObject;
|
||||
use crate::err::PyResult;
|
||||
use crate::exceptions::OverflowError;
|
||||
use crate::ffi::{self, Py_hash_t};
|
||||
use crate::python::{IntoPyPointer, Python};
|
||||
use crate::types::exceptions::OverflowError;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, IntoPyPointer};
|
||||
use std::os::raw::c_int;
|
||||
use std::{isize, ptr};
|
||||
|
||||
|
|
|
@ -10,17 +10,29 @@
|
|||
|
||||
use crate::callback::{BoolCallbackConverter, HashConverter, PyObjectCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::conversion::{FromPyObject, IntoPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::{IntoPyPointer, Python};
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::types::{exceptions, PyObjectRef};
|
||||
use crate::CompareOp;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use std::os::raw::c_int;
|
||||
use std::ptr;
|
||||
|
||||
/// Operators for the __richcmp__ method
|
||||
#[derive(Debug)]
|
||||
pub enum CompareOp {
|
||||
Lt = ffi::Py_LT as isize,
|
||||
Le = ffi::Py_LE as isize,
|
||||
Eq = ffi::Py_EQ as isize,
|
||||
Ne = ffi::Py_NE as isize,
|
||||
Gt = ffi::Py_GT as isize,
|
||||
Ge = ffi::Py_GE as isize,
|
||||
}
|
||||
|
||||
/// Basic python class customization
|
||||
#[allow(unused_variables)]
|
||||
pub trait PyObjectProtocol<'p>: PyTypeInfo {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use crate::callback::UnitCallbackConverter;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Buffer protocol interface
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
|
||||
/// Context manager interface
|
||||
#[allow(unused_variables)]
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
use crate::callback::{PyObjectCallbackConverter, UnitCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::conversion::{FromPyObject, IntoPyObject};
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::{PyObjectRef, PyType};
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Descriptor interface
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
//!
|
||||
|
||||
use crate::ffi;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
||||
#[repr(transparent)]
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
//! Trait and support implementation for implementing iterators
|
||||
|
||||
use crate::callback::{CallbackConverter, PyObjectCallbackConverter};
|
||||
use crate::conversion::IntoPyObject;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyRefMut;
|
||||
use crate::python::{IntoPyPointer, Python};
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::IntoPyObject;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use std::ptr;
|
||||
|
||||
/// Python Iterator Interface.
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
use crate::callback::{LenResultConverter, PyObjectCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::conversion::{FromPyObject, IntoPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::python::Python;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::types::exceptions;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
|
||||
/// Mapping interface
|
||||
#[allow(unused_variables)]
|
||||
|
|
|
@ -21,23 +21,10 @@ pub use self::basic::PyObjectProtocol;
|
|||
pub use self::buffer::PyBufferProtocol;
|
||||
pub use self::context::PyContextProtocol;
|
||||
pub use self::descr::PyDescrProtocol;
|
||||
pub use self::gc::{PyGCProtocol, PyTraverseError, PyVisit};
|
||||
pub use self::iter::PyIterProtocol;
|
||||
pub use self::mapping::PyMappingProtocol;
|
||||
pub use self::methods::{PyGetterDef, PyMethodDef, PyMethodDefType, PyMethodType, PySetterDef};
|
||||
pub use self::number::PyNumberProtocol;
|
||||
pub use self::pyasync::PyAsyncProtocol;
|
||||
pub use self::sequence::PySequenceProtocol;
|
||||
|
||||
pub use self::gc::{PyGCProtocol, PyTraverseError, PyVisit};
|
||||
pub use self::methods::{PyGetterDef, PyMethodDef, PyMethodDefType, PyMethodType, PySetterDef};
|
||||
use crate::ffi;
|
||||
|
||||
/// Operators for the __richcmp__ method
|
||||
#[derive(Debug)]
|
||||
pub enum CompareOp {
|
||||
Lt = ffi::Py_LT as isize,
|
||||
Le = ffi::Py_LE as isize,
|
||||
Eq = ffi::Py_EQ as isize,
|
||||
Ne = ffi::Py_NE as isize,
|
||||
Gt = ffi::Py_GT as isize,
|
||||
Ge = ffi::Py_GE as isize,
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::class::basic::PyObjectProtocolImpl;
|
|||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
|
||||
/// Number interface
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::callback::PyObjectCallbackConverter;
|
|||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
|
||||
/// Python Async/Await support interface.
|
||||
///
|
||||
|
@ -190,9 +190,10 @@ impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
|
|||
mod anext {
|
||||
use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
|
||||
use crate::callback::CallbackConverter;
|
||||
use crate::conversion::IntoPyObject;
|
||||
use crate::ffi;
|
||||
use crate::python::{IntoPyPointer, Python};
|
||||
use crate::IntoPyObject;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use std::ptr;
|
||||
|
||||
pub struct IterANextResultConverter;
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
//! Trait and support implementation for implementing sequence
|
||||
|
||||
use crate::callback::{BoolCallbackConverter, LenResultConverter, PyObjectCallbackConverter};
|
||||
use crate::conversion::{FromPyObject, IntoPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::types::{exceptions, PyObjectRef};
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Sequece interface
|
||||
|
|
|
@ -1,13 +1,73 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! This module contains some conversion traits
|
||||
//! Conversions between various states of rust and python types and their wrappers.
|
||||
|
||||
use crate::err::{PyDowncastError, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::types::PyTuple;
|
||||
use crate::Py;
|
||||
use crate::Python;
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
///
|
||||
/// This trait is implemented for types that internally wrap a pointer to a python object.
|
||||
pub trait ToPyPointer {
|
||||
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject;
|
||||
}
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
pub trait IntoPyPointer {
|
||||
/// Retrieves the underlying FFI pointer. Whether pointer owned or borrowed
|
||||
/// depends on implementation.
|
||||
fn into_ptr(self) -> *mut ffi::PyObject;
|
||||
}
|
||||
|
||||
/// Convert `None` into a null pointer.
|
||||
impl<T> ToPyPointer for Option<T>
|
||||
where
|
||||
T: ToPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref t) => t.as_ptr(),
|
||||
None => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `None` into a null pointer.
|
||||
impl<T> IntoPyPointer for Option<T>
|
||||
where
|
||||
T: IntoPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn into_ptr(self) -> *mut ffi::PyObject {
|
||||
match self {
|
||||
Some(t) => t.into_ptr(),
|
||||
None => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoPyPointer for &'a T
|
||||
where
|
||||
T: ToPyPointer,
|
||||
{
|
||||
fn into_ptr(self) -> *mut ffi::PyObject {
|
||||
let ptr = self.as_ptr();
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
ffi::Py_INCREF(ptr);
|
||||
}
|
||||
}
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
/// Conversion trait that allows various objects to be converted into `PyObject`
|
||||
pub trait ToPyObject {
|
||||
|
@ -18,7 +78,9 @@ pub trait ToPyObject {
|
|||
/// This trait has two implementations: The slow one is implemented for
|
||||
/// all [ToPyObject] and creates a new object using [ToPyObject::to_object],
|
||||
/// while the fast one is only implemented for ToPyPointer (we know
|
||||
/// that every ToPyObject is also ToPyObject) and uses [ToPyPointer::as_ptr()]
|
||||
/// that every ToPyPointer is also ToPyObject) and uses [ToPyPointer::as_ptr()]
|
||||
///
|
||||
/// This trait should eventually be replaced with [ManagedPyRef](crate::ManagedPyRef).
|
||||
pub trait ToBorrowedObject: ToPyObject {
|
||||
/// Converts self into a Python object and calls the specified closure
|
||||
/// on the native FFI pointer underlying the Python object.
|
||||
|
@ -52,12 +114,35 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Similar to [std::convert::Into], just that it requires a gil token and there's
|
||||
/// currently no corresponding [std::convert::From] part.
|
||||
/// Similar to [std::convert::From], just that it requires a gil token.
|
||||
pub trait FromPy<T>: Sized {
|
||||
/// Performs the conversion.
|
||||
fn from_py(_: T, py: Python) -> Self;
|
||||
}
|
||||
|
||||
/// Similar to [std::convert::Into], just that it requires a gil token.
|
||||
pub trait IntoPy<T>: Sized {
|
||||
/// Performs the conversion.
|
||||
fn into_py(self, py: Python) -> T;
|
||||
}
|
||||
|
||||
// From implies Into
|
||||
impl<T, U> IntoPy<U> for T
|
||||
where
|
||||
U: FromPy<T>,
|
||||
{
|
||||
fn into_py(self, py: Python) -> U {
|
||||
U::from_py(self, py)
|
||||
}
|
||||
}
|
||||
|
||||
// From (and thus Into) is reflexive
|
||||
impl<T> FromPy<T> for T {
|
||||
fn from_py(t: T, _: Python) -> T {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
/// Conversion trait that allows various objects to be converted into `PyObject`
|
||||
/// by consuming original object.
|
||||
pub trait IntoPyObject {
|
||||
|
@ -202,20 +287,17 @@ where
|
|||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
/// This trait is similar to `std::convert::TryInto`
|
||||
pub trait PyTryInto<T>: Sized {
|
||||
/// The type returned in the event of a conversion error.
|
||||
type Error;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn try_into(&self) -> Result<&T, Self::Error>;
|
||||
fn try_into(&self) -> Result<&T, PyDowncastError>;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type. With exact type check.
|
||||
fn try_into_exact(&self) -> Result<&T, Self::Error>;
|
||||
fn try_into_exact(&self) -> Result<&T, PyDowncastError>;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn try_into_mut(&self) -> Result<&mut T, Self::Error>;
|
||||
fn try_into_mut(&self) -> Result<&mut T, PyDowncastError>;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type. With exact type check.
|
||||
fn try_into_mut_exact(&self) -> Result<&mut T, Self::Error>;
|
||||
fn try_into_mut_exact(&self) -> Result<&mut T, PyDowncastError>;
|
||||
}
|
||||
|
||||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
|
@ -250,8 +332,6 @@ impl<U> PyTryInto<U> for PyObjectRef
|
|||
where
|
||||
U: for<'v> PyTryFrom<'v>,
|
||||
{
|
||||
type Error = PyDowncastError;
|
||||
|
||||
fn try_into(&self) -> Result<&U, PyDowncastError> {
|
||||
U::try_from(self)
|
||||
}
|
||||
|
@ -339,34 +419,20 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// This trait wraps a T: IntoPyObject into PyResult<T> while PyResult<T> remains PyResult<T>.
|
||||
///
|
||||
/// This is necessary because proc macros run before typechecking and can't decide
|
||||
/// whether a return type is a (possibly aliased) PyResult or not. It is also quite handy because
|
||||
/// the codegen is currently built on the assumption that all functions return a PyResult.
|
||||
pub trait IntoPyResult<T> {
|
||||
fn into_py_result(self) -> PyResult<T>;
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for T {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for PyResult<T> {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
self
|
||||
/// Converts `()` to an empty Python tuple.
|
||||
impl FromPy<()> for Py<PyTuple> {
|
||||
fn from_py(_: (), py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyTryFrom;
|
||||
use crate::types::PyList;
|
||||
use crate::Python;
|
||||
|
||||
use super::PyTryFrom;
|
||||
|
||||
#[test]
|
||||
fn test_try_from_unchecked() {
|
||||
let gil = Python::acquire_gil();
|
||||
|
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
//! Functionality for the code generated by the derive backend
|
||||
|
||||
use crate::conversion::PyTryFrom;
|
||||
use crate::err::PyResult;
|
||||
use crate::exceptions::TypeError;
|
||||
use crate::ffi;
|
||||
use crate::init_once;
|
||||
use crate::types::PyModule;
|
||||
use crate::types::{PyDict, PyObjectRef, PyString, PyTuple};
|
||||
use crate::types::{PyDict, PyModule, PyObjectRef, PyString, PyTuple};
|
||||
use crate::GILPool;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom};
|
||||
use std::ptr;
|
||||
|
||||
/// Description of a python parameter; used for `parse_args()`.
|
||||
|
@ -111,14 +110,13 @@ pub fn parse_fn_args<'p>(
|
|||
}
|
||||
|
||||
#[cfg(Py_3)]
|
||||
#[doc(hidden)]
|
||||
/// Builds a module (or null) from a user given initializer. Used for `#[pymodule]`.
|
||||
pub unsafe fn make_module(
|
||||
name: &str,
|
||||
doc: &str,
|
||||
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
|
||||
) -> *mut ffi::PyObject {
|
||||
use crate::python::IntoPyPointer;
|
||||
use crate::IntoPyPointer;
|
||||
|
||||
init_once();
|
||||
|
||||
|
@ -196,3 +194,24 @@ pub unsafe fn make_module(
|
|||
e.restore(py)
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait wraps a T: IntoPyObject into PyResult<T> while PyResult<T> remains PyResult<T>.
|
||||
///
|
||||
/// This is necessary because proc macros run before typechecking and can't decide
|
||||
/// whether a return type is a (possibly aliased) PyResult or not. It is also quite handy because
|
||||
/// the codegen is currently built on the assumption that all functions return a PyResult.
|
||||
pub trait IntoPyResult<T> {
|
||||
fn into_py_result(self) -> PyResult<T>;
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for T {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for PyResult<T> {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
14
src/err.rs
14
src/err.rs
|
@ -1,12 +1,15 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::Py;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeObject;
|
||||
use crate::types::{exceptions, PyObjectRef, PyType};
|
||||
use crate::type_object::PyTypeObject;
|
||||
use crate::types::{PyObjectRef, PyType};
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use libc::c_int;
|
||||
use std::error::Error;
|
||||
use std::ffi::CString;
|
||||
|
@ -54,7 +57,6 @@ impl PyErr {
|
|||
/// Creates a new PyErr of type `T`.
|
||||
///
|
||||
/// `value` can be:
|
||||
/// * `NoArgs`: the exception instance will be created using python `T()`
|
||||
/// * a tuple: the exception instance will be created using python `T(*tuple)`
|
||||
/// * any other value: the exception instance will be created using python `T(value)`
|
||||
///
|
||||
|
@ -521,7 +523,7 @@ pub fn error_on_minusone(py: Python, result: c_int) -> PyResult<()> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::types::exceptions;
|
||||
use crate::exceptions;
|
||||
use crate::{PyErr, Python};
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! This module contains the standard python exception types.
|
||||
//! Exception types defined by python.
|
||||
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeObject;
|
||||
use crate::type_object::PyTypeObject;
|
||||
use crate::types::{PyObjectRef, PyTuple};
|
||||
use crate::Python;
|
||||
use crate::{ToPyObject, ToPyPointer};
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
use std::{self, ops};
|
||||
|
@ -84,12 +84,12 @@ macro_rules! import_exception {
|
|||
};
|
||||
}
|
||||
|
||||
/// `impl $crate::typeob::PyTypeObject for $name` where `$name` is an exception defined in python
|
||||
/// `impl $crate::type_object::PyTypeObject for $name` where `$name` is an exception defined in python
|
||||
/// code.
|
||||
#[macro_export]
|
||||
macro_rules! import_exception_type_object {
|
||||
($module: expr, $name: ident) => {
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
impl $crate::type_object::PyTypeObject for $name {
|
||||
fn init_type() -> std::ptr::NonNull<$crate::ffi::PyTypeObject> {
|
||||
// We can't use lazy_static here because raw pointers aren't Send
|
||||
static TYPE_OBJECT_ONCE: ::std::sync::Once = ::std::sync::Once::new();
|
||||
|
@ -170,12 +170,12 @@ macro_rules! create_exception {
|
|||
};
|
||||
}
|
||||
|
||||
/// `impl $crate::typeob::PyTypeObject for $name` where `$name` is an exception newly defined in
|
||||
/// `impl $crate::type_object::PyTypeObject for $name` where `$name` is an exception newly defined in
|
||||
/// rust code.
|
||||
#[macro_export]
|
||||
macro_rules! create_exception_type_object {
|
||||
($module: ident, $name: ident, $base: ty) => {
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
impl $crate::type_object::PyTypeObject for $name {
|
||||
fn init_type() -> std::ptr::NonNull<$crate::ffi::PyTypeObject> {
|
||||
// We can't use lazy_static here because raw pointers aren't Send
|
||||
static TYPE_OBJECT_ONCE: ::std::sync::Once = ::std::sync::Once::new();
|
||||
|
@ -379,8 +379,8 @@ pub mod socket {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::exceptions::Exception;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::types::exceptions::Exception;
|
||||
use crate::types::PyDict;
|
||||
use crate::{PyErr, Python};
|
||||
|
|
@ -3,68 +3,59 @@
|
|||
#![cfg_attr(Py_LIMITED_API, allow(unused_imports))]
|
||||
#![cfg_attr(feature="cargo-clippy", allow(clippy::inline_always))]
|
||||
|
||||
pub use self::pymem::*;
|
||||
pub use self::pyport::*;
|
||||
|
||||
pub use self::object::*;
|
||||
pub use self::objimpl::*;
|
||||
pub use self::pyhash::*;
|
||||
pub use self::typeslots::*;
|
||||
|
||||
pub use self::pydebug::*;
|
||||
|
||||
pub use self::bltinmodule::*;
|
||||
pub use self::boolobject::*;
|
||||
pub use self::bytearrayobject::*;
|
||||
pub use self::bytesobject::*;
|
||||
pub use self::ceval::*;
|
||||
pub use self::code::*;
|
||||
pub use self::codecs::*;
|
||||
pub use self::compile::*;
|
||||
pub use self::complexobject::*;
|
||||
pub use self::descrobject::*;
|
||||
pub use self::dictobject::*;
|
||||
pub use self::enumobject::*;
|
||||
pub use self::eval::*;
|
||||
pub use self::fileobject::*;
|
||||
pub use self::floatobject::*;
|
||||
pub use self::frameobject::PyFrameObject;
|
||||
pub use self::genobject::*;
|
||||
pub use self::import::*;
|
||||
pub use self::intrcheck::*;
|
||||
pub use self::iterobject::*;
|
||||
pub use self::listobject::*;
|
||||
pub use self::longobject::*;
|
||||
pub use self::memoryobject::*;
|
||||
pub use self::methodobject::*;
|
||||
pub use self::modsupport::*;
|
||||
pub use self::moduleobject::*;
|
||||
pub use self::object::*;
|
||||
pub use self::objectabstract::*;
|
||||
pub use self::objimpl::*;
|
||||
#[cfg(Py_3_6)]
|
||||
pub use self::osmodule::*;
|
||||
pub use self::pyarena::*;
|
||||
pub use self::pycapsule::*;
|
||||
pub use self::pydebug::*;
|
||||
pub use self::pyerrors::*;
|
||||
pub use self::pyhash::*;
|
||||
pub use self::pymem::*;
|
||||
pub use self::pyport::*;
|
||||
pub use self::pystate::*;
|
||||
pub use self::pystrtod::*;
|
||||
pub use self::pythonrun::*;
|
||||
pub use self::rangeobject::*;
|
||||
pub use self::setobject::*;
|
||||
pub use self::sliceobject::*;
|
||||
pub use self::structseq::*;
|
||||
pub use self::sysmodule::*;
|
||||
pub use self::traceback::*;
|
||||
pub use self::tupleobject::*;
|
||||
pub use self::typeslots::*;
|
||||
pub use self::unicodeobject::*;
|
||||
pub use self::warnings::*;
|
||||
pub use self::weakrefobject::*;
|
||||
|
||||
pub use self::codecs::*;
|
||||
pub use self::pyerrors::*;
|
||||
|
||||
pub use self::pystate::*;
|
||||
|
||||
pub use self::ceval::*;
|
||||
pub use self::import::*;
|
||||
pub use self::intrcheck::*;
|
||||
pub use self::modsupport::*;
|
||||
#[cfg(Py_3_6)]
|
||||
pub use self::osmodule::*;
|
||||
pub use self::pyarena::*;
|
||||
pub use self::pythonrun::*;
|
||||
pub use self::sysmodule::*;
|
||||
|
||||
pub use self::bltinmodule::*;
|
||||
pub use self::objectabstract::*;
|
||||
|
||||
pub use self::code::*;
|
||||
pub use self::compile::*;
|
||||
pub use self::eval::*;
|
||||
|
||||
pub use self::frameobject::PyFrameObject;
|
||||
pub use self::pystrtod::*;
|
||||
|
||||
mod pyport;
|
||||
// mod pymacro; contains nothing of interest for Rust
|
||||
// mod pyatomic; contains nothing of interest for Rust
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
//! Free allocation list
|
||||
|
||||
use crate::ffi;
|
||||
use crate::python::Python;
|
||||
use crate::typeob::{pytype_drop, PyObjectAlloc, PyTypeInfo};
|
||||
use crate::type_object::{pytype_drop, PyObjectAlloc, PyTypeInfo};
|
||||
use crate::Python;
|
||||
use std::mem;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! Interaction with python's global interpreter lock
|
||||
|
||||
use crate::ffi;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use spin;
|
||||
use std::ptr::NonNull;
|
||||
use std::{any, marker, rc, sync};
|
||||
|
@ -325,10 +328,11 @@ mod array_list {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{GILPool, NonNull, ReleasePool, POOL};
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::{ffi, pythonrun};
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{ffi, gil};
|
||||
|
||||
fn get_object() -> PyObject {
|
||||
// Convenience function for getting a single unique object
|
||||
|
@ -342,7 +346,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_owned() {
|
||||
pythonrun::init_once();
|
||||
gil::init_once();
|
||||
|
||||
unsafe {
|
||||
let p: &'static mut ReleasePool = &mut *POOL;
|
||||
|
@ -355,7 +359,7 @@ mod test {
|
|||
|
||||
empty = ffi::PyTuple_New(0);
|
||||
cnt = ffi::Py_REFCNT(empty) - 1;
|
||||
let _ = pythonrun::register_owned(py, NonNull::new(empty).unwrap());
|
||||
let _ = gil::register_owned(py, NonNull::new(empty).unwrap());
|
||||
|
||||
assert_eq!(p.owned.len(), 1);
|
||||
}
|
||||
|
@ -369,7 +373,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_owned_nested() {
|
||||
pythonrun::init_once();
|
||||
gil::init_once();
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
|
@ -386,14 +390,14 @@ mod test {
|
|||
empty = ffi::PyTuple_New(0);
|
||||
cnt = ffi::Py_REFCNT(empty) - 1;
|
||||
|
||||
let _ = pythonrun::register_owned(py, NonNull::new(empty).unwrap());
|
||||
let _ = gil::register_owned(py, NonNull::new(empty).unwrap());
|
||||
|
||||
assert_eq!(p.owned.len(), 1);
|
||||
|
||||
{
|
||||
let _pool = GILPool::new();
|
||||
let empty = ffi::PyTuple_New(0);
|
||||
let _ = pythonrun::register_owned(py, NonNull::new(empty).unwrap());
|
||||
let _ = gil::register_owned(py, NonNull::new(empty).unwrap());
|
||||
assert_eq!(p.owned.len(), 2);
|
||||
}
|
||||
assert_eq!(p.owned.len(), 1);
|
||||
|
@ -407,7 +411,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_borrowed() {
|
||||
pythonrun::init_once();
|
||||
gil::init_once();
|
||||
|
||||
unsafe {
|
||||
let p: &'static mut ReleasePool = &mut *POOL;
|
||||
|
@ -421,7 +425,7 @@ mod test {
|
|||
assert_eq!(p.borrowed.len(), 0);
|
||||
|
||||
cnt = ffi::Py_REFCNT(obj_ptr);
|
||||
pythonrun::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
|
||||
assert_eq!(p.borrowed.len(), 1);
|
||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), cnt);
|
||||
|
@ -436,7 +440,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_borrowed_nested() {
|
||||
pythonrun::init_once();
|
||||
gil::init_once();
|
||||
|
||||
unsafe {
|
||||
let p: &'static mut ReleasePool = &mut *POOL;
|
||||
|
@ -450,7 +454,7 @@ mod test {
|
|||
assert_eq!(p.borrowed.len(), 0);
|
||||
|
||||
cnt = ffi::Py_REFCNT(obj_ptr);
|
||||
pythonrun::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
|
||||
assert_eq!(p.borrowed.len(), 1);
|
||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), cnt);
|
||||
|
@ -458,7 +462,7 @@ mod test {
|
|||
{
|
||||
let _pool = GILPool::new();
|
||||
assert_eq!(p.borrowed.len(), 1);
|
||||
pythonrun::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
||||
assert_eq!(p.borrowed.len(), 2);
|
||||
}
|
||||
|
||||
|
@ -475,7 +479,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_pyobject_drop() {
|
||||
pythonrun::init_once();
|
||||
gil::init_once();
|
||||
|
||||
unsafe {
|
||||
let p: &'static mut ReleasePool = &mut *POOL;
|
174
src/instance.rs
174
src/instance.rs
|
@ -1,32 +1,31 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::gil;
|
||||
use crate::instance;
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::pythonrun;
|
||||
use crate::typeob::PyTypeCreate;
|
||||
use crate::typeob::{PyTypeInfo, PyTypeObject};
|
||||
use crate::type_object::PyTypeCreate;
|
||||
use crate::type_object::{PyTypeInfo, PyTypeObject};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Any instance that is managed Python can have access to `gil`.
|
||||
/// Types that are built into the python interpreter.
|
||||
///
|
||||
/// Originally, this was given to all classes with a `PyToken` field, but since `PyToken` was
|
||||
/// removed this is only given to native types.
|
||||
pub trait PyObjectWithGIL: Sized {
|
||||
/// pyo3 is designed in a way that that all references to those types are bound to the GIL,
|
||||
/// which is why you can get a token from all references of those types.
|
||||
pub trait PyNativeType: Sized {
|
||||
fn py(&self) -> Python;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait PyNativeType: PyObjectWithGIL {}
|
||||
|
||||
/// A special reference of type `T`. `PyRef<T>` refers a instance of T, which exists in the Python
|
||||
/// heap as a part of a Python object.
|
||||
///
|
||||
|
@ -267,21 +266,19 @@ unsafe impl<T> Send for Py<T> {}
|
|||
|
||||
unsafe impl<T> Sync for Py<T> {}
|
||||
|
||||
impl<T> Py<T>
|
||||
where
|
||||
T: PyTypeCreate + PyTypeObject,
|
||||
{
|
||||
impl<T> Py<T> {
|
||||
/// Create new instance of T and move it under python management
|
||||
pub fn new(py: Python, value: T) -> PyResult<Py<T>> {
|
||||
pub fn new(py: Python, value: T) -> PyResult<Py<T>>
|
||||
where
|
||||
T: PyTypeCreate,
|
||||
{
|
||||
let ob = T::create(py)?;
|
||||
ob.init(value);
|
||||
|
||||
let ob = unsafe { Py::from_owned_ptr(ob.into_ptr()) };
|
||||
Ok(ob)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Py<T> {
|
||||
/// Creates a `Py<T>` instance for the given FFI pointer.
|
||||
/// This moves ownership over the pointer into the `Py<T>`.
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
|
@ -440,7 +437,7 @@ impl<T> PartialEq for Py<T> {
|
|||
impl<T> Drop for Py<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
pythonrun::register_pointer(self.0);
|
||||
gil::register_pointer(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,3 +498,140 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reference to a converted [ToPyObject].
|
||||
///
|
||||
/// Many methods want to take anything that can be converted into a python object. This type
|
||||
/// takes care of both types types that are already python object (i.e. implement
|
||||
/// [ToPyPointer]) and those that don't (i.e. [ToPyObject] types).
|
||||
/// For the [ToPyPointer] types, we just use the borrowed pointer, which is a lot faster
|
||||
/// and simpler than creating a new extra object. The remaning [ToPyObject] types are
|
||||
/// converted to python objects, the owned pointer is stored and decref'd on drop.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use pyo3::ffi;
|
||||
/// use pyo3::{ToPyObject, ToPyPointer, PyNativeType, ManagedPyRef};
|
||||
/// use pyo3::types::{PyDict, PyObjectRef};
|
||||
///
|
||||
/// pub fn get_dict_item<'p>(dict: &'p PyDict, key: &impl ToPyObject) -> Option<&'p PyObjectRef> {
|
||||
/// let key = ManagedPyRef::from_to_pyobject(dict.py(), key);
|
||||
/// unsafe {
|
||||
/// dict.py().from_borrowed_ptr_or_opt(ffi::PyDict_GetItem(dict.as_ptr(), key.as_ptr()))
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[repr(transparent)]
|
||||
pub struct ManagedPyRef<'p, T: ToPyObject + ?Sized> {
|
||||
data: *mut ffi::PyObject,
|
||||
data_type: PhantomData<T>,
|
||||
_py: Python<'p>,
|
||||
}
|
||||
|
||||
/// This should eventually be replaced with a generic `IntoPy` trait impl by figuring
|
||||
/// out the correct lifetime annotation to make the compiler happy
|
||||
impl<'p, T: ToPyObject> ManagedPyRef<'p, T> {
|
||||
pub fn from_to_pyobject(py: Python<'p>, to_pyobject: &T) -> Self {
|
||||
to_pyobject.to_managed_py_ref(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p, T: ToPyObject> ToPyPointer for ManagedPyRef<'p, T> {
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to choose the right implementation for [BorrowedPyRef]
|
||||
pub trait ManagedPyRefDispatch: ToPyObject {
|
||||
/// Optionally converts into a python object and stores the pointer to the python heap.
|
||||
///
|
||||
/// Contains the case 1 impl (with to_object) to avoid a specialization error
|
||||
fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
|
||||
ManagedPyRef {
|
||||
data: self.to_object(py).into_ptr(),
|
||||
data_type: PhantomData,
|
||||
_py: py,
|
||||
}
|
||||
}
|
||||
|
||||
/// Dispatch over a xdecref and a noop drop impl
|
||||
///
|
||||
/// Contains the case 1 impl (decref) to avoid a specialization error
|
||||
fn drop_impl(borrowed: &mut ManagedPyRef<Self>) {
|
||||
unsafe { ffi::Py_DECREF(borrowed.data) };
|
||||
}
|
||||
}
|
||||
|
||||
/// Case 1: It's a rust object which still needs to be converted to a python object.
|
||||
/// This means we're storing the owned pointer that into_ptr() has given us
|
||||
/// and therefore need to xdecref when we're done.
|
||||
///
|
||||
/// Note that the actual implementations are part of the trait declaration to avoid
|
||||
/// a specialization error
|
||||
impl<T: ToPyObject + ?Sized> ManagedPyRefDispatch for T {}
|
||||
|
||||
/// Case 2: It's an object on the python heap, we're just storing a borrowed pointer.
|
||||
/// The object we're getting is an owned pointer, it might have it's own drop impl.
|
||||
impl<T: ToPyObject + ToPyPointer + ?Sized> ManagedPyRefDispatch for T {
|
||||
/// Use ToPyPointer to copy the pointer and store it as borrowed pointer
|
||||
fn to_managed_py_ref<'p>(&self, py: Python<'p>) -> ManagedPyRef<'p, Self> {
|
||||
ManagedPyRef {
|
||||
data: self.as_ptr(),
|
||||
data_type: PhantomData,
|
||||
_py: py,
|
||||
}
|
||||
}
|
||||
|
||||
/// We have a borrowed pointer, so nothing to do here
|
||||
fn drop_impl(_: &mut ManagedPyRef<T>) {}
|
||||
}
|
||||
|
||||
impl<'p, T: ToPyObject + ?Sized> Drop for ManagedPyRef<'p, T> {
|
||||
/// Uses the internal [ManagedPyRefDispatch] trait to get the right drop impl without causing
|
||||
/// a specialization error
|
||||
fn drop(&mut self) {
|
||||
ManagedPyRefDispatch::drop_impl(self);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::ffi;
|
||||
use crate::types::PyDict;
|
||||
use crate::{ManagedPyRef, Python, ToPyPointer};
|
||||
|
||||
#[test]
|
||||
fn borrowed_py_ref_with_to_pointer() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let native = PyDict::new(py);
|
||||
let ref_count = unsafe { ffi::Py_REFCNT(native.as_ptr()) };
|
||||
let borrowed = ManagedPyRef::from_to_pyobject(py, native);
|
||||
assert_eq!(native.as_ptr(), borrowed.data);
|
||||
assert_eq!(ref_count, unsafe { ffi::Py_REFCNT(borrowed.data) });
|
||||
drop(borrowed);
|
||||
assert_eq!(ref_count, unsafe { ffi::Py_REFCNT(native.as_ptr()) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrowed_py_ref_with_to_object() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let convertible = (1, 2, 3);
|
||||
let borrowed = ManagedPyRef::from_to_pyobject(py, &convertible);
|
||||
let ptr = borrowed.data;
|
||||
// The refcountwould become 0 after dropping, which means the gc can free the pointer
|
||||
// and getting the refcount would be UB. This incref ensures that it remains 1
|
||||
unsafe {
|
||||
ffi::Py_INCREF(ptr);
|
||||
}
|
||||
assert_eq!(2, unsafe { ffi::Py_REFCNT(ptr) });
|
||||
drop(borrowed);
|
||||
assert_eq!(1, unsafe { ffi::Py_REFCNT(ptr) });
|
||||
unsafe {
|
||||
ffi::Py_DECREF(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
src/lib.rs
33
src/lib.rs
|
@ -118,29 +118,18 @@
|
|||
//! }
|
||||
//! ```
|
||||
|
||||
//pub extern crate libc;
|
||||
//pub extern crate mashup;
|
||||
//extern crate pyo3cls;
|
||||
//extern crate num_traits;
|
||||
//extern crate spin;
|
||||
//extern crate indoc;
|
||||
//#[macro_use]
|
||||
//extern crate assert_approx_eq;
|
||||
|
||||
pub use crate::class::*;
|
||||
pub use crate::conversion::{
|
||||
FromPyObject, IntoPy, IntoPyObject, IntoPyResult, PyTryFrom, PyTryInto, ToBorrowedObject,
|
||||
ToPyObject,
|
||||
FromPy, FromPyObject, IntoPy, IntoPyObject, IntoPyPointer, PyTryFrom, PyTryInto,
|
||||
ToBorrowedObject, ToPyObject, ToPyPointer,
|
||||
};
|
||||
pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
|
||||
pub use crate::instance::{AsPyRef, Py, PyNativeType, PyObjectWithGIL, PyRef, PyRefMut};
|
||||
pub use crate::noargs::NoArgs;
|
||||
pub use crate::gil::{init_once, GILGuard, GILPool};
|
||||
pub use crate::instance::{AsPyRef, ManagedPyRef, Py, PyNativeType, PyRef, PyRefMut};
|
||||
pub use crate::object::PyObject;
|
||||
pub use crate::objectprotocol::ObjectProtocol;
|
||||
pub use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
pub use crate::pythonrun::{init_once, prepare_freethreaded_python, GILGuard, GILPool};
|
||||
pub use crate::typeob::{PyObjectAlloc, PyRawObject, PyTypeInfo};
|
||||
pub use crate::types::exceptions;
|
||||
pub use crate::python::{prepare_freethreaded_python, Python};
|
||||
pub use crate::type_object::{PyObjectAlloc, PyRawObject, PyTypeInfo};
|
||||
|
||||
// We need that reexport for wrap_function
|
||||
#[doc(hidden)]
|
||||
|
@ -149,7 +138,7 @@ pub use mashup;
|
|||
#[doc(hidden)]
|
||||
pub use inventory;
|
||||
|
||||
/// Rust FFI declarations for Python
|
||||
/// Raw ffi declarations for the c interface of python
|
||||
pub mod ffi;
|
||||
|
||||
#[cfg(not(Py_3))]
|
||||
|
@ -175,15 +164,15 @@ mod conversion;
|
|||
#[doc(hidden)]
|
||||
pub mod derive_utils;
|
||||
mod err;
|
||||
pub mod exceptions;
|
||||
pub mod freelist;
|
||||
mod gil;
|
||||
mod instance;
|
||||
mod noargs;
|
||||
mod object;
|
||||
mod objectprotocol;
|
||||
pub mod prelude;
|
||||
pub mod python;
|
||||
mod pythonrun;
|
||||
pub mod typeob;
|
||||
mod python;
|
||||
pub mod type_object;
|
||||
pub mod types;
|
||||
|
||||
/// The proc macros, which are also part of the prelude
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::{IntoPy, IntoPyObject, ToPyObject};
|
||||
use crate::instance::Py;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyTuple;
|
||||
|
||||
/// An empty struct that represents the empty argument list.
|
||||
/// Corresponds to the empty tuple `()` in Python.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use pyo3::prelude::*;
|
||||
///
|
||||
/// let gil = Python::acquire_gil();
|
||||
/// let py = gil.python();
|
||||
/// let os = py.import("os").unwrap();
|
||||
/// let pid = os.call("get_pid", NoArgs, None);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct NoArgs;
|
||||
|
||||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl IntoPy<Py<PyTuple>> for NoArgs {
|
||||
fn into_py(self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts `()` to an empty Python tuple.
|
||||
impl IntoPy<Py<PyTuple>> for () {
|
||||
fn into_py(self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl ToPyObject for NoArgs {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
PyTuple::empty(py).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl IntoPyObject for NoArgs {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
PyTuple::empty(py).into()
|
||||
}
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::{
|
||||
FromPyObject, IntoPy, IntoPyObject, PyTryFrom, ToBorrowedObject, ToPyObject,
|
||||
};
|
||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::{AsPyRef, PyObjectWithGIL, PyRef, PyRefMut};
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::pythonrun;
|
||||
use crate::gil;
|
||||
use crate::instance::{AsPyRef, PyNativeType, PyRef, PyRefMut};
|
||||
use crate::types::{PyDict, PyObjectRef, PyTuple};
|
||||
use crate::Py;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{
|
||||
FromPyObject, IntoPy, IntoPyObject, IntoPyPointer, PyTryFrom, ToBorrowedObject, ToPyObject,
|
||||
};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
/// A python object
|
||||
|
@ -202,7 +203,7 @@ impl PyObject {
|
|||
/// Calls the object without arguments.
|
||||
/// This is equivalent to the Python expression: 'self()'
|
||||
pub fn call0(&self, py: Python) -> PyResult<PyObject> {
|
||||
self.call(py, PyTuple::empty(py), None)
|
||||
self.call(py, (), None)
|
||||
}
|
||||
|
||||
/// Calls the object.
|
||||
|
@ -238,7 +239,7 @@ impl PyObject {
|
|||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: 'self.name()'
|
||||
pub fn call_method0(&self, py: Python, name: &str) -> PyResult<PyObject> {
|
||||
self.call_method(py, name, PyTuple::empty(py), None)
|
||||
self.call_method(py, name, (), None)
|
||||
}
|
||||
|
||||
/// Calls a method on the object.
|
||||
|
@ -279,14 +280,6 @@ impl ToPyPointer for PyObject {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPyPointer for &'a PyObject {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
self.0.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyPointer for PyObject {
|
||||
/// Gets the underlying FFI pointer, returns a owned pointer.
|
||||
#[inline]
|
||||
|
@ -325,16 +318,16 @@ impl<'a> FromPyObject<'a> for PyObject {
|
|||
impl Drop for PyObject {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
pythonrun::register_pointer(self.0);
|
||||
gil::register_pointer(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyDict;
|
||||
use crate::PyObject;
|
||||
use crate::Python;
|
||||
|
||||
#[test]
|
||||
fn test_call_for_non_existing_method() {
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::{FromPyObject, IntoPy, PyTryFrom, ToBorrowedObject, ToPyObject};
|
||||
use crate::class::basic::CompareOp;
|
||||
use crate::err::{self, PyDowncastError, PyErr, PyResult};
|
||||
use crate::exceptions::TypeError;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeInfo;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::{PyDict, PyIterator, PyObjectRef, PyString, PyTuple, PyType};
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Py;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, IntoPy, PyTryFrom, ToBorrowedObject, ToPyObject};
|
||||
use std::cmp::Ordering;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
|
@ -68,7 +71,7 @@ pub trait ObjectProtocol {
|
|||
/// * CompareOp::Le: `self <= other`
|
||||
/// * CompareOp::Gt: `self > other`
|
||||
/// * CompareOp::Ge: `self >= other`
|
||||
fn rich_compare<O>(&self, other: O, compare_op: crate::CompareOp) -> PyResult<PyObject>
|
||||
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<PyObject>
|
||||
where
|
||||
O: ToPyObject;
|
||||
|
||||
|
@ -208,7 +211,7 @@ pub trait ObjectProtocol {
|
|||
|
||||
impl<T> ObjectProtocol for T
|
||||
where
|
||||
T: PyObjectWithGIL + ToPyPointer,
|
||||
T: PyNativeType + ToPyPointer,
|
||||
{
|
||||
fn hasattr<N>(&self, attr_name: N) -> PyResult<bool>
|
||||
where
|
||||
|
@ -290,7 +293,7 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn rich_compare<O>(&self, other: O, compare_op: crate::CompareOp) -> PyResult<PyObject>
|
||||
fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<PyObject>
|
||||
where
|
||||
O: ToPyObject,
|
||||
{
|
||||
|
@ -341,7 +344,7 @@ where
|
|||
}
|
||||
|
||||
fn call0(&self) -> PyResult<&PyObjectRef> {
|
||||
self.call(PyTuple::empty(self.py()), None)
|
||||
self.call((), None)
|
||||
}
|
||||
|
||||
fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyObjectRef> {
|
||||
|
@ -372,7 +375,7 @@ where
|
|||
}
|
||||
|
||||
fn call_method0(&self, name: &str) -> PyResult<&PyObjectRef> {
|
||||
self.call_method(name, PyTuple::empty(self.py()), None)
|
||||
self.call_method(name, (), None)
|
||||
}
|
||||
|
||||
fn call_method1(&self, name: &str, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyObjectRef> {
|
||||
|
@ -497,10 +500,10 @@ where
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::python::Python;
|
||||
use crate::types::{IntoPyDict, PyString};
|
||||
use crate::Python;
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
|
||||
#[test]
|
||||
fn test_debug_string() {
|
||||
|
|
|
@ -10,14 +10,15 @@
|
|||
//! use pyo3::prelude::*;
|
||||
//! ```
|
||||
|
||||
pub use crate::conversion::{FromPyObject, IntoPyObject, PyTryFrom, PyTryInto, ToPyObject};
|
||||
pub use crate::err::{PyErr, PyResult};
|
||||
pub use crate::gil::GILGuard;
|
||||
pub use crate::instance::{AsPyRef, Py, PyRef, PyRefMut};
|
||||
pub use crate::noargs::NoArgs;
|
||||
pub use crate::object::PyObject;
|
||||
pub use crate::objectprotocol::ObjectProtocol;
|
||||
pub use crate::python::Python;
|
||||
pub use crate::pythonrun::GILGuard;
|
||||
pub use crate::{
|
||||
FromPy, FromPyObject, IntoPy, IntoPyObject, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject,
|
||||
};
|
||||
// This is only part of the prelude because we need it for the pymodule function
|
||||
pub use crate::types::PyModule;
|
||||
// This is required for the constructor
|
||||
|
|
124
src/python.rs
124
src/python.rs
|
@ -2,20 +2,22 @@
|
|||
//
|
||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use crate::conversion::PyTryFrom;
|
||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::{AsPyRef, Py, PyRef, PyRefMut};
|
||||
use crate::gil::{self, GILGuard};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::object::PyObject;
|
||||
use crate::pythonrun::{self, GILGuard};
|
||||
use crate::typeob::PyTypeCreate;
|
||||
use crate::typeob::{PyTypeInfo, PyTypeObject};
|
||||
use crate::type_object::{PyTypeInfo, PyTypeObject};
|
||||
use crate::types::{PyDict, PyModule, PyObjectRef, PyType};
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyPointer, PyTryFrom};
|
||||
use std::ffi::CString;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_int;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
pub use gil::prepare_freethreaded_python;
|
||||
|
||||
/// Marker type that indicates that the GIL is currently held.
|
||||
///
|
||||
/// The 'Python' struct is a zero-size marker struct that is required for most Python operations.
|
||||
|
@ -48,62 +50,6 @@ use std::ptr::NonNull;
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Python<'p>(PhantomData<&'p GILGuard>);
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
pub trait ToPyPointer {
|
||||
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject;
|
||||
}
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
pub trait IntoPyPointer {
|
||||
/// Retrieves the underlying FFI pointer. Whether pointer owned or borrowed
|
||||
/// depends on implementation.
|
||||
fn into_ptr(self) -> *mut ffi::PyObject;
|
||||
}
|
||||
|
||||
/// Convert `None` into a null pointer.
|
||||
impl<T> ToPyPointer for Option<T>
|
||||
where
|
||||
T: ToPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref t) => t.as_ptr(),
|
||||
None => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `None` into a null pointer.
|
||||
impl<T> IntoPyPointer for Option<T>
|
||||
where
|
||||
T: IntoPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn into_ptr(self) -> *mut ffi::PyObject {
|
||||
match self {
|
||||
Some(t) => t.into_ptr(),
|
||||
None => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoPyPointer for &'a T
|
||||
where
|
||||
T: ToPyPointer,
|
||||
{
|
||||
fn into_ptr(self) -> *mut ffi::PyObject {
|
||||
let ptr = self.as_ptr();
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
ffi::Py_INCREF(ptr);
|
||||
}
|
||||
}
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> Python<'p> {
|
||||
/// Retrieve Python instance under the assumption that the GIL is already acquired at this point,
|
||||
/// and stays acquired for the lifetime `'p`.
|
||||
|
@ -246,38 +192,6 @@ impl<'p> Python<'p> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p> Python<'p> {
|
||||
/// Create new instance of `T` and move it under python management.
|
||||
/// Returns `Py<T>`.
|
||||
#[inline]
|
||||
pub fn init<T>(self, value: T) -> PyResult<Py<T>>
|
||||
where
|
||||
T: PyTypeCreate,
|
||||
{
|
||||
Py::new(self, value)
|
||||
}
|
||||
|
||||
/// Create new instance of `T` and move it under python management.
|
||||
/// Created object get registered in release pool. Returns references to `T`
|
||||
#[inline]
|
||||
pub fn init_ref<T>(self, value: T) -> PyResult<PyRef<'p, T>>
|
||||
where
|
||||
T: PyTypeCreate,
|
||||
{
|
||||
PyRef::new(self, value)
|
||||
}
|
||||
|
||||
/// Create new instance of `T` and move it under python management.
|
||||
/// Created object get registered in release pool. Returns mutable references to `T`
|
||||
#[inline]
|
||||
pub fn init_mut<T>(self, value: T) -> PyResult<PyRefMut<'p, T>>
|
||||
where
|
||||
T: PyTypeCreate,
|
||||
{
|
||||
PyRefMut::new(self, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> Python<'p> {
|
||||
unsafe fn unchecked_downcast<T: PyTypeInfo>(self, ob: &PyObjectRef) -> &'p T {
|
||||
if T::OFFSET == 0 {
|
||||
|
@ -303,7 +217,7 @@ impl<'p> Python<'p> {
|
|||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
let p = unsafe { pythonrun::register_owned(self, obj.into_nonnull()) };
|
||||
let p = unsafe { gil::register_owned(self, obj.into_nonnull()) };
|
||||
<T as PyTryFrom>::try_from(p)
|
||||
}
|
||||
|
||||
|
@ -312,14 +226,14 @@ impl<'p> Python<'p> {
|
|||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
let p = pythonrun::register_owned(self, obj.into_nonnull());
|
||||
let p = gil::register_owned(self, obj.into_nonnull());
|
||||
self.unchecked_downcast(p)
|
||||
}
|
||||
|
||||
/// Register `ffi::PyObject` pointer in release pool
|
||||
pub unsafe fn from_borrowed_ptr_to_obj(self, ptr: *mut ffi::PyObject) -> &'p PyObjectRef {
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => pythonrun::register_borrowed(self, p),
|
||||
Some(p) => gil::register_borrowed(self, p),
|
||||
None => crate::err::panic_after_error(),
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +247,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_owned(self, p);
|
||||
let p = gil::register_owned(self, p);
|
||||
self.unchecked_downcast(p)
|
||||
}
|
||||
None => crate::err::panic_after_error(),
|
||||
|
@ -348,7 +262,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_owned(self, p);
|
||||
let p = gil::register_owned(self, p);
|
||||
self.unchecked_mut_downcast(p)
|
||||
}
|
||||
None => crate::err::panic_after_error(),
|
||||
|
@ -364,7 +278,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_owned(self, p);
|
||||
let p = gil::register_owned(self, p);
|
||||
Ok(self.unchecked_downcast(p))
|
||||
}
|
||||
None => Err(PyErr::fetch(self)),
|
||||
|
@ -379,7 +293,7 @@ impl<'p> Python<'p> {
|
|||
T: PyTypeInfo,
|
||||
{
|
||||
NonNull::new(ptr).map(|p| {
|
||||
let p = pythonrun::register_owned(self, p);
|
||||
let p = gil::register_owned(self, p);
|
||||
self.unchecked_downcast(p)
|
||||
})
|
||||
}
|
||||
|
@ -393,7 +307,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_borrowed(self, p);
|
||||
let p = gil::register_borrowed(self, p);
|
||||
self.unchecked_downcast(p)
|
||||
}
|
||||
None => crate::err::panic_after_error(),
|
||||
|
@ -409,7 +323,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_borrowed(self, p);
|
||||
let p = gil::register_borrowed(self, p);
|
||||
self.unchecked_mut_downcast(p)
|
||||
}
|
||||
None => crate::err::panic_after_error(),
|
||||
|
@ -425,7 +339,7 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
match NonNull::new(ptr) {
|
||||
Some(p) => {
|
||||
let p = pythonrun::register_borrowed(self, p);
|
||||
let p = gil::register_borrowed(self, p);
|
||||
Ok(self.unchecked_downcast(p))
|
||||
}
|
||||
None => Err(PyErr::fetch(self)),
|
||||
|
@ -440,7 +354,7 @@ impl<'p> Python<'p> {
|
|||
T: PyTypeInfo,
|
||||
{
|
||||
NonNull::new(ptr).map(|p| {
|
||||
let p = pythonrun::register_borrowed(self, p);
|
||||
let p = gil::register_borrowed(self, p);
|
||||
self.unchecked_downcast(p)
|
||||
})
|
||||
}
|
||||
|
@ -449,7 +363,7 @@ impl<'p> Python<'p> {
|
|||
/// Pass value ownership to `Python` object and get reference back.
|
||||
/// Value get cleaned up on the GIL release.
|
||||
pub fn register_any<T: 'static>(self, ob: T) -> &'p T {
|
||||
unsafe { pythonrun::register_any(ob) }
|
||||
unsafe { gil::register_any(ob) }
|
||||
}
|
||||
|
||||
/// Release PyObject reference.
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
use crate::class::methods::PyMethodDefType;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::python::ToPyPointer;
|
||||
use crate::python::{IntoPyPointer, Python};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::types::PyType;
|
||||
use crate::{class, ffi, pythonrun};
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{class, ffi, gil};
|
||||
use class::methods::PyMethodsProtocol;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
|
@ -171,7 +172,7 @@ impl IntoPyPointer for PyRawObject {
|
|||
}
|
||||
}
|
||||
|
||||
impl PyObjectWithGIL for PyRawObject {
|
||||
impl PyNativeType for PyRawObject {
|
||||
#[inline]
|
||||
fn py(&self) -> Python {
|
||||
unsafe { Python::assume_gil_acquired() }
|
||||
|
@ -430,7 +431,7 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
|
|||
where
|
||||
T: PyObjectAlloc,
|
||||
{
|
||||
let _pool = pythonrun::GILPool::new_no_pointers();
|
||||
let _pool = gil::GILPool::new_no_pointers();
|
||||
let py = Python::assume_gil_acquired();
|
||||
<T as PyObjectAlloc>::dealloc(py, obj)
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
use crate::conversion::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::ffi;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::FromPyObject;
|
||||
use crate::PyResult;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
|
||||
/// Represents a Python `bool`.
|
||||
#[repr(transparent)]
|
||||
|
@ -62,10 +63,10 @@ impl<'source> FromPyObject<'source> for bool {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::types::{PyBool, PyObjectRef};
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
|
||||
#[test]
|
||||
fn test_true() {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use std::os::raw::c_char;
|
||||
use std::slice;
|
||||
|
||||
|
@ -72,8 +73,8 @@ impl PyByteArray {
|
|||
mod test {
|
||||
use crate::exceptions;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyByteArray;
|
||||
use crate::Python;
|
||||
|
||||
#[test]
|
||||
fn test_bytearray() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
#[cfg(any(not(Py_LIMITED_API), not(Py_3)))]
|
||||
use std::ops::*;
|
||||
use std::os::raw::c_double;
|
||||
|
@ -117,10 +118,10 @@ impl<'py> Neg for &'py PyComplex {
|
|||
#[cfg(feature = "num-complex")]
|
||||
mod complex_conversion {
|
||||
use super::*;
|
||||
use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::err::PyErr;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::PyResult;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use num_complex::Complex;
|
||||
|
||||
impl PyComplex {
|
||||
|
@ -215,7 +216,7 @@ mod complex_conversion {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyComplex;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use assert_approx_eq::assert_approx_eq;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::ffi::PyDateTimeAPI;
|
||||
|
@ -26,8 +25,10 @@ use crate::ffi::{
|
|||
};
|
||||
use crate::instance::Py;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::PyTuple;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
use crate::ToPyPointer;
|
||||
use std::os::raw::c_int;
|
||||
use std::ptr;
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::err::{self, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::types::{PyList, PyObjectRef};
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use std::{cmp, collections, hash, mem};
|
||||
|
||||
/// Represents a Python `dict`.
|
||||
|
@ -300,12 +302,12 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::python::Python;
|
||||
use crate::types::dict::IntoPyDict;
|
||||
use crate::types::{PyDict, PyList, PyTuple};
|
||||
use crate::ObjectProtocol;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -2,16 +2,17 @@
|
|||
//
|
||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use crate::conversion::{IntoPyObject, ToPyObject};
|
||||
use crate::err::PyErr;
|
||||
use crate::ffi;
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::FromPyObject;
|
||||
use crate::PyResult;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyObject, ToPyObject};
|
||||
use std::os::raw::c_double;
|
||||
|
||||
/// Represents a Python `float` object.
|
||||
|
@ -83,8 +84,8 @@ impl<'source> FromPyObject<'source> for f32 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
|
||||
macro_rules! num_to_py_object_and_back (
|
||||
($func_name:ident, $t1:ty, $t2:ty) => (
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
|
||||
/// A python iterator object.
|
||||
///
|
||||
|
@ -83,13 +84,13 @@ impl<'p> Drop for PyIterator<'p> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::gil::GILPool;
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::pythonrun::GILPool;
|
||||
use crate::types::{PyDict, PyList};
|
||||
use crate::GILGuard;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
//
|
||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use crate::conversion::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::err::{self, PyResult};
|
||||
use crate::ffi::{self, Py_ssize_t};
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
|
||||
/// Represents a Python `list`.
|
||||
#[repr(transparent)]
|
||||
|
@ -166,7 +168,7 @@ impl<T> ToPyObject for [T]
|
|||
where
|
||||
T: ToPyObject,
|
||||
{
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> PyObject {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
unsafe {
|
||||
let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
|
||||
for (i, e) in self.iter().enumerate() {
|
||||
|
@ -182,7 +184,7 @@ impl<T> ToPyObject for Vec<T>
|
|||
where
|
||||
T: ToPyObject,
|
||||
{
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> PyObject {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
self.as_slice().to_object(py)
|
||||
}
|
||||
}
|
||||
|
@ -205,11 +207,11 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyList;
|
||||
use crate::Python;
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
|
|
|
@ -30,7 +30,6 @@ pub use self::string2::{PyBytes, PyString, PyUnicode};
|
|||
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
|
||||
|
@ -58,8 +57,6 @@ macro_rules! pyobject_downcast (
|
|||
#[macro_export]
|
||||
macro_rules! pyobject_native_type_named (
|
||||
($name: ty $(,$type_param: ident)*) => {
|
||||
impl<$($type_param,)*> $crate::PyNativeType for $name {}
|
||||
|
||||
impl<$($type_param,)*> ::std::convert::AsRef<$crate::types::PyObjectRef> for $name {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &$crate::types::PyObjectRef {
|
||||
|
@ -67,14 +64,13 @@ macro_rules! pyobject_native_type_named (
|
|||
}
|
||||
}
|
||||
|
||||
impl<$($type_param,)*> $crate::PyObjectWithGIL for $name {
|
||||
#[inline]
|
||||
impl<$($type_param,)*> $crate::PyNativeType for $name {
|
||||
fn py(&self) -> $crate::Python {
|
||||
unsafe { $crate::Python::assume_gil_acquired() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($type_param,)*> $crate::python::ToPyPointer for $name {
|
||||
impl<$($type_param,)*> $crate::ToPyPointer for $name {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||
|
@ -85,6 +81,8 @@ macro_rules! pyobject_native_type_named (
|
|||
impl<$($type_param,)*> PartialEq for $name {
|
||||
#[inline]
|
||||
fn eq(&self, o: &$name) -> bool {
|
||||
use $crate::ToPyPointer;
|
||||
|
||||
self.as_ptr() == o.as_ptr()
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +106,7 @@ macro_rules! pyobject_native_type (
|
|||
#[macro_export]
|
||||
macro_rules! pyobject_native_type_convert(
|
||||
($name: ty, $typeobject: expr, $checkfunction: path $(,$type_param: ident)*) => {
|
||||
impl<$($type_param,)*> $crate::typeob::PyTypeInfo for $name {
|
||||
impl<$($type_param,)*> $crate::type_object::PyTypeInfo for $name {
|
||||
type Type = ();
|
||||
type BaseType = $crate::types::PyObjectRef;
|
||||
|
||||
|
@ -121,18 +119,20 @@ macro_rules! pyobject_native_type_convert(
|
|||
&mut $typeobject
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
fn is_instance(ptr: &$crate::types::PyObjectRef) -> bool {
|
||||
#[allow(unused_unsafe)]
|
||||
use $crate::ToPyPointer;
|
||||
|
||||
unsafe { $checkfunction(ptr.as_ptr()) > 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($type_param,)*> $crate::typeob::PyObjectAlloc for $name {}
|
||||
impl<$($type_param,)*> $crate::type_object::PyObjectAlloc for $name {}
|
||||
|
||||
impl<$($type_param,)*> $crate::typeob::PyTypeObject for $name {
|
||||
impl<$($type_param,)*> $crate::type_object::PyTypeObject for $name {
|
||||
fn init_type() -> std::ptr::NonNull<$crate::ffi::PyTypeObject> {
|
||||
unsafe {
|
||||
std::ptr::NonNull::new_unchecked(<Self as $crate::typeob::PyTypeInfo>::type_object() as *mut _)
|
||||
std::ptr::NonNull::new_unchecked(<Self as $crate::type_object::PyTypeInfo>::type_object() as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,8 @@ macro_rules! pyobject_native_type_convert(
|
|||
{
|
||||
#[inline]
|
||||
fn to_object(&self, py: $crate::Python) -> $crate::PyObject {
|
||||
use $crate::ToPyPointer;
|
||||
|
||||
unsafe {$crate::PyObject::from_borrowed_ptr(py, self.0.as_ptr())}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +180,6 @@ mod bytearray;
|
|||
mod complex;
|
||||
mod datetime;
|
||||
mod dict;
|
||||
pub mod exceptions;
|
||||
mod floatob;
|
||||
mod iterator;
|
||||
mod list;
|
||||
|
|
|
@ -2,18 +2,21 @@
|
|||
//
|
||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use crate::conversion::{IntoPy, ToPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::typeob::PyTypeCreate;
|
||||
use crate::typeob::PyTypeObject;
|
||||
use crate::type_object::PyTypeCreate;
|
||||
use crate::type_object::PyTypeObject;
|
||||
use crate::types::PyTuple;
|
||||
use crate::types::{exceptions, PyDict, PyObjectRef};
|
||||
use crate::types::{PyDict, PyObjectRef};
|
||||
use crate::IntoPy;
|
||||
use crate::Py;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
use crate::ToPyPointer;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
use std::str;
|
||||
|
@ -64,7 +67,7 @@ impl PyModule {
|
|||
return Err(PyErr::fetch(py));
|
||||
}
|
||||
|
||||
<&PyModule as crate::conversion::FromPyObject>::extract(py.from_owned_ptr_or_err(mptr)?)
|
||||
<&PyModule as crate::FromPyObject>::extract(py.from_owned_ptr_or_err(mptr)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,10 +127,7 @@ impl PyModule {
|
|||
|
||||
/// Calls a function in the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)(*args)`
|
||||
pub fn call1<A>(&self, name: &str, args: A) -> PyResult<&PyObjectRef>
|
||||
where
|
||||
A: IntoPy<Py<PyTuple>>,
|
||||
{
|
||||
pub fn call1(&self, name: &str, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyObjectRef> {
|
||||
self.getattr(name)?.call1(args)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use super::num_common::{err_if_invalid_value, IS_LITTLE_ENDIAN};
|
||||
use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::types::{exceptions, PyObjectRef};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use num_traits::cast::cast;
|
||||
use std::os::raw::{c_long, c_uchar};
|
||||
|
||||
|
@ -177,8 +180,8 @@ int_convert_bignum!(u128, 16, IS_LITTLE_ENDIAN, 0);
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
|
||||
macro_rules! num_to_py_object_and_back (
|
||||
($func_name:ident, $t1:ty, $t2:ty) => (
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use super::num_common::{err_if_invalid_value, IS_LITTLE_ENDIAN};
|
||||
use crate::conversion::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::{exceptions, PyObjectRef};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use num_traits::cast::cast;
|
||||
use std::i64;
|
||||
use std::os::raw::{c_long, c_uchar};
|
||||
|
@ -146,9 +148,9 @@ mod test {
|
|||
macro_rules! test_common (
|
||||
($test_mod_name:ident, $t:ty) => (
|
||||
mod $test_mod_name {
|
||||
use crate::types::exceptions;
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::python::Python;
|
||||
use crate::exceptions;
|
||||
use crate::ToPyObject;
|
||||
use crate::Python;
|
||||
|
||||
#[test]
|
||||
fn from_py_string_type_error() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! common macros for num2.rs and num3.rs
|
||||
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
pub(super) fn err_if_invalid_value<T: PartialEq + Copy>(
|
||||
|
@ -104,8 +104,8 @@ pub(super) const IS_LITTLE_ENDIAN: c_int = 0;
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
|
||||
#[test]
|
||||
fn test_u32_max() {
|
||||
|
@ -188,9 +188,9 @@ mod test {
|
|||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
fn test_u128_overflow() {
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::object::PyObject;
|
||||
use crate::types::exceptions;
|
||||
use std::os::raw::c_uchar;
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::buffer;
|
||||
use crate::conversion::{FromPyObject, PyTryFrom, ToBorrowedObject};
|
||||
use crate::err::{self, PyDowncastError, PyErr, PyResult};
|
||||
use crate::ffi::{self, Py_ssize_t};
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::ToPyPointer;
|
||||
use crate::types::{PyList, PyObjectRef, PyTuple};
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, PyTryFrom, ToBorrowedObject};
|
||||
|
||||
/// Represents a reference to a python object supporting the sequence protocol.
|
||||
#[repr(transparent)]
|
||||
|
@ -327,12 +327,13 @@ impl<'v> PyTryFrom<'v> for PySequence {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::PySequence;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
|
||||
fn get_object() -> PyObject {
|
||||
// Convenience function for getting a single unique object
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
//
|
||||
|
||||
use crate::conversion::{ToBorrowedObject, ToPyObject};
|
||||
use crate::err::{self, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::{AsPyRef, Py, PyObjectWithGIL};
|
||||
use crate::instance::{AsPyRef, Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{ToBorrowedObject, ToPyObject};
|
||||
use std::{collections, hash};
|
||||
|
||||
/// Represents a Python `set`
|
||||
|
@ -160,10 +161,10 @@ impl PyFrozenSet {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{PyFrozenSet, PySet};
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::ToPyObject;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi::{self, Py_ssize_t};
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::Python;
|
||||
use crate::{ToPyObject, ToPyPointer};
|
||||
use std::os::raw::c_long;
|
||||
|
||||
/// Represents a Python `slice`.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::exceptions;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use std::borrow::Cow;
|
||||
use std::os::raw::c_char;
|
||||
use std::{mem, str};
|
||||
|
@ -119,10 +120,10 @@ impl PyBytes {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyString;
|
||||
use crate::conversion::{FromPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, PyTryFrom, ToPyObject};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
use super::PyObjectRef;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::IntoPyPointer;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::types::exceptions;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use std::borrow::Cow;
|
||||
use std::os::raw::c_char;
|
||||
use std::str;
|
||||
|
@ -204,10 +205,10 @@ impl std::convert::From<Py<PyUnicode>> for Py<PyString> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyString;
|
||||
use crate::conversion::{FromPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, PyTryFrom, ToPyObject};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::conversion::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::err::PyResult;
|
||||
use crate::instance::PyObjectWithGIL;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::python::Python;
|
||||
use crate::types::{PyObjectRef, PyString};
|
||||
use crate::FromPyObject;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Converts Rust `str` to Python object.
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use super::exceptions;
|
||||
use crate::conversion::{FromPyObject, IntoPy, IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::conversion::FromPy;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi::{self, Py_ssize_t};
|
||||
use crate::instance::{AsPyRef, Py, PyObjectWithGIL};
|
||||
use crate::instance::{AsPyRef, Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use crate::{FromPyObject, IntoPy, IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use std::slice;
|
||||
|
||||
/// Represents a Python `tuple` object.
|
||||
|
@ -131,25 +134,9 @@ impl<'a> IntoIterator for &'a PyTuple {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPy<Py<PyTuple>> for &'a PyTuple {
|
||||
fn into_py(self, _py: Python) -> Py<PyTuple> {
|
||||
unsafe { Py::from_borrowed_ptr(self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<Py<PyTuple>> for Py<PyTuple> {
|
||||
fn into_py(self, _py: Python) -> Py<PyTuple> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPy<Py<PyTuple>> for &'a str {
|
||||
fn into_py(self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New(1);
|
||||
ffi::PyTuple_SetItem(ptr, 0, self.into_object(py).into_ptr());
|
||||
Py::from_owned_ptr_or_panic(ptr)
|
||||
}
|
||||
impl<'a> FromPy<&'a PyTuple> for Py<PyTuple> {
|
||||
fn from_py(tuple: &'a PyTuple, _py: Python) -> Py<PyTuple> {
|
||||
unsafe { Py::from_borrowed_ptr(tuple.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,12 +252,12 @@ tuple_conversion!(
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::python::Python;
|
||||
use crate::types::PyObjectRef;
|
||||
use crate::types::PyTuple;
|
||||
use crate::Python;
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::{Py, PyObjectWithGIL};
|
||||
use crate::instance::{Py, PyNativeType};
|
||||
use crate::object::PyObject;
|
||||
use crate::python::{Python, ToPyPointer};
|
||||
use crate::typeob::{PyTypeInfo, PyTypeObject};
|
||||
use crate::type_object::{PyTypeInfo, PyTypeObject};
|
||||
use crate::Python;
|
||||
use crate::ToPyPointer;
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::CStr;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use pyo3::class::basic::CompareOp;
|
||||
use pyo3::class::*;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyObjectRef;
|
||||
|
|
|
@ -12,7 +12,7 @@ fn empty_class() {
|
|||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClass>();
|
||||
// By default, don't allow creating instances from python.
|
||||
assert!(typeobj.call(NoArgs, None).is_err());
|
||||
assert!(typeobj.call((), None).is_err());
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ fn empty_class_with_new() {
|
|||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClassWithNew>();
|
||||
assert!(typeobj
|
||||
.call(NoArgs, None)
|
||||
.call((), None)
|
||||
.unwrap()
|
||||
.cast_as::<EmptyClassWithNew>()
|
||||
.is_ok());
|
||||
|
|
|
@ -6,8 +6,8 @@ use pyo3::class::{
|
|||
use pyo3::exceptions::{IndexError, ValueError};
|
||||
use pyo3::ffi;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::python::ToPyPointer;
|
||||
use pyo3::types::{PyBytes, PyDict, PyObjectRef, PySlice, PyString, PyType};
|
||||
use pyo3::ToPyPointer;
|
||||
use std::{isize, iter};
|
||||
|
||||
#[macro_use]
|
||||
|
@ -176,7 +176,7 @@ impl PySequenceProtocol for Sequence {
|
|||
|
||||
fn __getitem__(&self, key: isize) -> PyResult<isize> {
|
||||
if key == 5 {
|
||||
return Err(PyErr::new::<IndexError, NoArgs>(NoArgs));
|
||||
return Err(PyErr::new::<IndexError, _>(()));
|
||||
}
|
||||
Ok(key)
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ use pyo3::class::PyTraverseError;
|
|||
use pyo3::class::PyVisit;
|
||||
use pyo3::ffi;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::python::ToPyPointer;
|
||||
use pyo3::types::PyObjectRef;
|
||||
use pyo3::types::PyTuple;
|
||||
use pyo3::PyRawObject;
|
||||
use pyo3::ToPyPointer;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
@ -100,7 +100,7 @@ impl Drop for ClassWithDrop {
|
|||
}
|
||||
}
|
||||
|
||||
// Test behavior of pythonrun::register_pointers + typeob::dealloc
|
||||
// Test behavior of pythonrun::register_pointers + type_object::dealloc
|
||||
#[test]
|
||||
fn create_pointers_in_drop() {
|
||||
let _gil = Python::acquire_gil();
|
||||
|
@ -258,7 +258,7 @@ fn inheritance_with_new_methods_with_drop() {
|
|||
let py = gil.python();
|
||||
let _typebase = py.get_type::<BaseClassWithDrop>();
|
||||
let typeobj = py.get_type::<SubClassWithDrop>();
|
||||
let inst = typeobj.call(NoArgs, None).unwrap();
|
||||
let inst = typeobj.call((), None).unwrap();
|
||||
|
||||
let obj = SubClassWithDrop::try_from_mut(inst).unwrap();
|
||||
obj.data = Some(Arc::clone(&drop_called1));
|
||||
|
|
|
@ -60,6 +60,6 @@ fn inheritance_with_new_methods() {
|
|||
let py = gil.python();
|
||||
let _typebase = py.get_type::<BaseClass>();
|
||||
let typeobj = py.get_type::<SubClass>();
|
||||
let inst = typeobj.call(NoArgs, None).unwrap();
|
||||
let inst = typeobj.call((), None).unwrap();
|
||||
py_run!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5");
|
||||
}
|
||||
|
|
|
@ -86,14 +86,14 @@ fn some_name(_: Python, _: &PyModule) -> PyResult<()> {
|
|||
#[test]
|
||||
#[cfg(Py_3)]
|
||||
fn test_module_renaming() {
|
||||
use pyo3::wrap_pymodule;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("different_name", unsafe {
|
||||
PyObject::from_owned_ptr(py, PyInit_other_name())
|
||||
})
|
||||
.unwrap();
|
||||
d.set_item("different_name", wrap_pymodule!(other_name)(py))
|
||||
.unwrap();
|
||||
|
||||
py.run(
|
||||
"assert different_name.__name__ == 'other_name'",
|
||||
|
|
Loading…
Reference in a new issue