2947: change PyModule::add_class to return an error if class creation fails r=adamreichold a=davidhewitt
Related to #2942
At the moment there are panics deep in the `#[pyclass]` machinery when initialising the type fails. This PR adjusts a number of these functions to return `PyResult` instead, so that we can handle the error more appropriately further down the pipeline.
For example, take the following snippet:
```rust
#[pyclass(extends = PyBool)]
struct ExtendsBool;
#[pymodule]
fn pyo3_scratch(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<ExtendsBool>()?;
Ok(())
}
```
Currently, importing this module will fail with a panic:
```
TypeError: type 'bool' is not an acceptable base type
thread '<unnamed>' panicked at 'An error occurred while initializing class ExtendsBool', /Users/david/Dev/pyo3/src/pyclass.rs:412:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/david/.virtualenvs/pyo3/lib/python3.10/site-packages/pyo3_scratch/__init__.py", line 1, in <module>
from .pyo3_scratch import *
pyo3_runtime.PanicException: An error occurred while initializing class ExtendsBool
```
After this PR, this import still fails, but with a slightly cleaner, more Pythonic error:
```
TypeError: type 'bool' is not an acceptable base type
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/david/.virtualenvs/pyo3/lib/python3.10/site-packages/pyo3_scratch/__init__.py", line 1, in <module>
from .pyo3_scratch import *
RuntimeError: An error occurred while initializing class ExtendsBool
```
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
Co-authored-by: Adam Reichold <adam.reichold@t-online.de>
2944: optimize sequence conversion for list and tuple r=adamreichold a=davidhewitt
closes#2943
Avoid using `PyObject_IsInstance` for checking if lists or tuples are sequences, as we know they are always sequences.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2954: optimize mapping conversion for dict r=davidhewitt a=davidhewitt
Equivalent of #2944 for dicts -> mapping.
The benchmark diff is not as significant as in #2944. Still something like 80ns -> 2ns on my machine.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2955: add pydantic's use of Rust to README r=davidhewitt a=davidhewitt
Adding links to Pydantic to PyO3's readme - if you're ok with this `@samuelcolvin` ? :)
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2953: set csv minimal package version for 1.48 CI r=davidhewitt a=davidhewitt
New `csv 1.2.0` requires Rust 1.60.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2948: don't parse doc attributes unnecessarily r=davidhewitt a=davidhewitt
While working on #2866 I found that for all `#[pymethods]` we process the `#[doc]` attributes and build a Python docstring. However we don't always emit this doc - e.g. for class attributes and `__dunder__` methods.
This is just a small adjustment to move the `#[doc]` processing slightly later in the macro code to avoid the wasted work. (It also helps for the #2866 implementation later.)
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2945: move some private internals out of public implementation r=davidhewitt a=davidhewitt
This runs some quick cleanups on private stuff:
- Remove `#[doc(hidden)]` trait `TryFromPyCell` which is unused.
- Move `#[doc(hidden)]` struct `pyo3::type_object::LazyStaticType` to `pyo3::impl_::pyclass::LazyStaticType`.
- Move `pub(crate)` function `pyo3::pyclass::create_type_object` into submodule, to clean up main `pyclass.rs` implementation for readers.
As this is no behaviour change and separates stuff out slightly better, I'm just going to proceed to merge this. If anyone reading this wants to suggest a different way to factor out, happy to write a follow-up PR.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2939: Disable default features of `chrono` r=adamreichold a=messense
To avoid bringing `time` v0.1.x into dependency graph, see https://github.com/time-rs/time/issues/293
Co-authored-by: messense <messense@icloud.com>
2938: release notes for 0.18.1 r=davidhewitt a=davidhewitt
Update for `main` following release of new patch release.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2934: guide: add documentation for trailing option arguments r=davidhewitt a=davidhewitt
Following the increased clarity around PyO3's handling of function signatures of 0.18.0, I wanted to add a section to the guide documenting the default-to-none behaviour for trailing `Option<T>` arguments.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2937: link against pythonXY_d.dll for debug Python on Windows r=davidhewitt a=davidhewitt
Closes#2780
Note that upstream Python issue https://github.com/python/cpython/issues/101614 means linking against `python3_d.dll` is useless, so I've set this to always use the version-specific builds for now.
The heuristic for detecting a Windows debug build is... not great. I check if the `EXT_SUFFIX` starts with `_d.`, which is the only thing that I could see in the sysconfig which suggested a debug build. If this proves to be brittle, we may wish to ask upstream for something better to be added to `sysconfig`.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2936: bump maturin version in getting_started.md r=messense a=jmhodges
Latest maturin is 0.14.x, so reference that in the docs
Co-authored-by: Jeff Hodges <jeff@somethingsimilar.com>
2929: docs: Precise the abscense of `py: Python` for the #[pyo3(signature)] r=davidhewitt a=jjerphan
Hi,
First, thank you for working on PyO3!
I think this adds a precision which was not obvious when migrating to 0.18.0 conventions.
What do you think? Also, should something be added to [the migration guide](https://pyo3.rs/main/migration) in this regard?
Thank you!
Co-authored-by: Julien Jerphanion <git@jjerphan.xyz>
2914: correct ffi definition of PyIter_Check r=davidhewitt a=davidhewitt
Closes#2913
It looks like what is happening is that PyO3 was relying on an outdated macro form of `PyIter_Check` which is now a CPython implementation detail, which would explain why it was behaving inconsistently on different platforms (likely due to differences in linkers / implementations).
The test I've pushed succeeds, but fails to compile due to a hygiene bug! I'm done for tonight so I'll take a look at that soon and then rebase this after.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2930: add better error message for Python in signature r=adamreichold a=davidhewitt
Inspired by #2929, this just adds a better error message when `Python` arguments are accidentally included in the signature.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2933: changelog: add missing entry for frozen r=davidhewitt a=davidhewitt
After discussion in https://github.com/PyO3/rust-numpy/pull/367#issuecomment-1409283700 I noticed we were missing a CHANGELOG entry for frozen. This doesn't help past users but does help document when the feature was released (in 0.17.0).
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2912: Add `PyDict.update()` and `PyDict.update_if_missing()` r=davidhewitt a=samuelcolvin
Fix#2910
Note, I'd also be happy to remove the `override_` argument from merge and perhaps rename it to `update_missing` or similar to give a cleaner API. LMK what you think.
Please consider adding the following to your pull request:
- [x] an entry for this PR in newsfragments
- [x] docs to all new functions and / or detail in the guide
- [x] tests for all new or changed functions
Co-authored-by: Samuel Colvin <s@muelcolvin.com>
2926: Warn about unknown config keys in `PYO3_CONFIG_FILE` r=davidhewitt a=messense
`maturin` also read from `PYO3_CONFIG_FILE` to get `ext_suffix` config, `pyo3-build-config` currently denies unknown config keys makes it inconvenient.
See https://github.com/PyO3/maturin/issues/1430
Co-authored-by: messense <messense@icloud.com>
2873: A new example that shows how to integrate Python plugins that use pyclasses into a Rust app r=davidhewitt a=alexpyattaev
Example showing integration of a Python plugin into a Rust app while having option to test pyclass based API without the main app. This also illustrates some aspects related to import of Python modules into a Rust app while also having an API module available for the Python code to be able to produce Rust objects.
CI seems to fail on my local machine for reasons unrelated to the example just added:
```
error: unused macro definition: `check_struct`
--> pyo3-ffi-check/src/main.rs:13:18
|
13 | macro_rules! check_struct {
| ^^^^^^^^^^^^
|
```
Co-authored-by: Alex Pyattaev <alex.pyattaev@gmail.com>
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
2923: hygiene: fix `#[pymethods(crate = "...")]` r=davidhewitt a=davidhewitt
Got to the bottom of the hygiene issue in test of #2914
Turns out that `#[pymethods] #[pyo3(crate = "...")]` works, but `#[pymethods(crate = "...")]` was ignoring the argument.
Added a tweak to fix this and a snippet in the hygiene test (which fails on `main`).
2924: remove unneeded into_iter calls r=davidhewitt a=davidhewitt
Clippy complaining about these to me this morning locally.
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>