Skip to content

Comments

docs: Improves IntoPyObject documentation in the guides#5835

Open
Cheukting wants to merge 12 commits intoPyO3:mainfrom
Cheukting:doc-5709
Open

docs: Improves IntoPyObject documentation in the guides#5835
Cheukting wants to merge 12 commits intoPyO3:mainfrom
Cheukting:doc-5709

Conversation

@Cheukting
Copy link
Contributor

closes #5709

@Cheukting Cheukting changed the title docs: Improves IntoPyObject documentation in the guides [WIP] docs: Improves IntoPyObject documentation in the guides Feb 22, 2026
Copy link
Member

@Icxolu Icxolu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this! I spotted a few things and left comments below.

Comment on lines 697 to 698
You can also use `#[pyo3(from_item_all)]` on a struct to convert every field to be used with `get_item` method.
In this case, you don't need to use `#[pyo3(item)]` on each field.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from_item_all has no functionality for IntoPyObject since it exclusively uses set_item. It is just accepted for compatibility with FromPyObject. (Same is true for for other attributes as well, for example attribute or default)

For `enum`s each variant is converted according to the rules for `struct`s above.

```rust,no_run
```rust
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only makes sense to run these if there is main which does something, otherwise it is better to leave these as no_run for a faster test suite.

Comment on lines 880 to 887
- `pyo3(default)`, `pyo3(default = ...)`
- if the argument is set, uses the given default value.
- in this case, the argument must be a Rust expression returning a value of the desired Rust type.
- if the argument is not set, [`Default::default`](https://doc.rust-lang.org/std/default/trait.Default.html#tymethod.default) is used.
- note that the default value is only used if the field is not set.
If the field is set and the conversion function from Rust to Python fails, an exception is raised and the default value is not used.
- this attribute is only supported on named fields.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one has no effect for IntoPyObject and we should not document it.


#### `#[derive(IntoPyObject)]`/`#[derive(IntoPyObjectRef)]` Field Attributes

- `pyo3(item)`, `pyo3(item("key"))`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pyo3(item) is actually the default and only pyo3(item("key")) has the effect to use a different key

…er field attributes in `IntoPyObject` traits.
@Cheukting
Copy link
Contributor Author

It is updated considering all your feedback and suggestions @Icxolu please feel free to check again

- fields with an explicit renaming via `attribute(...)`/`item(...)` are not affected
- `#[pyo3(from_item_all)]`
- extract every field with `get_item` method.
- can't use `#[pyo3(attribute)]` or barely use `#[pyo3(item)]` on any field after.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not quite sure what you mean here

struct RustyStruct {
#[pyo3(item("key"))]
string_in_mapping: String,
#[pyo3(attribute("name"))] // no effect on this field
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this has no effect here, I would not put it in an example. I think this is just confusing to people. What I think we can do is to write a sentence somewhere that FromPyObject and IntoPyObject for convenience (technical) reasons accept each other arguments, but that not all of them are supported by both of them equally, then linking to the sections with the list of supported attributes of each.


- `pyo3(transparent)`
- convert the field directly to the object instead of `set_item()`
- Newtype structs and tuple-variants are treated as transparent per default.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Newtype structs and tuple-variants are treated as transparent per default.
- Newtype tuple structs and tuple-variants are treated as transparent per default.

Comment on lines +793 to +795
- `#[pyo3(from_item_all)]`
- Added for avoid erroring when `FromPyObject` is dervived together
- It will be a no-op attribute for `#[derive(IntoPyObject)]`/`#[derive(IntoPyObjectRef)]`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned here, I think we should not list the ones that don't do anything, instead writing a more generic paragraph and maybe link to it from here. IMO this just clutters up the list without bringing too much valuable info to a user who is looking to customize IntoPyObject, but maybe other have different opinions here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Doc Improvements: IntoPyObject actually supports item / attribute attributes

2 participants