|
3 | 3 | This guide can help you upgrade code through breaking changes from one PyO3 version to the next.
|
4 | 4 | For a detailed list of all changes, see the [CHANGELOG](changelog.md).
|
5 | 5 |
|
| 6 | +## from 0.17.* to 0.18 |
| 7 | + |
| 8 | +### Required arguments after `Option<_>` arguments will no longer be automatically inferred |
| 9 | + |
| 10 | +In `#[pyfunction]` and `#[pymethods]`, if a "required" function input such as `i32` came after an `Option<_>` input, then the `Option<_>` would be implicitly treated as required. (All trailing `Option<_>` arguments were treated as optional with a default value of `None`). |
| 11 | + |
| 12 | +Starting with PyO3 0.18, this is deprecated and a future PyO3 version will require a [`#[pyo3(signature = (...))]` option](./function/signature.md) to explicitly declare the programmer's intention. |
| 13 | + |
| 14 | +Before, x in the below example would be required to be passed from Python code: |
| 15 | + |
| 16 | +```rust,compile_fail |
| 17 | +# #![allow(dead_code)] |
| 18 | +# use pyo3::prelude::*; |
| 19 | +
|
| 20 | +#[pyfunction] |
| 21 | +fn required_argument_after_option(x: Option<i32>, y: i32) { } |
| 22 | +``` |
| 23 | + |
| 24 | +After, specify the intended Python signature explicitly: |
| 25 | + |
| 26 | +```rust |
| 27 | +# #![allow(dead_code)] |
| 28 | +# use pyo3::prelude::*; |
| 29 | + |
| 30 | +// If x really was intended to be required |
| 31 | +#[pyfunction(signature = (x, y))] |
| 32 | +fn required_argument_after_option_a(x: Option<i32>, y: i32) { } |
| 33 | + |
| 34 | +// If x was intended to be optional, y needs a default too |
| 35 | +#[pyfunction(signature = (x=None, y=0))] |
| 36 | +fn required_argument_after_option_b(x: Option<i32>, y: i32) { } |
| 37 | +``` |
| 38 | + |
| 39 | +### `__text_signature__` is now automatically generated for `#[pyfunction]` and `#[pymethods]` |
| 40 | + |
| 41 | +The [`#[pyo3(text_signature = "...")]` option](./function/signature.md#making-the-function-signature-available-to-python) was previously the only supported way to set the `__text_signature__` attribute on generated Python functions. |
| 42 | + |
| 43 | +PyO3 is now able to automatically populate `__text_signature__` for all functions automatically based on their Rust signature (or the [new `#[pyo3(signature = (...))]` option](./function/signature.md)). These automatically-generated `__text_signature__` values will currently only render `...` for all default values. Many `#[pyo3(text_signature = "...")]` options can be removed from functions when updating to PyO3 0.18, however in cases with default values a manual implementation may still be preferred for now. |
| 44 | + |
| 45 | +As examples: |
| 46 | + |
| 47 | +```rust |
| 48 | +# use pyo3::prelude::*; |
| 49 | + |
| 50 | +// The `text_signature` option here is no longer necessary, as PyO3 will automatically |
| 51 | +// generate exactly the same value. |
| 52 | +#[pyfunction(text_signature = "(a, b, c)")] |
| 53 | +fn simple_function(a: i32, b: i32, c: i32) {} |
| 54 | + |
| 55 | +// The `text_signature` still provides value here as of PyO3 0.18, because the automatically |
| 56 | +// generated signature would be "(a, b=..., c=...)". |
| 57 | +#[pyfunction(signature = (a, b = 1, c = 2), text_signature = "(a, b=1, c=2)")] |
| 58 | +fn function_with_defaults(a: i32, b: i32, c: i32) {} |
| 59 | + |
| 60 | +# fn main() { |
| 61 | +# Python::with_gil(|py| { |
| 62 | +# let simple = wrap_pyfunction!(simple_function, py).unwrap(); |
| 63 | +# assert_eq!(simple.getattr("__text_signature__").unwrap().to_string(), "(a, b, c)"); |
| 64 | +# let defaulted = wrap_pyfunction!(function_with_defaults, py).unwrap(); |
| 65 | +# assert_eq!(defaulted.getattr("__text_signature__").unwrap().to_string(), "(a, b=1, c=2)"); |
| 66 | +# }) |
| 67 | +# } |
| 68 | +``` |
| 69 | + |
6 | 70 | ## from 0.16.* to 0.17
|
7 | 71 |
|
8 | 72 | ### Type checks have been changed for `PyMapping` and `PySequence` types
|
|
0 commit comments