Skip to content

Commit

Permalink
Draft: Inspect: module stubs entry point
Browse files Browse the repository at this point in the history
  • Loading branch information
Tpt committed Mar 11, 2024
1 parent a7fa1bd commit c1668bb
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -70,7 +70,7 @@ experimental-async = ["macros", "pyo3-macros/experimental-async"]

# Enables pyo3::inspect module and additional type information on FromPyObject
# and IntoPy traits
experimental-inspect = []
experimental-inspect = ["pyo3-macros/experimental-inspect"]

# Enables annotating Rust inline modules with #[pymodule] to build Python modules declaratively
experimental-declarative-modules = ["pyo3-macros/experimental-declarative-modules", "macros"]
Expand Down
1 change: 1 addition & 0 deletions pyo3-macros-backend/Cargo.toml
Expand Up @@ -29,3 +29,4 @@ workspace = true

[features]
experimental-async = []
experimental-inspect = []
29 changes: 25 additions & 4 deletions pyo3-macros-backend/src/module.rs
Expand Up @@ -242,12 +242,18 @@ pub fn pymodule_module_impl(mut module: syn::ItemMod) -> Result<TokenStream> {
}
}

let initialization = module_initialization(options, ident);
let initialization = module_initialization(&options, ident);
#[cfg(feature = "experimental-inspect")]
let type_stubs = module_type_stubs(&options, ident);
#[cfg(not(feature = "experimental-inspect"))]
let type_stubs = quote! {};

Ok(quote!(
#vis mod #ident {
#(#items)*

#initialization
#type_stubs

impl MakeDef {
const fn make_def() -> #pyo3_path::impl_::pymodule::ModuleDef {
Expand Down Expand Up @@ -288,7 +294,7 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result<TokenStream>
let vis = &function.vis;
let doc = get_doc(&function.attrs, None);

let initialization = module_initialization(options, ident);
let initialization = module_initialization(&options, ident);

// Module function called with optional Python<'_> marker as first arg, followed by the module.
let mut module_args = Vec::new();
Expand Down Expand Up @@ -356,8 +362,8 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result<TokenStream>
})
}

fn module_initialization(options: PyModuleOptions, ident: &syn::Ident) -> TokenStream {
let name = options.name.unwrap_or_else(|| ident.unraw());
fn module_initialization(options: &PyModuleOptions, ident: &syn::Ident) -> TokenStream {
let name = options.name.clone().unwrap_or_else(|| ident.unraw());
let ctx = &Ctx::new(&options.krate);
let Ctx { pyo3_path } = ctx;
let pyinit_symbol = format!("PyInit_{}", name);
Expand All @@ -382,6 +388,21 @@ fn module_initialization(options: PyModuleOptions, ident: &syn::Ident) -> TokenS
}
}

#[cfg(feature = "experimental-inspect")]
fn module_type_stubs(options: &PyModuleOptions, ident: &syn::Ident) -> TokenStream {
let name = options.name.clone().unwrap_or_else(|| ident.unraw());
let symbol = format!("__pyo3_stubs_{}", name);

quote! {
/// This autogenerated function is called by the python interpreter when importing
/// the module.
#[export_name = #symbol]
pub unsafe extern "C" fn __pyo3_type_stubs() -> *mut ::std::ffi::c_char {
::std::ffi::CString::new("Hello, world!").expect("Null bytes in auto-generated type stubs").into_raw()
}
}
}

/// Finds and takes care of the #[pyfn(...)] in `#[pymodule]`
fn process_functions_in_module(options: &PyModuleOptions, func: &mut syn::ItemFn) -> Result<()> {
let ctx = &Ctx::new(&options.krate);
Expand Down
1 change: 1 addition & 0 deletions pyo3-macros/Cargo.toml
Expand Up @@ -17,6 +17,7 @@ proc-macro = true
multiple-pymethods = []
experimental-async = ["pyo3-macros-backend/experimental-async"]
experimental-declarative-modules = []
experimental-inspect = ["pyo3-macros-backend/experimental-inspect"]

[dependencies]
proc-macro2 = { version = "1", default-features = false }
Expand Down

0 comments on commit c1668bb

Please sign in to comment.