PyO3 / PyO3/pyo3

Subclass defined in Python does not run `__init__` if `new` returns `PyResult<Py<Self>>`

Open
#5,004 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
16.2k
Forks
1k
Avg merge
2d 6h
Merged PRs (30d)
66

Description

Bug Description

When a pyclass's new function returns PyResult<Py<Self>>, subclasses defined in python do not run their __init__ functions.

Steps to Reproduce

Write the base class in rust:

#[pyclass(subclass)]
struct BaseClass;

#[pymethods]
impl BaseClass {
    #[new]
    fn py_new(py: Python) -> PyResult<Py<Self>> {
        Ok(Bound::new(py, Self)?.unbind())
    }
}

#[pymodule]
fn some_module(m: &Bound<PyModule>) -> PyResult<()> {
    m.add_class::<BaseClass>()?;

    Ok(())
}

Write a subclass in python:

from some_module import BaseClass


class SubClass(BaseClass):
    def __new__(cls, *args):
        return super().__new__(cls)

    def __init__(self):
        print("in init") 


obj = SubClass()
Backtrace

Your operating system and version

Debian 12

Your Python version (python --version)

Python 3.12.9

Your Rust version (rustc --version)

rustc 1.85.0 (4d91de4e4 2025-02-17)

Your PyO3 version

0.24.0

How did you install python? Did you use a virtualenv?

pyenv

Additional Info

I am not sure if this is related, but if I add print(type(obj)) to the end of the python code, it says that it's an instance of BaseClass not SubClass.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example with the Rust #[new] method returning PyResult<Py> and the Python-defined subclass. Trace PyO3's handling of subclass construction and verify that the resulting object keeps the Python subclass type and runs its init method.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.