[Stubs] Inner classes extending outer for data-carrying enums
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.2k
- Forks
- 1k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 66
Description
Bug Description
Hi all!
I have the following enum in my Rust code:
/// An expectation instead of what was found
#[pyclass(eq, from_py_object, module = "scarf_python")]
#[derive(Clone, PartialEq, Eq)]
pub enum Expectation {
/// A specific token
Token { token: Token },
/// A verbose human-readable label
Label { label: String },
/// The end of a file
EOI(),
}
When I attempt to generate stubs for this, I get the following:
class Expectation:
"""
An expectation instead of what was found
"""
def __eq__(self, /, other: object) -> bool: ...
def __ne__(self, /, other: object) -> bool: ...
@final
class EOI(Expectation):
"""
The end of a file
"""
__match_args__: Final = ()
def __getitem__(self, /, key: int) -> Any: ...
def __len__(self, /) -> int: ...
def __new__(cls, /) -> Expectation.EOI: ...
@final
class Label(Expectation):
"""
A verbose human-readable label
"""
__match_args__: Final = ("label",)
def __new__(cls, /, label: str) -> Expectation.Label: ...
@property
def label(self, /) -> str: ...
@final
class Token(Expectation):
"""
A specific token
"""
__match_args__: Final = ("token",)
def __new__(cls, /, token: Token) -> Expectation.Token: ...
@property
def token(self, /) -> Token: ...
In Python, inner classes cannot extend outer classes, as the outer isn't fully elaborated by the time the inner is encountered. The easiest way to see this is trying to run python on the following:
class Outer:
class Inner(Outer):
pass
My proposed fix for the above would just be to avoid nesting the inner classes; since they already extend the parent, they already have access to all methods/attributes/etc. The simplest change that I believe would fix this would be to remove the replace call here. However, I don't know what other changes I'd need to make to the actual generated code, beyond the stubs.
I believe similar issues would be present when generating stubs for any data-carrying enums.
Steps to Reproduce
My particular steps to encounter this involved trying to document the generated stubs (above) with sphinx-autodoc2; can provide issues to reproduce if needed (may be convoluted :), but I believe the issue is already identified
Backtrace
Your operating system and version
MacOS Monterey (12.6.5)
Your Python version (python --version)
Python 3.14.2
Your Rust version (rustc --version)
rustc 1.93.1 (01f6ddf75 2026-02-11)
Your PyO3 version
0.29.0
How did you install python? Did you use a virtualenv?
virtualenv
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
Start by reading pyo3-introspection/src/stubs.rs around the linked replace call and reproduce the nested-class output with the shown Expectation enum. Verify the generated stubs are valid Python and that data-carrying enums no longer produce inner classes extending an incompletely defined outer class.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100