-
Notifications
You must be signed in to change notification settings - Fork 835
Implement #[init]
method attribute in #[pymethods]
#4951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
f256dc8
to
6dbd5f4
Compare
This allows to control objects initialization flow in the Rust code in case of inheritance from native Python types.
It seems that most of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies for the delay. Thanks for this, it seems useful 👍
Please add some more tests, for stuff like combinations of attributes:
#[init]
#[classmethod]
#[init]
#[new]
and a pyclass that inherits another pyclass, that init cannot be on functions and so on.
explicitly like that happens in a regular Python code. | ||
|
||
To declare an initializer, you need to define a method and annotate it with the `#[init]` | ||
attribute. An `init` method must have the same input paretemeters signature like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attribute. An `init` method must have the same input paretemeters signature like | |
attribute. An `init` method must have the same input parameters signature like |
`__init__` method of `PyDict` been called. In this case by defining an own `init` method | ||
it's possible to stop initialization flow. | ||
|
||
If you declare an own `init` method you may need to call a super class `__init__` method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you declare an own `init` method you may need to call a super class `__init__` method | |
If you declare an own `init` method you may need to call a super class' `__init__` method |
@@ -830,7 +842,6 @@ impl<'a> FnSpec<'a> { | |||
_kwargs: *mut #pyo3_path::ffi::PyObject | |||
) -> #pyo3_path::PyResult<*mut #pyo3_path::ffi::PyObject> { | |||
use #pyo3_path::impl_::callback::IntoPyCallbackOutput; | |||
let function = #rust_name; // Shadow the function name to avoid #3017 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this no longer needed?
@@ -104,6 +106,35 @@ impl ClassWithDict { | |||
} | |||
} | |||
|
|||
#[cfg(Py_3_8)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is #[init]
only supported on 3.8 and up? Please also document this in the guide.
@@ -181,6 +182,59 @@ created from Rust, but not from Python. | |||
|
|||
For arguments, see the [`Method arguments`](#method-arguments) section below. | |||
|
|||
## Initializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also document that it shall return either PyResult<()>
or nothing. Ideally the macro would check for this; not sure how feasible that is.
@@ -181,6 +182,59 @@ created from Rust, but not from Python. | |||
|
|||
For arguments, see the [`Method arguments`](#method-arguments) section below. | |||
|
|||
## Initializer | |||
|
|||
An initializer implements Python's `__init__` method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should discourage users from using init
unless they really need it; they probably should use new
instead.
|
||
Like in the constructor case the Rust method name isn't important. | ||
|
||
```rust,ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this ignored? Please write some test code in this example. It can be something simple like a hidden test that just creates and checks it.
btw I also have basic support for defining
|
This allows to control objects initialization flow in the Rust code in case of inheritance from native Python types.
A simple example, you implement a class inherited from
PyDict
but want to build a custom constructor interface. With just the#[new]
constructor it's not possible and the basePyDict
__init__
method will be called too with all arguments that were passed to the constructor as a standard objects initialization behavior.