PyO3 / PyO3/pyo3

Overriding base class constructor when subclassing builtins

Open
#4,443 12 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

It appears there is no way to override the arguments to the base class constructor when subclassing builtin types. It will always be passed the same arguments as #[new].

For example:

use pyo3::prelude::*;
use pyo3::types::PyDict;

#[pyclass(extends=PyDict)]
pub struct PyDefaultDict {
    x: i32,
}

#[pymethods]
impl PyDefaultDict {
    #[new]
    #[pyo3(signature = (x, *_args, **_kwargs))]
    fn new(
        x: i32,
        _args: &Bound<'_, PyAny>,
        _kwargs: Option<&Bound<'_, PyAny>>,
    ) -> Self {
        Self { x }
    }

    fn get_x(&self) -> i32 {
        self.x
    }
}

In Python:

from my_module import PyDefaultDict
PyDefaultDict(42)

# Errors with:
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable

PyClassInitializer doesn't allow that either.

Originally asked on Stack Overflow: https://stackoverflow.com/q/78873598/7884305.

I'm willing to work on this, if I get input on the API.

I envision an API similar to:

impl<S: PyClass> PyClassInitializer<S> {
    fn from_native<B>(subclass: S, native: Py<B>) -> Self
    where
        S: PyClass<BaseType = B>,
        B: PyClassBaseType<Initializer = PyNativeTypeInitializer<B>>,
}

I don't know if it is actually possible (I don't know enough the Python C API).

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

The issue names no files or tests; start by reading PyClassInitializer and the #[new] behavior for classes extending builtin types. Check the relevant Python C API constraints before evaluating the proposed from_native API. Done means an agreed, feasible API design with coverage for overriding builtin constructor arguments.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.