#![cfg_attr(feature="nightly", allow(incomplete_features))]
#![cfg_attr(feature="nightly", feature(
specialization, // for impl FromPyObject<'s> for Vec<...> (#31844)
))]
#![allow(
unused_imports, // because some imports are only necessary with python 2.x or 3.x
clippy::missing_safety_doc,
clippy::manual_strip,
clippy::match_like_matches_macro
)]
use std::{mem, ptr};
#[cfg(feature = "python27-sys")]
pub(crate) use python27_sys as ffi;
#[cfg(feature = "python3-sys")]
pub(crate) use python3_sys as ffi;
pub use ffi::Py_ssize_t;
pub use crate::conversion::{FromPyObject, RefFromPyObject, ToPyObject};
pub use crate::err::{PyErr, PyResult};
pub use crate::objectprotocol::{ObjectProtocol, NumberProtocol};
pub use crate::objects::*;
pub use crate::py_class::CompareOp;
pub use crate::python::{
PyClone, PyDrop, Python, PythonObject, PythonObjectDowncastError,
PythonObjectWithCheckedDowncast, PythonObjectWithTypeObject,
};
pub use crate::pythonrun::{prepare_freethreaded_python, GILGuard, GILProtected};
pub use crate::sharedref::{
PyLeakedRef, PyLeakedRefMut, PySharedRef, PySharedRefCell, UnsafePyLeaked,
};
#[cfg(feature = "python27-sys")]
#[allow(non_camel_case_types)]
pub type Py_hash_t = libc::c_long;
#[cfg(feature = "python3-sys")]
#[allow(non_camel_case_types)]
pub type Py_hash_t = ffi::Py_hash_t;
macro_rules! cstr(
($s: tt) => (
unsafe {
std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr() as *const _)
}
);
);
#[macro_export]
#[doc(hidden)]
macro_rules! py_coerce_expr {
($s:expr) => {
$s
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_coerce_item {
($s:item) => {
$s
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_replace_expr {
($_t:tt $sub:expr) => {
$sub
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_impl_to_py_object_for_python_object {
($T: ty) => {
impl $crate::ToPyObject for $T {
type ObjectType = $T;
#[inline]
fn to_py_object(&self, py: $crate::Python) -> $T {
$crate::PyClone::clone_ref(self, py)
}
#[inline]
fn into_py_object(self, _py: $crate::Python) -> $T {
self
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, _py: $crate::Python, f: F) -> R
where
F: FnOnce(*mut $crate::_detail::ffi::PyObject) -> R,
{
f($crate::PythonObject::as_object(self).as_ptr())
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_impl_from_py_object_for_python_object {
($T:ty) => {
impl<'s> $crate::FromPyObject<'s> for $T {
#[inline]
fn extract(py: $crate::Python, obj: &'s $crate::PyObject) -> $crate::PyResult<$T> {
use $crate::PyClone;
Ok(obj.clone_ref(py).cast_into::<$T>(py)?)
}
}
impl<'s> $crate::FromPyObject<'s> for &'s $T {
#[inline]
fn extract(py: $crate::Python, obj: &'s $crate::PyObject) -> $crate::PyResult<&'s $T> {
Ok(obj.cast_as::<$T>(py)?)
}
}
};
}
pub mod argparse;
pub mod buffer;
mod conversion;
mod err;
mod function;
mod objectprotocol;
mod objects;
mod python;
mod pythonrun;
pub mod py_class;
mod sharedref;
#[cfg(feature = "serde-convert")]
pub mod serde;
#[doc(hidden)]
pub mod _detail {
pub mod ffi {
pub use crate::ffi::*;
}
pub mod libc {
pub use libc::{c_char, c_int, c_void};
}
pub use crate::err::{from_owned_ptr_or_panic, result_from_owned_ptr};
pub use crate::function::{
handle_callback, py_fn_impl, AbortOnDrop, PyObjectCallbackConverter,
PythonObjectCallbackConverter,
};
pub use paste;
pub use std::result::Result;
}
#[macro_export]
#[cfg(feature = "python27-sys")]
macro_rules! py_module_initializer {
($name: ident, $( $_py2: ident, $_py3: ident, )? |$py_id: ident, $m_id: ident| $body: tt) => {
$crate::_detail::paste::item! {
#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "C" fn [< init $name >]() {
fn init($py_id: $crate::Python, $m_id: &$crate::PyModule) -> $crate::PyResult<()> {
$body
}
let name = concat!(stringify!($name), "\0").as_ptr() as *const _;
$crate::py_module_initializer_impl(name, init)
}
}
};
}
#[doc(hidden)]
#[cfg(feature = "python27-sys")]
pub unsafe fn py_module_initializer_impl(
name: *const libc::c_char,
init: fn(Python, &PyModule) -> PyResult<()>,
) {
let guard = function::AbortOnDrop("py_module_initializer");
let py = Python::assume_gil_acquired();
ffi::PyEval_InitThreads();
let module = ffi::Py_InitModule(name, ptr::null_mut());
if module.is_null() {
mem::forget(guard);
return;
}
let module = match PyObject::from_borrowed_ptr(py, module).cast_into::<PyModule>(py) {
Ok(m) => m,
Err(e) => {
PyErr::from(e).restore(py);
mem::forget(guard);
return;
}
};
let ret = match init(py, &module) {
Ok(()) => (),
Err(e) => e.restore(py),
};
mem::forget(guard);
ret
}
#[macro_export]
#[cfg(feature = "python3-sys")]
macro_rules! py_module_initializer {
($name: ident, $( $_py2: ident, $_py3: ident, )? |$py_id: ident, $m_id: ident| $body: tt) => {
$crate::_detail::paste::item! {
#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "C" fn [< PyInit_ $name >]() -> *mut $crate::_detail::ffi::PyObject {
fn init($py_id: $crate::Python, $m_id: &$crate::PyModule) -> $crate::PyResult<()> {
$body
}
static mut MODULE_DEF: $crate::_detail::ffi::PyModuleDef =
$crate::_detail::ffi::PyModuleDef_INIT;
MODULE_DEF.m_name = concat!(stringify!($name), "\0").as_ptr() as *const _;
$crate::py_module_initializer_impl(&mut MODULE_DEF, init)
}
}
};
}
#[doc(hidden)]
#[cfg(feature = "python3-sys")]
pub unsafe fn py_module_initializer_impl(
def: *mut ffi::PyModuleDef,
init: fn(Python, &PyModule) -> PyResult<()>,
) -> *mut ffi::PyObject {
let guard = function::AbortOnDrop("py_module_initializer");
let py = Python::assume_gil_acquired();
ffi::PyEval_InitThreads();
let module = ffi::PyModule_Create(def);
if module.is_null() {
mem::forget(guard);
return module;
}
let module = match PyObject::from_owned_ptr(py, module).cast_into::<PyModule>(py) {
Ok(m) => m,
Err(e) => {
PyErr::from(e).restore(py);
mem::forget(guard);
return ptr::null_mut();
}
};
let ret = match init(py, &module) {
Ok(()) => module.into_object().steal_ptr(),
Err(e) => {
e.restore(py);
ptr::null_mut()
}
};
mem::forget(guard);
ret
}
#[macro_export]
#[doc(hidden)]
macro_rules! strip_raw {
($s:expr) => {{
let s = $s;
if s.starts_with("r#") {
&s[2..]
} else {
s
}
}};
}