Migrate to rust 2018

This commit is contained in:
konstin 2019-02-01 14:01:18 +01:00
parent 423b5d1099
commit 936f0153e8
73 changed files with 398 additions and 507 deletions

2
.gitignore vendored
View File

@ -14,7 +14,7 @@ dist/
.eggs/
venv*
guide/book/
examples/*/py
examples/*/py*
*.so
*.out

View File

@ -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

View File

@ -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 }

View File

@ -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(())
}

View File

@ -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) {

View File

@ -1,6 +1,3 @@
extern crate regex;
extern crate version_check;
use regex::Regex;
use std::collections::HashMap;
use std::convert::AsRef;

View File

@ -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

View File

@ -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]

View File

@ -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(())

View File

@ -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;

View File

@ -1,8 +1,5 @@
#![feature(specialization)]
#[macro_use]
extern crate pyo3;
pub mod datetime;
pub mod dict_iter;
pub mod othermod;

View File

@ -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())?;

View File

@ -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(())
}

View File

@ -2,6 +2,7 @@
authors = ["Messense Lv <messense@icloud.com>"]
name = "word-count"
version = "0.1.0"
edition = "2018"
[dependencies]
rayon = "1.0.2"

View File

@ -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(())

View File

@ -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]

View File

@ -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

View File

@ -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);

View File