pyo3 icon indicating copy to clipboard operation
pyo3 copied to clipboard

`PyInt` cannot be subclassed

Open ChayimFriedman2 opened this issue 1 year ago • 1 comments

Bug Description

PyInt does not implement PyClassBaseType, because it does not use pyobject_native_type!() but pyobject_native_type_core!(). As such, it cannot be subclassed.

Fixing this is not trivial because:

error[E0277]: the trait bound `pyo3_ffi::PyLongObject: PySizedLayout<types::num::PyInt>` is not satisfied
    --> src\types\mod.rs:200:33
     |
200  |             type LayoutAsBase = $crate::impl_::pycell::PyClassObjectBase<$layout>;
     |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PySizedLayout<types::num::PyInt>` is not implemented for `pyo3_ffi::PyLongObject`, which is required by `PyClassObjectBase<pyo3_ffi::PyLongObject>: PyClassObjectLayout<types::num::PyInt>`
     |
    ::: src\types\num.rs:17:1
     |
17   | pyobject_subclassable_native_type!(PyInt, ffi::PyLongObject);
     | ------------------------------------------------------------ in this macro invocation
     |
     = help: the following other types implement trait `PySizedLayout<T>`:
               <PyClassObject<T> as PySizedLayout<T>>
               <_PyWeakReference as PySizedLayout<PyWeakrefReference>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyArithmeticError>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyAssertionError>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyAttributeError>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyBaseException>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyBaseExceptionGroup>>
               <pyo3_ffi::PyBaseExceptionObject as PySizedLayout<PyBlockingIOError>>
             and 74 others
note: required for `PyClassObjectBase<pyo3_ffi::PyLongObject>` to implement `PyClassObjectLayout<types::num::PyInt>`
    --> src\pycell\impl_.rs:195:12
     |
195  | impl<T, U> PyClassObjectLayout<T> for PyClassObjectBase<U>
     |            ^^^^^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^^
196  | where
197  |     U: PySizedLayout<T>,
     |        ---------------- unsatisfied trait bound introduced here
note: required by a bound in `PyClassBaseType::LayoutAsBase`
    --> src\impl_\pyclass.rs:1131:24
     |
1131 |     type LayoutAsBase: PyClassObjectLayout<Self>;
     |                        ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `PyClassBaseType::LayoutAsBase`
     = note: this error originates in the macro `pyobject_subclassable_native_type` (in Nightly builds, run with -Z macro-backtrace for more info)

Steps to Reproduce

The following code:

use pyo3::prelude::*;
use pyo3::types::PyInt;

#[pyclass(extends=PyInt)]
pub struct IntSubClass {}

Triggers the error:

error[E0277]: the trait bound `PyInt: PyClass` is not satisfied
 --> src\lib.rs:4:1
  |
4 | #[pyclass(extends=PyInt)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyInt`, which is required by `PyInt: PyClassBaseType`
  |
  = help: the trait `PyClass` is implemented for `IntSubClass`
  = note: required for `PyInt` to implement `PyClassBaseType`
  = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info)

Backtrace

No response

Your operating system and version

Windows 11

Your Python version (python --version)

3.12

Your Rust version (rustc --version)

rustc 1.80.1 (3f5fd8dd4 2024-08-06)

Your PyO3 version

0.22.0

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

The official website.

Additional Info

Noticed while working on https://github.com/PyO3/pyo3/pull/4453.

ChayimFriedman2 avatar Aug 19 '24 13:08 ChayimFriedman2

See also #1647, I think int is a PyVarObject like tuple. If we were fixing this, I think it would also likely help with #1344.

davidhewitt avatar Aug 21 '24 07:08 davidhewitt