docs: Improves IntoPyObject documentation in the guides#5835
docs: Improves IntoPyObject documentation in the guides#5835
IntoPyObject documentation in the guides#5835Conversation
…tructs and tuples.
… and `#[derive(IntoPyObjectRef)]`.
…readability and consistency.
IntoPyObject documentation in the guides [WIP]IntoPyObject documentation in the guides
Icxolu
left a comment
There was a problem hiding this comment.
Thank you for working on this! I spotted a few things and left comments below.
guide/src/conversions/traits.md
Outdated
| 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. |
There was a problem hiding this comment.
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)
guide/src/conversions/traits.md
Outdated
| For `enum`s each variant is converted according to the rules for `struct`s above. | ||
|
|
||
| ```rust,no_run | ||
| ```rust |
There was a problem hiding this comment.
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.
| - `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. | ||
|
|
There was a problem hiding this comment.
This one has no effect for IntoPyObject and we should not document it.
|
|
||
| #### `#[derive(IntoPyObject)]`/`#[derive(IntoPyObjectRef)]` Field Attributes | ||
|
|
||
| - `pyo3(item)`, `pyo3(item("key"))` |
There was a problem hiding this comment.
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.
|
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. |
There was a problem hiding this comment.
not quite sure what you mean here
| struct RustyStruct { | ||
| #[pyo3(item("key"))] | ||
| string_in_mapping: String, | ||
| #[pyo3(attribute("name"))] // no effect on this field |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
| - Newtype structs and tuple-variants are treated as transparent per default. | |
| - Newtype tuple structs and tuple-variants are treated as transparent per default. |
| - `#[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)]` |
There was a problem hiding this comment.
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.
| ``` | ||
|
|
||
| - `pyo3(default)`, `pyo3(default = ...)` | ||
| - Added for avoid erroring when `FromPyObject` is dervived together |
There was a problem hiding this comment.
I'm not sure what this means. Together with what?
There was a problem hiding this comment.
I think @Icxolu has explained that, it is common practice to derviced IntoPyObject and FromPyObject together and this option is available to avoid errors. I think it is obvious to people who are using this feature but I can add more explanation once we have decided on the format.
There was a problem hiding this comment.
I think I was just having trouble with the grammar. Maybe instead:
"Used to avoid errors when deriving both FromPyObject and IntoPyObject"
| - Possible values are: "camelCase", "kebab-case", "lowercase", "PascalCase", "SCREAMING-KEBAB-CASE", "SCREAMING_SNAKE_CASE", "snake_case", "UPPERCASE". | ||
| - fields with an explicit renaming via `attribute(...)`/`item(...)` are not affected | ||
| - `#[pyo3(from_item_all)]` | ||
| - extract every field with `get_item` method. |
There was a problem hiding this comment.
Not sure what this means either.
There was a problem hiding this comment.
There is an explanation above, this is just a list of organising them together in one place. Please read the paragraph above
| ### `#[derive(FromPyObject)]` Container Attributes | ||
|
|
||
| - `pyo3(transparent)` | ||
| - extract the field directly from the object as `obj.extract()` instead of `get_item()` or |
There was a problem hiding this comment.
Observation: this is currently in a list. Some of these macros have the options documented as a table, e.g. https://pyo3.rs/v0.28.2/class.html#customizing-the-class
I think we're probably quite inconsistent across the documentation, maybe we should create a new issue to decide on preferred style (table or list) and convert them all?
There was a problem hiding this comment.
I do like the table format better, we can tie the effect of the attribution for FromPyObject and IntoPyObject together. I can work on that this weekend if it looks better
|
In my opinion, we need a list or table to list out the behaviour of each option, including the no-op ones because:
If a table is clearer and easier to explain I don't mind moving all items in the lists into tables. But I do believe they need to be explicitly documentated. |
|
Hmm, the reason I don't think we should list them is that I would not consider these "public" API. You should not use the options if you only implementing Alternatively, I think we could follow |
|
Let's follow serde's example then, I also think it looks neater by not having two lists. |
closes #5709