Skip to content

add PyModule::new_bound and PyModule::import_bound#3775

Merged
davidhewitt merged 6 commits intoPyO3:mainfrom
davidhewitt:import-bound
Feb 22, 2024
Merged

add PyModule::new_bound and PyModule::import_bound#3775
davidhewitt merged 6 commits intoPyO3:mainfrom
davidhewitt:import-bound

Conversation

@davidhewitt
Copy link
Member

Part of #3684

This is a WIP migration of PyModule::new and PyModule::import to the new APIs.

I decided to pause on this one for a bit and leave in draft, because:

  • I started moving Python::import to Python::import_bound at the same time, but this got too much so I might try to do that one first.
  • I think we should solve #[pymodule] taking &Bound<'_, PyModule> (probably in a similar way to the draft support &Bound<PyType> for classmethod #3744) before continuing here, because a lot of the examples / docs get in a really bad interim state here otherwise.

@davidhewitt davidhewitt added the CI-skip-changelog Skip checking changelog entry label Jan 29, 2024
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 29, 2024

CodSpeed Performance Report

Merging #3775 will not alter performance

Comparing davidhewitt:import-bound (5296636) with main (5ddcd46)

Summary

✅ 67 untouched benchmarks

@davidhewitt davidhewitt changed the title add PyModule::new and PyModule::import_bound add PyModule::new_bound and PyModule::import_bound Feb 18, 2024
@davidhewitt
Copy link
Member Author

davidhewitt commented Feb 18, 2024

Ok, I rebased this and it should be in a suitable state now. We still need to resolve #3808, but the diff here is still pretty reviewable without that cleanup.

@davidhewitt davidhewitt marked this pull request as ready for review February 18, 2024 22:44
Copy link
Contributor

@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.

Nice to see a lot of as_borrowed and as_gil_ref disappear!

wrap_pyfunction is a bit of a bound-ref-bound circle for now, but that's ok. I noticed a type error in a place or two, that the compiler/ci shout also pickup, and a few style nits.

A bit unrelated, but while reviewing I noticed that this example also needs updating. And since compile_fail examples tend to fail for the wrong reason as time passes, I might as well mention it, before I forget again 😄 .

pyo3/src/instance.rs

Lines 609 to 636 in 2bdc80a

/// ```compile_fail
/// # use pyo3::prelude::*;
/// # use pyo3::types::PyDict;
/// #
/// #[pyclass]
/// struct Foo<'py> {
/// inner: &'py PyDict,
/// }
///
/// impl Foo {
/// fn new() -> Foo {
/// let foo = Python::with_gil(|py| {
/// // `py` will only last for this scope.
///
/// // `&PyDict` derives its lifetime from `py` and
/// // so won't be able to outlive this closure.
/// let dict: &PyDict = PyDict::new(py);
///
/// // because `Foo` contains `dict` its lifetime
/// // is now also tied to `py`.
/// Foo { inner: dict }
/// });
/// // Foo is no longer valid.
/// // Returning it from this function is a 💥 compiler error 💥
/// foo
/// }
/// }
/// ```

Copy link
Contributor

@LilyFirefly LilyFirefly left a comment

Choose a reason for hiding this comment

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

I think we can change some more &PyModule to &Bound<'_, PyModule>, but maybe these should all wait until we update the wrap_pyfunction! macro to support Bound.

@@ -78,9 +78,9 @@ fn parent_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
}

fn register_child_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we do:

Suggested change
fn register_child_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> {
fn register_child_module(py: Python<'_>, parent_module: &Bound<'_, PyModule>) -> PyResult<()> {

parent_module.add_submodule(child_module)?;
let child_module = PyModule::new_bound(py, "child_module")?;
child_module.add_function(&wrap_pyfunction!(func, child_module.as_gil_ref())?.as_borrowed())?;
parent_module.add_submodule(child_module.as_gil_ref())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
parent_module.add_submodule(child_module.as_gil_ref())?;
parent_module.add_submodule(child_module)?;

@@ -286,10 +336,10 @@ impl PyModule {
///
/// #[pymodule]
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
/// fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {

/// submodule.add("super_useful_constant", "important")?;
///
/// module.add_submodule(submodule)?;
/// module.add_submodule(submodule.as_gil_ref())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// module.add_submodule(submodule.as_gil_ref())?;
/// module.add_submodule(submodule)?;

@@ -480,10 +530,10 @@ pub trait PyModuleMethods<'py> {
///
/// #[pymodule]
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
/// fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {

/// submodule.add("super_useful_constant", "important")?;
///
/// module.add_submodule(submodule)?;
/// module.add_submodule(submodule.as_gil_ref())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// module.add_submodule(submodule.as_gil_ref())?;
/// module.add_submodule(submodule)?;

@@ -258,12 +258,12 @@ fn superfunction() -> String {
#[pymodule]
fn supermodule(py: Python<'_>, module: &PyModule) -> PyResult<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fn supermodule(py: Python<'_>, module: &PyModule) -> PyResult<()> {
fn supermodule(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {

module.add_submodule(module_to_add)?;
let module_to_add = PyModule::new_bound(py, "submodule")?;
submodule(&module_to_add)?;
module.add_submodule(module_to_add.as_gil_ref())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
module.add_submodule(module_to_add.as_gil_ref())?;
module.add_submodule(module_to_add)?;

module.add_submodule(module_to_add.as_gil_ref())?;
let module_to_add = PyModule::new_bound(py, "submodule_with_init_fn")?;
submodule_with_init_fn(py, module_to_add.as_gil_ref())?;
module.add_submodule(module_to_add.as_gil_ref())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
module.add_submodule(module_to_add.as_gil_ref())?;
module.add_submodule(module_to_add)?;

@davidhewitt
Copy link
Member Author

Indeed, #[pymodule] doesn't yet support a &Bound<PyModule> argument yet either. It might be possible to achieve that in one go based on what I've got remaining in #3744. I might try that after this is merged.

@davidhewitt
Copy link
Member Author

@LilyFoote regarding the suggestions above, the blocker is the support for #[pymodule], otherwise those suggestions would compile. I'll try to include those in the follow-up.

@davidhewitt
Copy link
Member Author

Ooof can't keep up with the merge conflicts! I'll try to fixup this again this evening and hopefully see it across the line.

@davidhewitt davidhewitt added this pull request to the merge queue Feb 22, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 22, 2024
@davidhewitt davidhewitt added this pull request to the merge queue Feb 22, 2024
Merged via the queue into PyO3:main with commit 9e74c85 Feb 22, 2024
@davidhewitt davidhewitt deleted the import-bound branch February 22, 2024 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI-skip-changelog Skip checking changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants