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
//! Store of metadata for generating Python stub file
//!
//! Stub file generation takes two steps:
//!
//! Store metadata (compile time)
//! ------------------------------
//! Embed compile-time information about Rust types and PyO3 macro arguments
//! using [inventory::submit!](https://docs.rs/inventory/latest/inventory/macro.submit.html) macro into source codes,
//! and these information will be gathered by [inventory::iter](https://docs.rs/inventory/latest/inventory/struct.iter.html).
//! This submodule is responsible for this process.
//!
//! - [PyClassInfo] stores information obtained from `#[pyclass]` macro
//! - [PyMethodsInfo] stores information obtained from `#[pymethods]` macro
//!
//! and others are their components.
//!
//! Gathering metadata and generating stub file (runtime)
//! -------------------------------------------------------
//! Since `#[pyclass]` and `#[pymethods]` definitions are not bundled in a single block,
//! we have to reconstruct these information corresponding to a Python `class`.
//! This process is done at runtime in [gen_stub](../../gen_stub) executable.
//!
use crate::{PyStubType, TypeInfo};
use std::any::TypeId;
/// Work around for `CompareOp` for `__richcmp__` argument,
/// which does not implements `FromPyObject`
pub fn compare_op_type_input() -> TypeInfo {
<isize as PyStubType>::type_input()
}
pub fn no_return_type_output() -> TypeInfo {
TypeInfo::none()
}
/// Info of method argument appears in `#[pymethods]`
#[derive(Debug)]
pub struct ArgInfo {
pub name: &'static str,
pub r#type: fn() -> TypeInfo,
}
/// Info of usual method appears in `#[pymethod]`
#[derive(Debug)]
pub struct MethodInfo {
pub name: &'static str,
pub args: &'static [ArgInfo],
pub r#return: fn() -> TypeInfo,
pub signature: Option<&'static str>,
pub doc: &'static str,
pub is_static: bool,
pub is_class: bool,
}
/// Info of getter method decorated with `#[getter]` or `#[pyo3(get, set)]` appears in `#[pyclass]`
#[derive(Debug)]
pub struct MemberInfo {
pub name: &'static str,
pub r#type: fn() -> TypeInfo,
}
/// Info of `#[new]`-attributed methods appears in `#[pymethods]`
#[derive(Debug)]
pub struct NewInfo {
pub args: &'static [ArgInfo],
pub signature: Option<&'static str>,
}
/// Info of `#[pymethod]`
#[derive(Debug)]
pub struct PyMethodsInfo {
// The Rust struct type-id of `impl` block where `#[pymethod]` acts on
pub struct_id: fn() -> TypeId,
/// Method specified `#[new]` attribute
pub new: Option<NewInfo>,
/// Methods decorated with `#[getter]`
pub getters: &'static [MemberInfo],
/// Other usual methods
pub methods: &'static [MethodInfo],
}
inventory::collect!(PyMethodsInfo);
/// Info of `#[pyclass]` with Rust struct
#[derive(Debug)]
pub struct PyClassInfo {
// Rust struct type-id
pub struct_id: fn() -> TypeId,
// The name exposed to Python
pub pyclass_name: &'static str,
/// Module name specified by `#[pyclass(module = "foo.bar")]`
pub module: Option<&'static str>,
/// Docstring
pub doc: &'static str,
/// static members by `#[pyo3(get, set)]`
pub members: &'static [MemberInfo],
}
inventory::collect!(PyClassInfo);
/// Info of `#[pyclass]` with Rust enum
#[derive(Debug)]
pub struct PyEnumInfo {
// Rust struct type-id
pub enum_id: fn() -> TypeId,
// The name exposed to Python
pub pyclass_name: &'static str,
/// Module name specified by `#[pyclass(module = "foo.bar")]`
pub module: Option<&'static str>,
/// Docstring
pub doc: &'static str,
/// Variants of enum
pub variants: &'static [&'static str],
}
inventory::collect!(PyEnumInfo);
/// Info of `#[pyfunction]`
#[derive(Debug)]
pub struct PyFunctionInfo {
pub name: &'static str,
pub args: &'static [ArgInfo],
pub r#return: fn() -> TypeInfo,
pub doc: &'static str,
pub signature: Option<&'static str>,
pub module: Option<&'static str>,
}
inventory::collect!(PyFunctionInfo);
#[derive(Debug)]
pub struct PyErrorInfo {
pub name: &'static str,
pub module: &'static str,
pub base: fn() -> &'static str,
}
inventory::collect!(PyErrorInfo);
#[derive(Debug)]
pub struct PyVariableInfo {
pub name: &'static str,
pub module: &'static str,
pub r#type: fn() -> TypeInfo,
}
inventory::collect!(PyVariableInfo);