1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#![feature(specialization, proc_macro, try_from, fn_must_use)]

//! Rust bindings to the Python interpreter.
//!
//! # Ownership and Lifetimes
//! In Python, all objects are implicitly reference counted.
//! In rust, we will use the `PyObject` 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>` as a token to indicate
//! that a function can assume that the GIL is held.
//!
//! You obtain a `Python` instance by acquiring the GIL,
//! and have to pass it into all operations that call into the Python runtime.
//!
//! # Error Handling
//! The vast majority of operations in this library will return `PyResult<...>`.
//! This is an alias for the type `Result<..., PyErr>`.
//!
//! A `PyErr` represents a Python exception. Errors within the `PyO3` library are
//! also exposed as Python exceptions.
//!
//! # Example
//!
//! ```rust
//! extern crate pyo3;
//!
//! use pyo3::{Python, PyDict, PyResult, ObjectProtocol};
//!
//! fn main() {
//!     let gil = Python::acquire_gil();
//!     hello(gil.python()).unwrap();
//! }
//!
//! fn hello(py: Python) -> PyResult<()> {
//!     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()?;
//!
//!     println!("Hello {}, I'm Python {}", user, version);
//!     Ok(())
//! }
//! ```
//!
//! # Python extension
//!
//! To allow Python to load the rust code as a Python extension
//! module, you need provide initialization function and annotate it with `#[pymodinit(name)]`.
//! `pymodinit` expands to an `extern "C"` function.
//!
//! Macro syntax: `#[pymodinit(name)]`
//!
//! 1. `name`: The module name as a Rust identifier
//! 2. Decorate init function `Fn(Python, &PyModule) -> PyResult<()>`.
//!    This function will be called when the module is imported, and is responsible
//!    for adding the module's members.
//!
//! To creates a Python callable object that invokes a Rust function, specify rust
//! function and decorate it with `#[pyfn()]` attribute. `pyfn()` accepts three parameters.
//!
//! 1. `m`: The module name.
//! 2. name of function visible to Python code.
//! 3. comma separated arguments, i.e. param="None", "*", param3="55"
//!
//!
//! # Example
//!
//! ```rust
//! #![feature(proc_macro, specialization)]
//!
//! extern crate pyo3;
//! use pyo3::{py, Python, PyResult, PyModule, PyString};
//!
//! use pyo3::py::modinit as pymodinit;
//!
//! // add bindings to the generated python module
//! // N.B: names: "libhello" must be the name of the `.so` or `.pyd` file
//!
//! /// Module documentation string
//! #[pymodinit(hello)]
//! fn init_module(py: Python, m: &PyModule) -> PyResult<()> {
//!
//!     // 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.
//!     #[pyfn(m, "run_rust_func")]
//!     fn run(name: &PyString) -> PyResult<()> {
//!         println!("Rust says: Hello {} of Python!", name);
//!         Ok(())
//!     }
//!
//!     Ok(())
//! }
//!
//! # fn main() {}
//! ```
//!
//! In your `Cargo.toml`, use the `extension-module` feature for the `pyo3` dependency:
//!
//! ```cargo
//! [dependencies.pyo3]
//! version = "*"
//! features = ["extension-module"]
//! ```
//!
//! The full example project can be found at:
//!   <https://github.com/PyO3/setuptools-rust/tree/master/example/>
//!
//! Rust will compile the code into a file named `libhello.so`, but we have to
//! rename the file in order to use it with Python:
//!
//! ```bash
//! cp ./target/debug/libhello.so ./hello.so
//! ```
//!
//! (Note: on macOS you will have to rename `libhello.dynlib` to `libhello.so`. 
//! To build on macOS, use `-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).)
//!
//! The extension module can then be imported into Python:
//!
//! ```python,ignore
//! >>> import hello
//! >>> hello.run_rust_func("test")
//! Rust says: Hello Python!
//! ```

extern crate libc;
extern crate spin;
extern crate pyo3cls;
#[macro_use] extern crate log;

#[cfg(not(Py_3))]
mod ffi2;

#[cfg(Py_3)]
mod ffi3;

/// Rust FFI declarations for Python
pub mod ffi {
    #[cfg(not(Py_3))]
    pub use ffi2::*;

    #[cfg(Py_3)]
    pub use ffi3::*;
}

pub use err::{PyErr, PyErrValue, PyResult, PyDowncastError, PyErrArguments};
pub use objects::*;
pub use objectprotocol::ObjectProtocol;
pub use object::PyObject;
pub use noargs::NoArgs;
pub use typeob::{PyTypeInfo, PyRawObject, PyObjectAlloc};
pub use python::{Python, ToPyPointer, IntoPyPointer, IntoPyDictPointer};
pub use pythonrun::{GILGuard, GILPool, prepare_freethreaded_python, prepare_pyo3_library};
pub use instance::{PyToken, PyObjectWithToken, AsPyRef, Py, PyNativeType};
pub use conversion::{FromPyObject, PyTryFrom, PyTryInto,
                     ToPyObject, ToBorrowedObject, IntoPyObject, IntoPyTuple};
pub mod class;
pub use class::*;

/// Procedural macros
pub mod py {
    pub use pyo3cls::{proto, class, methods};

    #[cfg(Py_3)]
    pub use pyo3cls::mod3init as modinit;

    #[cfg(not(Py_3))]
    pub use pyo3cls::mod2init as modinit;
}

/// Constructs a `&'static CStr` literal.
macro_rules! cstr(
    ($s: tt) => (
        // TODO: verify that $s is a string literal without nuls
        unsafe {
            ::std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr() as *const _)
        }
    );
);

mod python;
mod err;
mod conversion;
mod instance;
mod object;
mod objects;
mod objectprotocol;
mod noargs;
mod pythonrun;
#[doc(hidden)]
pub mod callback;
pub mod typeob;
#[doc(hidden)]
pub mod argparse;
pub mod buffer;
pub mod freelist;
pub mod prelude;

// re-export for simplicity
#[doc(hidden)]
pub use std::os::raw::*;