Merge branch 'master' into pyclass-new-layout

This commit is contained in:
kngwyu 2020-01-08 17:16:10 +09:00
commit 451de182cb
10 changed files with 88 additions and 18 deletions

View file

@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## Unreleased ## 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) * Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)
* Implemented `FromPyObject` for `HashMap` and `BTreeMap` * Implemented `FromPyObject` for `HashMap` and `BTreeMap`

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3" name = "pyo3"
version = "0.8.4" version = "0.8.5"
description = "Bindings to Python interpreter" description = "Bindings to Python interpreter"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
readme = "README.md" readme = "README.md"
@ -22,7 +22,7 @@ appveyor = { repository = "fafhrd91/pyo3" }
libc = "0.2.62" libc = "0.2.62"
spin = "0.5.1" spin = "0.5.1"
num-traits = "0.2.8" 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-complex = { version = ">= 0.2", optional = true }
num-bigint = { version = ">= 0.2", optional = true } num-bigint = { version = ">= 0.2", optional = true }
inventory = "0.1.4" inventory = "0.1.4"

View file

@ -50,7 +50,7 @@ name = "string_sum"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies.pyo3] [dependencies.pyo3]
version = "0.8.4" version = "0.8.5"
features = ["extension-module"] features = ["extension-module"]
``` ```
@ -95,7 +95,7 @@ Add `pyo3` to your `Cargo.toml` like this:
```toml ```toml
[dependencies] [dependencies]
pyo3 = "0.8.4" pyo3 = "0.8.5"
``` ```
Example program displaying the value of `sys.version` and the current user name: Example program displaying the value of `sys.version` and the current user name:

View file

@ -86,6 +86,23 @@ pyo3::inventory::collect!(MyClassGeneratedPyo3Inventory);
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'") # 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` ## Get Python objects from `pyclass`
You sometimes need to convert your `pyclass` into a Python object in Rust code (e.g., for testing it). 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] #[pymethods]
impl MyClass { impl MyClass {
#[args(arg1=true, args="*", arg2=10, args3="\"Hello\"", kwargs="**")] #[new]
fn method(&self, arg1: bool, args: &PyTuple, arg2: i32, arg3: &str, kwargs: Option<&PyDict>) -> PyResult<i32> { #[args(num = "-1", debug = "true")]
Ok(1) 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 ## Class customizations

View file

@ -44,7 +44,7 @@ name = "string_sum"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies.pyo3] [dependencies.pyo3]
version = "0.8.4" version = "0.8.5"
features = ["extension-module"] features = ["extension-module"]
``` ```
@ -89,7 +89,7 @@ Add `pyo3` to your `Cargo.toml` like this:
```toml ```toml
[dependencies] [dependencies]
pyo3 = "0.8.4" pyo3 = "0.8.5"
``` ```
Example program displaying the value of `sys.version` and the current user name: Example program displaying the value of `sys.version` and the current user name:

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3-derive-backend" name = "pyo3-derive-backend"
version = "0.8.4" version = "0.8.5"
description = "Code generation for PyO3 package" description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]

View file

@ -31,7 +31,7 @@ pub const OBJECT: Proto = Proto {
MethodProto::Binary { MethodProto::Binary {
name: "__delattr__", name: "__delattr__",
arg: "Name", arg: "Name",
pyres: true, pyres: false,
proto: "pyo3::class::basic::PyObjectDelAttrProtocol", proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
}, },
MethodProto::Unary { MethodProto::Unary {

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3cls" name = "pyo3cls"
version = "0.8.4" version = "0.8.5"
description = "Proc macros for PyO3 package" description = "Proc macros for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]
@ -17,7 +17,7 @@ proc-macro = true
quote = "1" quote = "1"
proc-macro2 = "1" proc-macro2 = "1"
syn = { version = "1", features = ["full", "extra-traits"] } 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] [features]
unsound-subclass = ["pyo3-derive-backend/unsound-subclass"] unsound-subclass = ["pyo3-derive-backend/unsound-subclass"]

View file

@ -146,7 +146,7 @@ impl<T, U> IntoPy<U> for T
where where
U: FromPy<T>, U: FromPy<T>,
{ {
default fn into_py(self, py: Python) -> U { fn into_py(self, py: Python) -> U {
U::from_py(self, py) U::from_py(self, py)
} }
} }
@ -250,7 +250,7 @@ where
T: PyTryFrom<'a>, T: PyTryFrom<'a>,
{ {
#[inline] #[inline]
default fn extract(ob: &'a PyAny) -> PyResult<&'a T> { fn extract(ob: &'a PyAny) -> PyResult<&'a T> {
Ok(T::try_from(ob)?) Ok(T::try_from(ob)?)
} }
} }
@ -261,7 +261,7 @@ where
T: PyTryFrom<'a>, T: PyTryFrom<'a>,
{ {
#[inline] #[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)?) Ok(T::try_from_mut(ob)?)
} }
} }

View file

@ -48,7 +48,7 @@
//! crate-type = ["cdylib"] //! crate-type = ["cdylib"]
//! //!
//! [dependencies.pyo3] //! [dependencies.pyo3]
//! version = "0.8.4" //! version = "0.8.5"
//! features = ["extension-module"] //! features = ["extension-module"]
//! ``` //! ```
//! //!
@ -93,7 +93,7 @@
//! //!
//! ```toml //! ```toml
//! [dependencies] //! [dependencies]
//! pyo3 = "0.8.4" //! pyo3 = "0.8.5"
//! ``` //! ```
//! //!
//! Example program displaying the value of `sys.version`: //! Example program displaying the value of `sys.version`: