Merge branch 'master' into pyclass-new-layout
This commit is contained in:
commit
451de182cb
|
@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Changed
|
||||
|
||||
* The blanket implementations for `FromPyObject` for `&T` and `&mut T` are no longer specializable. Implement `PyTryFrom` for your type to control the behavior of `FromPyObject::extract()` for your types.
|
||||
* The implementation for `IntoPy<U> for T` where `U: FromPy<T>` is no longer specializable. Control the behavior of this via the implementation of `FromPy`.
|
||||
|
||||
## [0.8.5]
|
||||
|
||||
* Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)
|
||||
* Implemented `FromPyObject` for `HashMap` and `BTreeMap`
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pyo3"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
description = "Bindings to Python interpreter"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
readme = "README.md"
|
||||
|
@ -22,7 +22,7 @@ appveyor = { repository = "fafhrd91/pyo3" }
|
|||
libc = "0.2.62"
|
||||
spin = "0.5.1"
|
||||
num-traits = "0.2.8"
|
||||
pyo3cls = { path = "pyo3cls", version = "=0.8.4" }
|
||||
pyo3cls = { path = "pyo3cls", version = "=0.8.5" }
|
||||
num-complex = { version = ">= 0.2", optional = true }
|
||||
num-bigint = { version = ">= 0.2", optional = true }
|
||||
inventory = "0.1.4"
|
||||
|
|
|
@ -50,7 +50,7 @@ name = "string_sum"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
features = ["extension-module"]
|
||||
```
|
||||
|
||||
|
@ -95,7 +95,7 @@ Add `pyo3` to your `Cargo.toml` like this:
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
pyo3 = "0.8.4"
|
||||
pyo3 = "0.8.5"
|
||||
```
|
||||
|
||||
Example program displaying the value of `sys.version` and the current user name:
|
||||
|
|
|
@ -86,6 +86,23 @@ pyo3::inventory::collect!(MyClassGeneratedPyo3Inventory);
|
|||
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
|
||||
```
|
||||
|
||||
## Add class to module
|
||||
|
||||
Custom Python classes can then be added to a module using `add_class`.
|
||||
|
||||
```rust
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
# num: i32,
|
||||
# debug: bool,
|
||||
# }
|
||||
#[pymodule]
|
||||
fn mymodule(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_class::<MyClass>()?;
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
## Get Python objects from `pyclass`
|
||||
You sometimes need to convert your `pyclass` into a Python object in Rust code (e.g., for testing it).
|
||||
|
@ -568,13 +585,59 @@ use pyo3::types::{PyDict, PyTuple};
|
|||
#
|
||||
#[pymethods]
|
||||
impl MyClass {
|
||||
#[args(arg1=true, args="*", arg2=10, args3="\"Hello\"", kwargs="**")]
|
||||
fn method(&self, arg1: bool, args: &PyTuple, arg2: i32, arg3: &str, kwargs: Option<&PyDict>) -> PyResult<i32> {
|
||||
Ok(1)
|
||||
#[new]
|
||||
#[args(num = "-1", debug = "true")]
|
||||
fn new(num: i32, debug: bool) -> Self {
|
||||
MyClass { num, debug }
|
||||
}
|
||||
|
||||
#[args(
|
||||
num = "10",
|
||||
debug = "true",
|
||||
py_args = "*",
|
||||
name = "\"Hello\"",
|
||||
py_kwargs = "**"
|
||||
)]
|
||||
fn method(
|
||||
&mut self,
|
||||
num: i32,
|
||||
debug: bool,
|
||||
name: &str,
|
||||
py_args: &PyTuple,
|
||||
py_kwargs: Option<&PyDict>,
|
||||
) -> PyResult<String> {
|
||||
self.debug = debug;
|
||||
self.num = num;
|
||||
Ok(format!(
|
||||
"py_args={:?}, py_kwargs={:?}, name={}, num={}, debug={}",
|
||||
py_args, py_kwargs, name, self.num, self.debug
|
||||
))
|
||||
}
|
||||
|
||||
fn make_change(&mut self, num: i32, debug: bool) -> PyResult<String> {
|
||||
self.num = num;
|
||||
self.debug = debug;
|
||||
Ok(format!("num={}, debug={}", self.num, self.debug))
|
||||
}
|
||||
}
|
||||
```
|
||||
N.B. the position of the `"*"` argument (if included) controls the system of handling positional and keyword arguments. In Python:
|
||||
```python
|
||||
import mymodule
|
||||
|
||||
mc = mymodule.MyClass()
|
||||
print(mc.method(44, False, "World", 666, x=44, y=55))
|
||||
print(mc.method(num=-1, name="World"))
|
||||
print(mc.make_change(44, False))
|
||||
print(mc.make_change(debug=False, num=-1))
|
||||
```
|
||||
Produces output:
|
||||
```text
|
||||
py_args=('World', 666), py_kwargs=Some({'x': 44, 'y': 55}), name=Hello, num=44, debug=false
|
||||
py_args=(), py_kwargs=None, name=World, num=-1, debug=true
|
||||
num=44, debug=false
|
||||
num=-1, debug=false
|
||||
```
|
||||
|
||||
## Class customizations
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ name = "string_sum"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
features = ["extension-module"]
|
||||
```
|
||||
|
||||
|
@ -89,7 +89,7 @@ Add `pyo3` to your `Cargo.toml` like this:
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
pyo3 = "0.8.4"
|
||||
pyo3 = "0.8.5"
|
||||
```
|
||||
|
||||
Example program displaying the value of `sys.version` and the current user name:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pyo3-derive-backend"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
description = "Code generation for PyO3 package"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||
|
|
|
@ -31,7 +31,7 @@ pub const OBJECT: Proto = Proto {
|
|||
MethodProto::Binary {
|
||||
name: "__delattr__",
|
||||
arg: "Name",
|
||||
pyres: true,
|
||||
pyres: false,
|
||||
proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pyo3cls"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
description = "Proc macros for PyO3 package"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||
|
@ -17,7 +17,7 @@ proc-macro = true
|
|||
quote = "1"
|
||||
proc-macro2 = "1"
|
||||
syn = { version = "1", features = ["full", "extra-traits"] }
|
||||
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.8.4" }
|
||||
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.8.5" }
|
||||
|
||||
[features]
|
||||
unsound-subclass = ["pyo3-derive-backend/unsound-subclass"]
|
||||
|
|
|
@ -146,7 +146,7 @@ impl<T, U> IntoPy<U> for T
|
|||
where
|
||||
U: FromPy<T>,
|
||||
{
|
||||
default fn into_py(self, py: Python) -> U {
|
||||
fn into_py(self, py: Python) -> U {
|
||||
U::from_py(self, py)
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ where
|
|||
T: PyTryFrom<'a>,
|
||||
{
|
||||
#[inline]
|
||||
default fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
|
||||
fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
|
||||
Ok(T::try_from(ob)?)
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ where
|
|||
T: PyTryFrom<'a>,
|
||||
{
|
||||
#[inline]
|
||||
default fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
|
||||
fn extract(ob: &'a PyAny) -> PyResult<&'a mut T> {
|
||||
Ok(T::try_from_mut(ob)?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
//! crate-type = ["cdylib"]
|
||||
//!
|
||||
//! [dependencies.pyo3]
|
||||
//! version = "0.8.4"
|
||||
//! version = "0.8.5"
|
||||
//! features = ["extension-module"]
|
||||
//! ```
|
||||
//!
|
||||
|
@ -93,7 +93,7 @@
|
|||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! pyo3 = "0.8.4"
|
||||
//! pyo3 = "0.8.5"
|
||||
//! ```
|
||||
//!
|
||||
//! Example program displaying the value of `sys.version`:
|
||||
|
|
Loading…
Reference in a new issue