Migrate to rust 2018
This commit is contained in:
parent
423b5d1099
commit
936f0153e8
|
@ -14,7 +14,7 @@ dist/
|
|||
.eggs/
|
||||
venv*
|
||||
guide/book/
|
||||
examples/*/py
|
||||
examples/*/py*
|
||||
|
||||
*.so
|
||||
*.out
|
||||
|
|
|
@ -8,13 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
|
||||
### Added
|
||||
|
||||
* Added a `wrap_module!` macro similar to the existing `wrap_function!` macro. Only available on python 3
|
||||
* 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.
|
||||
|
||||
### Changed
|
||||
|
||||
* Renamed `add_function` to `add_wrapped` as it now also supports modules.
|
||||
* Renamed `#[pymodinit]` to `#[pymodule]`.
|
||||
* Renamed `py_exception` to `create_exception` and refactored the error macros.
|
||||
* Renamed `wrap_function!` to `wrap_pyfunction!`
|
||||
* Migrated to the 2018 edition
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pyo3"
|
||||
version = "0.6.0-alpha.1"
|
||||
version = "0.6.0-alpha.2"
|
||||
description = "Bindings to Python interpreter"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
readme = "README.md"
|
||||
|
@ -12,6 +12,7 @@ categories = ["api-bindings", "development-tools::ffi"]
|
|||
license = "Apache-2.0"
|
||||
exclude = ["/.gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
|
||||
build = "build.rs"
|
||||
edition = "2018"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "PyO3/pyo3", branch = "master" }
|
||||
|
@ -22,7 +23,7 @@ codecov = { repository = "PyO3/pyo3", branch = "master", service = "github" }
|
|||
libc = "0.2.43"
|
||||
spin = "0.5.0"
|
||||
num-traits = "0.2.6"
|
||||
pyo3cls = { path = "pyo3cls", version = "=0.6.0-alpha.1" }
|
||||
pyo3cls = { path = "pyo3cls", version = "=0.6.0-alpha.2" }
|
||||
mashup = "0.1.9"
|
||||
num-complex = { version = "0.2.1", optional = true }
|
||||
|
||||
|
|
20
README.md
20
README.md
|
@ -31,19 +31,20 @@ sudo apt install python3-dev python-dev
|
|||
|
||||
Pyo3 can be used to generate a native python module.
|
||||
|
||||
**`Cargo.toml`:**
|
||||
**`Cargo.toml`**
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "string-sum"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "string_sum"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.6.0-alpha.1"
|
||||
version = "0.6.0-alpha.2"
|
||||
features = ["extension-module"]
|
||||
```
|
||||
|
||||
|
@ -52,10 +53,8 @@ features = ["extension-module"]
|
|||
```rust
|
||||
#![feature(specialization)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::wrap_pyfunction;
|
||||
|
||||
#[pyfunction]
|
||||
/// Formats the sum of two numbers as string
|
||||
|
@ -66,7 +65,7 @@ fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
|
|||
/// This module is a python module implemented in Rust.
|
||||
#[pymodule]
|
||||
fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_function!(sum_as_string))?;
|
||||
m.add_wrapped(wrap_pyfunction!(sum_as_string))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -92,7 +91,7 @@ Add `pyo3` this to your `Cargo.toml`:
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
pyo3 = "0.5"
|
||||
pyo3 = "0.6.0-alpha.2"
|
||||
```
|
||||
|
||||
Example program displaying the value of `sys.version`:
|
||||
|
@ -100,8 +99,6 @@ Example program displaying the value of `sys.version`:
|
|||
```rust
|
||||
#![feature(specialization)]
|
||||
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyDict;
|
||||
|
||||
|
@ -110,11 +107,10 @@ fn main() -> PyResult<()> {
|
|||
let py = gil.python();
|
||||
let sys = py.import("sys")?;
|
||||
let version: String = sys.get("version")?.extract()?;
|
||||
|
||||
let locals = PyDict::new(py);
|
||||
locals.set_item("os", py.import("os")?)?;
|
||||
let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract()?;
|
||||
|
||||
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
|
||||
let user: String = py.eval(code, None, Some(&locals))?.extract()?;
|
||||
println!("Hello {}, I'm Python {}", user, version);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![feature(test)]
|
||||
extern crate pyo3;
|
||||
extern crate test;
|
||||
use test::Bencher;
|
||||
|
||||
use pyo3::{prelude::*, types::IntoPyDict};
|
||||
extern crate test;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::IntoPyDict;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn iter_dict(b: &mut Bencher) {
|
||||
|
|
3
build.rs
3
build.rs
|
@ -1,6 +1,3 @@
|
|||
extern crate regex;
|
||||
extern crate version_check;
|
||||
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::AsRef;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
set -ex
|
||||
|
||||
cargo fmt --all -- --check
|
||||
cargo test --features "$FEATURES"
|
||||
cargo clippy --features "$FEATURES"
|
||||
cargo test --features "$FEATURES num-complex"
|
||||
cargo clippy --features "$FEATURES num-complex"
|
||||
|
||||
for example_dir in examples/*; do
|
||||
tox -c "$example_dir/tox.ini" -e py
|
||||
|
|
|
@ -3,6 +3,7 @@ authors = ["PyO3 Authors"]
|
|||
name = "rustapi-module"
|
||||
version = "0.1.0"
|
||||
description = "A Python wrapper for the Rust API for purposes of testing"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
||||
|
|
|
@ -3,14 +3,15 @@ use pyo3::types::{
|
|||
PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess, PyTuple,
|
||||
PyTzInfo,
|
||||
};
|
||||
use pyo3::wrap_pyfunction;
|
||||
|
||||
#[pyfunction]
|
||||
fn make_date(py: Python, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> {
|
||||
fn make_date(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> {
|
||||
PyDate::new(py, year, month, day)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_date_tuple(py: Python, d: &PyDate) -> Py<PyTuple> {
|
||||
fn get_date_tuple(py: Python<'_>, d: &PyDate) -> Py<PyTuple> {
|
||||
PyTuple::new(
|
||||
py,
|
||||
&[d.get_year(), d.get_month() as i32, d.get_day() as i32],
|
||||
|
@ -18,13 +19,13 @@ fn get_date_tuple(py: Python, d: &PyDate) -> Py<PyTuple> {
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn date_from_timestamp(py: Python, timestamp: i64) -> PyResult<Py<PyDate>> {
|
||||
fn date_from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<Py<PyDate>> {
|
||||
PyDate::from_timestamp(py, timestamp)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_time(
|
||||
py: Python,
|
||||
py: Python<'_>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
|
@ -64,7 +65,7 @@ fn time_with_fold(
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_time_tuple(py: Python, dt: &PyTime) -> Py<PyTuple> {
|
||||
fn get_time_tuple(py: Python<'_>, dt: &PyTime) -> Py<PyTuple> {
|
||||
PyTuple::new(
|
||||
py,
|
||||
&[
|
||||
|
@ -92,12 +93,12 @@ fn get_time_tuple_fold(py: Python, dt: &PyTime) -> Py<PyTuple> {
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_delta(py: Python, days: i32, seconds: i32, microseconds: i32) -> PyResult<Py<PyDelta>> {
|
||||
fn make_delta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> PyResult<Py<PyDelta>> {
|
||||
PyDelta::new(py, days, seconds, microseconds, true)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_delta_tuple(py: Python, delta: &PyDelta) -> Py<PyTuple> {
|
||||
fn get_delta_tuple(py: Python<'_>, delta: &PyDelta) -> Py<PyTuple> {
|
||||
PyTuple::new(
|
||||
py,
|
||||
&[
|
||||
|
@ -110,7 +111,7 @@ fn get_delta_tuple(py: Python, delta: &PyDelta) -> Py<PyTuple> {
|
|||
|
||||
#[pyfunction]
|
||||
fn make_datetime(
|
||||
py: Python,
|
||||
py: Python<'_>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
|
@ -134,7 +135,7 @@ fn make_datetime(
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_datetime_tuple(py: Python, dt: &PyDateTime) -> Py<PyTuple> {
|
||||
fn get_datetime_tuple(py: Python<'_>, dt: &PyDateTime) -> Py<PyTuple> {
|
||||
PyTuple::new(
|
||||
py,
|
||||
&[
|
||||
|
@ -168,7 +169,11 @@ fn get_datetime_tuple_fold(py: Python, dt: &PyDateTime) -> Py<PyTuple> {
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn datetime_from_timestamp(py: Python, ts: f64, tz: Option<&PyTzInfo>) -> PyResult<Py<PyDateTime>> {
|
||||
fn datetime_from_timestamp(
|
||||
py: Python<'_>,
|
||||
ts: f64,
|
||||
tz: Option<&PyTzInfo>,
|
||||
) -> PyResult<Py<PyDateTime>> {
|
||||
PyDateTime::from_timestamp(py, ts, tz)
|
||||
}
|
||||
|
||||
|
@ -189,41 +194,41 @@ impl TzClass {
|
|||
obj.init(|| TzClass {})
|
||||
}
|
||||
|
||||
fn utcoffset(&self, py: Python, _dt: &PyDateTime) -> PyResult<Py<PyDelta>> {
|
||||
fn utcoffset(&self, py: Python<'_>, _dt: &PyDateTime) -> PyResult<Py<PyDelta>> {
|
||||
PyDelta::new(py, 0, 3600, 0, true)
|
||||
}
|
||||
|
||||
fn tzname(&self, _py: Python, _dt: &PyDateTime) -> PyResult<String> {
|
||||
fn tzname(&self, _py: Python<'_>, _dt: &PyDateTime) -> PyResult<String> {
|
||||
Ok(String::from("+01:00"))
|
||||
}
|
||||
|
||||
fn dst(&self, _py: Python, _dt: &PyDateTime) -> PyResult<Option<&PyDelta>> {
|
||||
fn dst(&self, _py: Python<'_>, _dt: &PyDateTime) -> PyResult<Option<&PyDelta>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_function!(make_date))?;
|
||||
m.add_wrapped(wrap_function!(get_date_tuple))?;
|
||||
m.add_wrapped(wrap_function!(date_from_timestamp))?;
|
||||
m.add_wrapped(wrap_function!(make_time))?;
|
||||
m.add_wrapped(wrap_function!(get_time_tuple))?;
|
||||
m.add_wrapped(wrap_function!(make_delta))?;
|
||||
m.add_wrapped(wrap_function!(get_delta_tuple))?;
|
||||
m.add_wrapped(wrap_function!(make_datetime))?;
|
||||
m.add_wrapped(wrap_function!(get_datetime_tuple))?;
|
||||
m.add_wrapped(wrap_function!(datetime_from_timestamp))?;
|
||||
fn datetime(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_pyfunction!(make_date))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_date_tuple))?;
|
||||
m.add_wrapped(wrap_pyfunction!(date_from_timestamp))?;
|
||||
m.add_wrapped(wrap_pyfunction!(make_time))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_time_tuple))?;
|
||||
m.add_wrapped(wrap_pyfunction!(make_delta))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_delta_tuple))?;
|
||||
m.add_wrapped(wrap_pyfunction!(make_datetime))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_datetime_tuple))?;
|
||||
m.add_wrapped(wrap_pyfunction!(datetime_from_timestamp))?;
|
||||
|
||||
// Python 3.6+ functions
|
||||
#[cfg(Py_3_6)]
|
||||
{
|
||||
m.add_wrapped(wrap_function!(time_with_fold))?;
|
||||
m.add_wrapped(wrap_function!(get_time_tuple_fold))?;
|
||||
m.add_wrapped(wrap_function!(get_datetime_tuple_fold))?;
|
||||
m.add_wrapped(wrap_pyfunction!(time_with_fold))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_time_tuple_fold))?;
|
||||
m.add_wrapped(wrap_pyfunction!(get_datetime_tuple_fold))?;
|
||||
}
|
||||
|
||||
m.add_wrapped(wrap_function!(issue_219))?;
|
||||
m.add_wrapped(wrap_pyfunction!(issue_219))?;
|
||||
|
||||
m.add_class::<TzClass>()?;
|
||||
Ok(())
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use pyo3::prelude::*;
|
||||
|
||||
use pyo3::exceptions::RuntimeError;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyDict;
|
||||
|
||||
#[pymodule]
|
||||
fn test_dict(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
fn test_dict(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_class::<DictSize>()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -21,7 +20,7 @@ impl DictSize {
|
|||
obj.init(|| DictSize { expected })
|
||||
}
|
||||
|
||||
fn iter_dict(&mut self, _py: Python, dict: &PyDict) -> PyResult<u32> {
|
||||
fn iter_dict(&mut self, _py: Python<'_>, dict: &PyDict) -> PyResult<u32> {
|
||||
let mut seen = 0u32;
|
||||
for (sym, values) in dict.iter() {
|
||||
seen += 1;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#![feature(specialization)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate pyo3;
|
||||
|
||||
pub mod datetime;
|
||||
pub mod dict_iter;
|
||||
pub mod othermod;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//! The code below just tries to use the most important code generation paths
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::wrap_pyfunction;
|
||||
|
||||
#[pyclass]
|
||||
pub struct ModClass {
|
||||
|
@ -29,8 +30,8 @@ fn double(x: i32) -> i32 {
|
|||
}
|
||||
|
||||
#[pymodule]
|
||||
fn othermod(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_function!(double))?;
|
||||
fn othermod(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_pyfunction!(double))?;
|
||||
m.add_class::<ModClass>()?;
|
||||
|
||||
m.add("USIZE_MIN", usize::min_value())?;
|
||||
|
|
|
@ -14,7 +14,7 @@ impl Subclassable {
|
|||
}
|
||||
|
||||
#[pymodule]
|
||||
fn subclassing(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
fn subclassing(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_class::<Subclassable>()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
authors = ["Messense Lv <messense@icloud.com>"]
|
||||
name = "word-count"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.0.2"
|
||||
|
|
|
@ -2,11 +2,8 @@
|
|||
// https://github.com/tildeio/helix-website/blob/master/crates/word_count/src/lib.rs
|
||||
#![feature(specialization)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate pyo3;
|
||||
extern crate rayon;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::wrap_pyfunction;
|
||||
use rayon::prelude::*;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
@ -27,7 +24,7 @@ impl WordCounter {
|
|||
}
|
||||
|
||||
/// Searches for the word, parallelized by rayon
|
||||
fn search(&self, py: Python, search: String) -> PyResult<usize> {
|
||||
fn search(&self, py: Python<'_>, search: String) -> PyResult<usize> {
|
||||
let contents = fs::read_to_string(&self.path)?;
|
||||
|
||||
let count = py.allow_threads(move || {
|
||||
|
@ -79,8 +76,8 @@ fn count_line(line: &str, needle: &str) -> usize {
|
|||
}
|
||||
|
||||
#[pymodule]
|
||||
fn word_count(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_function!(count_line))?;
|
||||
fn word_count(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
m.add_wrapped(wrap_pyfunction!(count_line))?;
|
||||
m.add_class::<WordCounter>()?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -6,7 +6,6 @@ To define python custom class, rust struct needs to be annotated with `#[pyclass
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
|
||||
#[pyclass]
|
||||
|
@ -45,7 +44,6 @@ attribute. Only the python `__new__` method can be specified, `__init__` is not
|
|||
```rust
|
||||
# #![feature(specialization)]
|
||||
#
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# use pyo3::PyRawObject;
|
||||
|
||||
|
@ -89,7 +87,6 @@ with value of custom class struct. Subclass must call parent's `__new__` method.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# use pyo3::PyRawObject;
|
||||
#[pyclass]
|
||||
|
@ -140,7 +137,6 @@ attributes. i.e.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -166,7 +162,6 @@ rust's special keywords like `type`.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -196,7 +191,6 @@ If parameter is specified, it is used and property name. i.e.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -225,7 +219,6 @@ For simple cases you can also define getters and setters in your Rust struct fie
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
#[pyclass]
|
||||
struct MyClass {
|
||||
|
@ -245,7 +238,6 @@ class method static methods, etc.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -274,7 +266,6 @@ get injected by method wrapper. i.e
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -299,7 +290,6 @@ with`#[classmethod]` attribute.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -332,7 +322,6 @@ for some `T` that implements `IntoPyObject`.
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -356,7 +345,6 @@ with `#[call]` attribute. Arguments of the method are specified same as for inst
|
|||
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# #[pyclass]
|
||||
# struct MyClass {
|
||||
|
@ -400,7 +388,6 @@ Each parameter could one of following type:
|
|||
Example:
|
||||
```rust
|
||||
# #![feature(specialization)]
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
#
|
||||
# #[pyclass]
|
||||
|
@ -429,7 +416,7 @@ with `#[pyproto]` attribute.
|
|||
|
||||
### Basic object customization
|
||||
|
||||
[`PyObjectProtocol`](https://docs.rs/pyo3/0.5.2/class/basic/trait.PyObjectProtocol.html) trait provide several basic customizations.
|
||||
[`PyObjectProtocol`](https://docs.rs/pyo3/0.6.0-alpha.2/class/basic/trait.PyObjectProtocol.html) trait provide several basic customizations.
|
||||
|
||||
#### Attribute access
|
||||
|
||||
|
@ -493,7 +480,7 @@ Each methods corresponds to python's `self.attr`, `self.attr = value` and `del s
|
|||
If your type owns references to other python objects, you will need to
|
||||
integrate with Python's garbage collector so that the GC is aware of
|
||||
those references.
|
||||
To do this, implement [`PyGCProtocol`](https://docs.rs/pyo3/0.5.2/class/gc/trait.PyGCProtocol.html) trait for your struct.
|
||||
To do this, implement [`PyGCProtocol`](https://docs.rs/pyo3/0.6.0-alpha.2/class/gc/trait.PyGCProtocol.html) trait for your struct.
|
||||
It includes two methods `__traverse__` and `__clear__`.
|
||||
These correspond to the slots `tp_traverse` and `tp_clear` in the Python C API.
|
||||
`__traverse__` must call `visit.call()` for each reference to another python object.
|
||||
|
@ -503,7 +490,6 @@ as every cycle must contain at least one mutable reference.
|
|||
Example:
|
||||
```rust
|
||||
#![feature(specialization)]
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
|
@ -540,7 +526,7 @@ collector, and it is possible to track them with `gc` module methods.
|
|||
### Iterator Types
|
||||
|
||||
Iterators can be defined using the
|
||||
[`PyIterProtocol`](https://docs.rs/pyo3/0.5.2/class/iter/trait.PyIterProtocol.html) trait.
|
||||
[`PyIterProtocol`](https://docs.rs/pyo3/0.6.0-alpha.2/class/iter/trait.PyIterProtocol.html) trait.
|
||||
It includes two methods `__iter__` and `__next__`:
|
||||
* `fn __iter__(&mut self) -> PyResult<impl IntoPyObject>`
|
||||
* `fn __next__(&mut self) -> PyResult<Option<impl IntoPyObject>>`
|
||||
|
@ -552,8 +538,6 @@ Example:
|
|||
```rust
|
||||
#![feature(specialization)]
|
||||
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
#[pyclass]
|
||||
|
|
|
@ -17,7 +17,6 @@ The easiest way to convert a python object to a rust value is using `.extract()?
|
|||
For example, [`IntoPyTuple`][IntoPyTuple] trait is implemented for `()` so that you can convert it into a empty [`PyTuple`][PyTuple]
|
||||
|
||||
```rust
|
||||
extern crate pyo3;
|
||||
use pyo3::{Python, IntoPyTuple};
|
||||
|
||||
fn main() {
|
||||
|
@ -43,16 +42,15 @@ Both methods accept `args` and `kwargs` arguments. `args` argument is generate o
|
|||
rust tuple with up to 10 elements. Or `NoArgs` object which represents empty tuple object.
|
||||
|
||||
```rust
|
||||
extern crate pyo3;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
# struct SomeObject;
|
||||
# impl SomeObject {
|
||||
# fn new(py: Python) -> PyObject {
|
||||
# pyo3::PyDict::new(py).to_object(py)
|
||||
# }
|
||||
# }
|
||||
#
|
||||
struct SomeObject;
|
||||
impl SomeObject {
|
||||
fn new(py: Python) -> PyObject {
|
||||
pyo3::PyDict::new(py).to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
# let arg1 = "arg1";
|
||||
# let arg2 = "arg2";
|
||||
|
@ -80,22 +78,23 @@ fn main() {
|
|||
[`IntoPyDict`][IntoPyDict] trait to convert other dict-like containers, e.g. `HashMap`, `BTreeMap` as well as tuples with up to 10 elements and `Vec`s where each element is a two element tuple.
|
||||
|
||||
```rust
|
||||
extern crate pyo3;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::{IntoPyDict, PyDict};
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct SomeObject;
|
||||
|
||||
impl SomeObject {
|
||||
fn new(py: Python) -> PyObject {
|
||||
PyDict::new(py).to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
# struct SomeObject;
|
||||
# impl SomeObject {
|
||||
# fn new(py: Python) -> PyObject {
|
||||
# pyo3::PyDict::new(py).to_object(py)
|
||||
# }
|
||||
# }
|
||||
fn main() {
|
||||
# let key1 = "key1";
|
||||
# let val1 = 1;
|
||||
# let key2 = "key2";
|
||||
# let val2 = 2;
|
||||
let key1 = "key1";
|
||||
let val1 = 1;
|
||||
let key2 = "key2";
|
||||
let val2 = 2;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -105,26 +104,25 @@ fn main() {
|
|||
// call object with PyDict
|
||||
let kwargs = PyDict::new(py);
|
||||
kwargs.set_item(key1, val1);
|
||||
obj.call(py, NoArgs, kwargs);
|
||||
obj.call(py, NoArgs, Some(kwargs));
|
||||
|
||||
// pass arguments as rust tuple
|
||||
let kwargs = ((key1, val1), (key2, val2));
|
||||
obj.call(py, NoArgs, kwargs);
|
||||
// pass arguments as Vec
|
||||
let kwargs = vec![(key1, val1), (key2, val2)];
|
||||
obj.call(py, NoArgs, 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, kwargs);
|
||||
obj.call(py, NoArgs, Some(kwargs.into_py_dict(py)));
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
TODO
|
||||
|
||||
[`ToPyObject`]: https://docs.rs/pyo3/0.5.2/trait.ToPyObject.html
|
||||
[IntoPyObject]: https://docs.rs/pyo3/0.5.2/trait.IntoPyObject.html
|
||||
[PyObject]: https://docs.rs/pyo3/0.5.2/struct.PyObject.html
|
||||
[IntoPyTuple]: https://docs.rs/pyo3/0.5.2/trait.IntoPyTuple.html
|
||||
[PyTuple]: https://docs.rs/pyo3/0.5.2/struct.PyTuple.html
|
||||
[ObjectProtocol]: https://docs.rs/pyo3/0.5.2/trait.ObjectProtocol.html
|
||||
[IntoPyDict]: https://docs.rs/pyo3/0.5.2/trait.IntoPyDict.html
|
||||
[`ToPyObject`]: https://docs.rs/pyo3/0.6.0-alpha.2/trait.ToPyObject.html
|
||||
[IntoPyObject]: https://docs.rs/pyo3/0.6.0-alpha.2/trait.IntoPyObject.html
|
||||
[PyObject]: https://docs.rs/pyo3/0.6.0-alpha.2/struct.PyObject.html
|
||||
[IntoPyTuple]: https://docs.rs/pyo3/0.6.0-alpha.2/trait.IntoPyTuple.html
|
||||
[PyTuple]: https://docs.rs/pyo3/0.6.0-alpha.2/struct.PyTuple.html
|
||||
[ObjectProtocol]: https://docs.rs/pyo3/0.6.0-alpha.2/trait.ObjectProtocol.html
|
||||
[IntoPyDict]: https://docs.rs/pyo3/0.6.0-alpha.2/trait.IntoPyDict.html
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
You can use the `create_exception!` macro to define a new exception type:
|
||||
|
||||
```rust
|
||||
#[macro_use] extern crate pyo3;
|
||||
use pyo3::import_exception;
|
||||
|
||||
create_exception!(module, MyError, pyo3::exceptions::Exception);
|
||||
```
|
||||
|
@ -16,9 +16,8 @@ create_exception!(module, MyError, pyo3::exceptions::Exception);
|
|||
For example:
|
||||
|
||||
```rust
|
||||
#[macro_use] extern crate pyo3;
|
||||
|
||||
use pyo3::Python;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::create_exception;
|
||||
use pyo3::types::PyDict;
|
||||
use pyo3::exceptions::Exception;
|
||||
|
||||
|
@ -41,8 +40,6 @@ fn main() {
|
|||
To raise an exception, first you need to obtain an exception type and construct a new [`PyErr`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html), then call [`PyErr::restore()`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html#method.restore) method to write the exception back to the Python interpreter's global state.
|
||||
|
||||
```rust
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::{Python, PyErr, exc};
|
||||
|
||||
fn main() {
|
||||
|
@ -66,7 +63,6 @@ has corresponding rust type, exceptions defined by `create_exception!` and `impo
|
|||
have rust type as well.
|
||||
|
||||
```rust
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# fn check_for_error() -> bool {false}
|
||||
fn my_func(arg: PyObject) -> PyResult<()> {
|
||||
|
@ -84,8 +80,6 @@ Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#is
|
|||
in `PyO3` there is a [`Python::is_instance()`](https://docs.rs/pyo3/0.2.7/struct.Python.html#method.is_instance) method which does the same thing.
|
||||
|
||||
```rust
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::{Python, PyBool, PyList};
|
||||
|
||||
fn main() {
|
||||
|
@ -103,7 +97,6 @@ fn main() {
|
|||
To check the type of an exception, you can simply do:
|
||||
|
||||
```rust
|
||||
# extern crate pyo3;
|
||||
# use pyo3::prelude::*;
|
||||
# fn main() {
|
||||
# let gil = Python::acquire_gil();
|
||||
|
@ -134,7 +127,6 @@ until `Python` object is available.
|
|||
|
||||
```rust,ignore
|
||||
#![feature(specialization)]
|
||||
extern crate pyo3;
|
||||
|
||||
use std::net::TcpListener;
|
||||
use pyo3::{PyErr, PyResult, exc};
|
||||
|
@ -157,7 +149,6 @@ The code snippet above will raise `OSError` in Python if `TcpListener::bind()` r
|
|||
types so `try!` macro or `?` operator can be used.
|
||||
|
||||
```rust
|
||||
# extern crate pyo3;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
fn parse_int(s: String) -> PyResult<usize> {
|
||||
|
@ -175,8 +166,8 @@ It is possible to use exception defined in python code as native rust types.
|
|||
for that exception.
|
||||
|
||||
```rust
|
||||
#[macro_use] extern crate pyo3;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::import_exception;
|
||||
|
||||
import_exception!(io, UnsupportedOperation);
|
||||
|
||||
|
|