PyO3 / PyO3/pyo3

attribute set_all does not work on complex enums

Open
#4,939 7 comments 1 reaction 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

I can annotate a complex enum as #[pyclass(get_all, set_all)], but set_all does not work.
It should either work or be rejected during compilation.

Steps to Reproduce

To demonstrate the issue I wrote the following code:

use pyo3::prelude::*;

#[pyclass(get_all, set_all)]
#[derive(Debug, Clone)]
struct ItemValues {
    number: u8,
}

#[pymethods]
impl ItemValues {
    #[new]
    fn new(number: u8) -> Self {
        ItemValues { number }
    }

    fn __repr__(&self) -> String {
        format!("{:#?}", self)
    }
}

#[pyclass(get_all, set_all)]
#[derive(Debug, Clone)]
enum ComplexEnum {
    Item(ItemValues),
    OtherItem {
        value: usize,
    },
}

#[pymethods]
impl ComplexEnum {
    fn __repr__(&self) -> String {
        format!("{:#?}", self)
    }
}

#[pymodule]
fn pyo3_test(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_class::<ItemValues>()?;
    m.add_class::<ComplexEnum>()?;
    Ok(())
}

After building and installing the module, I tested it in the REPL:

>>> from pyo3_test import *
>>> enumval = ComplexEnum.Item(ItemValue(55))
>>> enumval
Item(
    ItemValues {
        number: 55,
    },
)
>>> enumval[0].number = 1
>>> enumval
Item(
    ItemValues {
        number: 55,
    },
)

In this first test we see that writing to the number did not raise an error, but had no effect.

Next I try to set the value of OtherItem:

>>> other = ComplexEnum.OtherItem(3)
>>> other
OtherItem {
    value: 3,
}
>>> other.value = 4
Traceback (most recent call last):
  File "<python-input-9>", line 1, in <module>
    other.value = 4
    ^^^^^^^^^^^
AttributeError: attribute 'value' of 'builtins.ComplexEnum_OtherItem' objects is not writable

This at least raises an error, which is better than discarding thewrite silently, but it is still unexpected considering the set_all attribute was accepted.

Backtrace

Your operating system and version

Windows 10

Your Python version (python --version)

Python 3.13.2

Your Rust version (rustc --version)

rustc 1.85.0

Your PyO3 version

0.23.4

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

Yes, I'm using a virtualenv

Additional Info

No response

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 provided Rust and Python example, then trace how #[pyclass(get_all, set_all)] handles the ComplexEnum variants and their fields. Done means set_all either updates nested and struct-like enum values correctly or rejects this combination during compilation, with coverage for both demonstrated cases.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.