create_interface macro example from documentation does not produce usable classes when used inside pymodule
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.2k
- Forks
- 1k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 66
Description
Bug Description
The documentation includes an example macro showing how to work around restrictions on generic using macros. However, when building modules using this macro, the classes defined inside the macro are not available to be imported.
Steps to Reproduce
- Create a new project with
maturin init macro-reproducer - Make lib.rs look like this:
use pyo3::prelude::*;
#[pymodule]
mod macro_reproducer {
use pyo3::prelude::*;
struct GenericClass<T> {
data: T,
}
macro_rules! create_interface {
($name: ident, $type: ident) => {
#[pyclass]
pub struct $name {
inner: GenericClass<$type>,
}
#[pymethods]
impl $name {
#[new]
pub fn new(data: $type) -> Self {
Self {
inner: GenericClass { data: data },
}
}
}
};
}
create_interface!(IntClass, i64);
create_interface!(FloatClass, f64);
#[pyclass]
pub struct StringClass {
inner: GenericClass<String>,
}
#[pymethods]
impl StringClass {
#[new]
pub fn new(data: String) -> Self {
Self {
inner: GenericClass { data: data },
}
}
}
}
- Create a test:
def test_string_class():
from macro_reproducer import StringClass
s = StringClass("Hello, World!")
def test_int_class():
from macro_reproducer import IntClass
i = IntClass(42)
def test_float_class():
from macro_reproducer import FloatClass
f = FloatClass(3.14)
- Run test with
pytest test.py - IntClass and FloatClass tests fail with
ImportError: cannot import name 'IntClass' from 'macro_reproducer'. Test for non-macro-coded StringClass passes
Backtrace
Your operating system and version
Ubuntu Linux 24.04
Your Python version (python --version)
Python 3.14.4
Your Rust version (rustc --version)
rustc 1.94.1 (e408947bf 2026-03-25)
Your PyO3 version
0.28.2
How did you install python? Did you use a virtualenv?
apt installed from deadsnakes, but issue is reproducible with uv installed Python too
Additional Info
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the problem in the shown lib.rs and test.py files, then run pytest test.py to confirm that StringClass imports while the macro-generated classes do not. Start by tracing how PyO3's #[pymodule], #[pyclass], and #[pymethods] macros handle items generated by create_interface!. Done means IntClass and FloatClass can be imported and constructed like StringClass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100