Some more documentation work

This commit is contained in:
konstin 2018-05-19 17:27:26 +02:00
parent 319afe1f76
commit 314a4a2b3e
11 changed files with 37 additions and 107 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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