Some more documentation work
This commit is contained in:
parent
319afe1f76
commit
314a4a2b3e
|
@ -7,7 +7,7 @@
|
|||
* [User Guide](https://pyo3.github.io/pyo3/guide/)
|
||||
* [API Documentation](http://pyo3.github.io/pyo3/pyo3/)
|
||||
|
||||
A comparison with pyo3, the base for this project, can be found [in the guide](https://pyo3.github.io/pyo3/guide/rust-cpython.html).
|
||||
A comparison with rust-cpython can be found [in the guide](https://pyo3.github.io/pyo3/guide/rust-cpython.html).
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -80,8 +80,8 @@ use pyo3::py::modinit as pymodinit;
|
|||
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
||||
|
||||
#[pyfn(m, "sum_as_string")]
|
||||
// ``#[pyfn()]` converts the arguments from Python objects to Rust values and the Rust return
|
||||
// value back into a Python object.
|
||||
// ``#[pyfn()]` converts the arguments from Python objects to Rust values
|
||||
// and the Rust return value back into a Python object.
|
||||
fn sum_as_string_py(a:i64, b:i64) -> PyResult<String> {
|
||||
let out = sum_as_string(a, b);
|
||||
Ok(out)
|
||||
|
|
|
@ -14,13 +14,14 @@ fi
|
|||
|
||||
### Build API reference ########################################################
|
||||
|
||||
cargo doc --no-deps -p pyo3 -p pyo3cls
|
||||
cargo doc --no-deps -p pyo3 -p pyo3cls -p pyo3-derive-backend
|
||||
echo "<meta http-equiv=refresh content=0;url='guide/'>" > target/doc/index.html
|
||||
|
||||
|
||||
### Build guide ################################################################
|
||||
|
||||
mdbook build -d target/doc/guide guide
|
||||
# This builds the book in target/doc/guide. See https://github.com/rust-lang-nursery/mdBook/issues/698
|
||||
mdbook build -d ../target/doc/guide guide
|
||||
|
||||
git clone https://github.com/davisp/ghp-import.git
|
||||
./ghp-import/ghp_import.py -n -p -f -m "Documentation upload" -r https://"$GH_TOKEN"@github.com/"$TRAVIS_REPO_SLUG.git" target/doc
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# Summary
|
||||
|
||||
[Overview](./overview.md)
|
||||
|
||||
link-arg=-undefi- [Type Conversions](./conversions.md)
|
||||
- [Get Started](./overview.md)
|
||||
- [Type Conversions](./conversions.md)
|
||||
- [Python Exception](./exception.md)
|
||||
- [Python Module](./module.md)
|
||||
- [Python Function](./function.md)
|
||||
|
|
|
@ -1,26 +1,6 @@
|
|||
# Python Module
|
||||
|
||||
Python module generation is powered by unstable [Procedural Macros](https://doc.rust-lang.org/book/first-edition/procedural-macros.html) feature, so you need to turn on `proc_macro` feature:
|
||||
|
||||
```rust
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate pyo3;
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
You need to change your `crate-type` to `cdylib` to produce a Python compatible library:
|
||||
|
||||
```toml
|
||||
[lib]
|
||||
name = "rust2py"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
pyo3 = { version = "0.2", features = ["extension-module"] }
|
||||
```
|
||||
|
||||
Now you can write your module, for example
|
||||
As shown in the Getting Started chapter, you can create a module as follows:
|
||||
|
||||
```rust
|
||||
#![feature(proc_macro)]
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
# Overview
|
||||
# PyO3
|
||||
|
||||
[![Build Status](https://travis-ci.org/PyO3/pyo3.svg?branch=master)](https://travis-ci.org/PyO3/pyo3)
|
||||
[![Latest Version](https://img.shields.io/crates/v/pyo3.svg)](https://crates.io/crates/pyo3)
|
||||
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](http://pyo3.github.io/pyo3/pyo3/)
|
||||
|
||||
PyO3 is a [Rust](http://www.rust-lang.org/) bindings for the [Python](https://www.python.org/) interpreter.
|
||||
|
||||
Supported Python versions:
|
||||
|
||||
* Python2.7, Python 3.5 and up
|
||||
|
||||
Supported Rust version:
|
||||
|
||||
* Rust 1.20.0-nightly or later
|
||||
* On Windows, we require rustc 1.20.0-nightly
|
||||
[Rust](http://www.rust-lang.org/) bindings for the [Python](https://www.python.org/) interpreter. This includes running and interacting with python code from a rust binaries as well as writing native python modules.
|
||||
|
||||
## Usage
|
||||
|
||||
Pyo3 supports python 2.7 as well as python 3.5 and up. The minimum required rust version is 1.27.0-nightly 2018-05-01.
|
||||
|
||||
### From a rust binary
|
||||
|
||||
To use `pyo3`, add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
|
@ -31,12 +22,9 @@ extern crate pyo3;
|
|||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
fn main() {
|
||||
fn main() -> PyResult<()> {
|
||||
let gil = Python::acquire_gil();
|
||||
hello(gil.python()).unwrap();
|
||||
}
|
||||
|
||||
fn hello(py: Python) -> PyResult<()> {
|
||||
let py = gil.python();
|
||||
let sys = py.import("sys")?;
|
||||
let version: String = sys.get("version")?.extract()?;
|
||||
|
||||
|
@ -49,14 +37,12 @@ fn hello(py: Python) -> PyResult<()> {
|
|||
}
|
||||
```
|
||||
|
||||
Example library with python bindings:
|
||||
### As native module
|
||||
|
||||
The following two files will build with `cargo build`, and will generate a python-compatible library.
|
||||
For MacOS, `-C link-arg=-undefined -C link-arg=dynamic_lookup` is required to build the library.
|
||||
`setuptools-rust` includes this by default.
|
||||
See [examples/word-count](https://github.com/PyO3/pyo3/tree/master/examples/word-count).
|
||||
Also on macOS, you will need to rename the output from \*.dylib to \*.so.
|
||||
On Windows, you will need to rename the output from \*.dll to \*.pyd.
|
||||
Pyo3 can be used to write native python module. The example will generate a python-compatible library.
|
||||
|
||||
For MacOS, "-C link-arg=-undefined -C link-arg=dynamic_lookup" is required to build the library.
|
||||
`setuptools-rust` includes this by default. See [examples/word-count](examples/word-count) and the associated setup.py. Also on macOS, you will need to rename the output from \*.dylib to \*.so. On Windows, you will need to rename the output from \*.dll to \*.pyd.
|
||||
|
||||
**`Cargo.toml`:**
|
||||
|
||||
|
@ -80,17 +66,16 @@ use pyo3::prelude::*;
|
|||
|
||||
use pyo3::py::modinit as pymodinit;
|
||||
|
||||
// add bindings to the generated python module
|
||||
// Add bindings to the generated python module
|
||||
// N.B: names: "librust2py" must be the name of the `.so` or `.pyd` file
|
||||
/// This module is implemented in Rust.
|
||||
#[pymodinit(rust2py)]
|
||||
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
||||
|
||||
#[pyfn(m, "sum_as_string")]
|
||||
// pyo3 aware function. All of our python interface could be declared in a separate module.
|
||||
// Note that the `#[pyfn()]` annotation automatically converts the arguments from
|
||||
// Python objects to Rust values; and the Rust return value back into a Python object.
|
||||
fn sum_as_string_py(_py: Python, a:i64, b:i64) -> PyResult<String> {
|
||||
// ``#[pyfn()]` converts the arguments from Python objects to Rust values
|
||||
// and the Rust return value back into a Python object.
|
||||
fn sum_as_string_py(a:i64, b:i64) -> PyResult<String> {
|
||||
let out = sum_as_string(a, b);
|
||||
Ok(out)
|
||||
}
|
||||
|
@ -98,48 +83,11 @@ fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// logic implemented as a normal Rust function
|
||||
// The logic can be implemented as a normal rust function
|
||||
fn sum_as_string(a:i64, b:i64) -> String {
|
||||
format!("{}", a + b).to_string()
|
||||
}
|
||||
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
For `setup.py` integration, see [setuptools-rust](https://github.com/PyO3/setuptools-rust)
|
||||
|
||||
## Ownership and Lifetimes
|
||||
|
||||
In Python, all objects are implicitly reference counted.
|
||||
In Rust, we will use the [`PyObject`](https://pyo3.github.io/pyo3/pyo3/struct.PyObject.html) type
|
||||
to represent a reference to a Python object.
|
||||
|
||||
Because all Python objects potentially have multiple owners, the
|
||||
concept of Rust mutability does not apply to Python objects.
|
||||
As a result, this API will **allow mutating Python objects even if they are not stored
|
||||
in a mutable Rust variable**.
|
||||
|
||||
The Python interpreter uses a global interpreter lock (GIL) to ensure thread-safety.
|
||||
This API uses a zero-sized [`struct Python<'p>`](https://pyo3.github.io/pyo3/pyo3/struct.Python.html) as a token to indicate
|
||||
that a function can assume that the GIL is held.
|
||||
|
||||
You obtain a [`Python`](https://pyo3.github.io/pyo3/pyo3/struct.Python.html) instance
|
||||
by acquiring the GIL, and have to pass it into some operations that call into the Python runtime.
|
||||
|
||||
PyO3 library provides wrappers for python native objects. Ownership of python objects are
|
||||
disallowed because any access to python runtime has to be protected by GIL.
|
||||
All APIs are available through references. Lifetimes of python object's references are
|
||||
bound to GIL lifetime.
|
||||
|
||||
There are two types of pointers that could be stored on Rust structs.
|
||||
Both implements `Send` and `Sync` traits and maintain python object's reference count.
|
||||
|
||||
* [`PyObject`](https://pyo3.github.io/pyo3/pyo3/struct.PyObject.html) is general purpose
|
||||
type. It does not maintain type of the referenced object. It provides helper methods
|
||||
for extracting Rust values and casting to specific python object type.
|
||||
|
||||
* [`Py<T>`](https://pyo3.github.io/pyo3/pyo3/struct.Py.html) represents a reference to a
|
||||
concrete python object `T`.
|
||||
|
||||
To upgrade to a reference [`AsPyRef`](https://pyo3.github.io/pyo3/pyo3/trait.AsPyRef.html)
|
||||
trait can be used.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
//! This crate contains the implementation of the proc macro attributes
|
||||
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
//! Code generation for the function that initializes a python module and adds classes and function.
|
||||
|
||||
use args;
|
||||
use method;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
//! This crate declares only the proc macro attributes, as a crate defining proc macro attributes
|
||||
//! must not contain any other public items
|
||||
|
||||
#![recursion_limit = "1024"]
|
||||
#![feature(proc_macro)]
|
||||
|
|
|
@ -10,6 +10,7 @@ use python::{ToPyPointer, Python};
|
|||
use err::PyErr;
|
||||
use instance::{Py, PyObjectWithToken};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
|
||||
/// Represents a Python `float` object.
|
||||
///
|
||||
|
|
|
@ -31,7 +31,7 @@ pub use self::num3::PyLong as PyInt;
|
|||
pub use self::num2::{PyInt, PyLong};
|
||||
|
||||
|
||||
/// Implements typesafe conversions from a PyObjectRef, given a typecheck function as second
|
||||
/// Implements a typesafe conversions throught [FromPyObject], given a typecheck function as second
|
||||
/// parameter
|
||||
#[macro_export]
|
||||
macro_rules! pyobject_downcast(
|
||||
|
@ -178,6 +178,9 @@ macro_rules! pyobject_native_type_convert(
|
|||
};
|
||||
);
|
||||
|
||||
/// Implements [FromPyObject] and (currently deactivated until it's stabillized) a
|
||||
/// [TryFrom](std::convert::TryFrom) implementation, given a function body that performs the actual
|
||||
/// conversion
|
||||
#[macro_export]
|
||||
macro_rules! pyobject_extract(
|
||||
($obj:ident to $t:ty => $body: block) => {
|
||||
|
@ -185,9 +188,6 @@ macro_rules! pyobject_extract(
|
|||
{
|
||||
fn extract($obj: &'source $crate::PyObjectRef) -> $crate::PyResult<Self>
|
||||
{
|
||||
#[allow(unused_imports)]
|
||||
use objectprotocol::ObjectProtocol;
|
||||
|
||||
$body
|
||||
}
|
||||
}
|
||||
|
@ -199,9 +199,6 @@ macro_rules! pyobject_extract(
|
|||
|
||||
fn try_from($obj: &$crate::PyObjectRef) -> Result<Self, $crate::PyErr>
|
||||
{
|
||||
#[allow(unused_imports)]
|
||||
use $crate::ObjectProtocol;
|
||||
|
||||
$body
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ macro_rules! int_fits_larger_int(
|
|||
}
|
||||
}
|
||||
pyobject_extract!(obj to $rust_type => {
|
||||
let val = try!(obj.extract::<$larger_type>());
|
||||
let val = try!($crate::objectprotocol::ObjectProtocol::extract::<$larger_type>(obj));
|
||||
match cast::<$larger_type, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(exc::OverflowError.into())
|
||||
|
|
Loading…
Reference in New Issue