Skip to content
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

[v2.12] Backport: Enable type-safe interoperability between different independent Python/C++ bindings systems. #5368

Merged
merged 6 commits into from
Sep 13, 2024

Conversation

rwgk
Copy link
Collaborator

@rwgk rwgk commented Sep 13, 2024

Description

Backport of PR #5296 to the pybind11 v2.12 series, to maximize the benefit of the new cross-version interoperability feature.

Suggested changelog entry:

Backport of PR #5296: The pybind11 v2.12 series now interoperates with other pybind11 versions that include PR #5296. (See the description of PR #5296 for limitations.)

…n/C++ bindings systems. (pybind#5296)

* `self.__cpp_transporter__()` proof of concept: Enable passing C++ pointers across extensions even if the `PYBIND11_INTERNALS_VERSION`s do not match.

* Include cleanup (mainly to resolve PyPy build failures).

* Fix clang-tidy errors.

* Resolve `error: extra

* factor out platform_abi_id.h from internals.h (no functional changes)

* factor out internals_version.h from internals.h (no functional changes)

* Update CMakeLists.txt, tests/extra_python_package/test_files.py

* Revert "factor out internals_version.h from internals.h (no functional changes)"

This reverts commit 3ccea8c.

* Remove internals_version.h from CMakeLists.txt, tests/extra_python_package/test_files.py

* `.__cpp_transporter__()` implementation: compare `pybind11_platform_abi_id`, `cpp_typeid_name`

* Add PremiumTraveler

* Rename test_cpp_transporter_traveler_type.h -> test_cpp_transporter_traveler_types.h

* Expand tests: `PremiumTraveler`, `get_points()`

* Shuffle order of tests (no real changes).

* Move `__cpp_transporter__` lambda to `py::cpp_transporter()` regular function.

* Use `type_caster_generic::load(self)` instead of `cast<T *>(self)`

* Pass `const std::type_info *` via `py::capsule` (instead of `cpp_typeid_name`).

* Make platform_abi_id.h completely stand-alone.

* rename exo_planet.cpp -> exo_planet_pybind11.cpp

* Add exo_planet_c_api.cpp (incomplete).

* Fix silly oversight (wrong filename in `#include`).

* Resolve clang-tidy errors:

```
/__w/pybind11/pybind11/tests/exo_planet_c_api.cpp:10:18: error: 'wrapGetLuggage' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace,-warnings-as-errors]
   10 | static PyObject *wrapGetLuggage(PyObject *, PyObject *) { return PyUnicode_FromString("TODO"); }
      | ~~~~~~           ^
/__w/pybind11/pybind11/tests/exo_planet_c_api.cpp:14:20: error: 'ThisMethodDef' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace,-warnings-as-errors]
   14 | static PyMethodDef ThisMethodDef[]
      | ~~~~~~             ^
/__w/pybind11/pybind11/tests/exo_planet_c_api.cpp:17:27: error: 'ThisModuleDef' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace,-warnings-as-errors]
   17 | static struct PyModuleDef ThisModuleDef = {
      | ~~~~~~                    ^
```

* Implement exo_planet_c_api GetLuggage(), GetPoints()

* Move new code from test_cpp_transporter_traveler_bindings.h to pybind11/detail/type_caster_base.h, under the name `class_dunder_cpp_transporter()`

* Fix oversight.

* Unconditionally add `__cpp_transporter__` method to all `py::class_` objects, but do not include that magic method in docstring signatures.

* Back out pybind11/detail/platform_abi_id.h for now. Maximizing reusability can be handled separately, later.

* Small cleanup.

* Restore and add to `test_call_cpp_transporter_*()`

* Ensure pybind#3788 does not bite again.

* `class_dunder_cpp_transporter()`: replace `obj.cast<std::string>()` with `std::string(obj)`

* Add (simple) copyright notices in all newly added files.

* Globally replace cpp_transporter with cpp_conduit

* style: pre-commit fixes

* IWYU fixes

* Rename `class_dunder_cpp_conduit()` -> `cpp_conduit_method()`

* Change `pybind11_platform_abi_id`, `pointer_kind` argument types from `str` to `bytes`.

This avoids the unicode decode/encode roundtrips:

* More robust (no decode/encode errors).

* Minor runtime optimization.

* Systematically rename `cap_cpp_type_info` -> `cpp_type_info_capsule` (no functional changes).

* Systematically replace `cpp_type_info_capsule` `name`: `"const std::type_info *"` -> `typeid(std::type_info).name()` (this IS a functional change).

This provides an extra layer of protection against C++ ABI mismatches:

* The first and most important layer is that the `PYBIND11_PLATFORM_ABI_ID`s must match between extensions.

* The second layer is that the `typeid(std::type_info).name()`s must match between extensions.

* Fix sort order accident in tests/CMakeLists.txt

* Apply suggestions from code review

Co-authored-by: Aaron Gokaslan <[email protected]>

* style: pre-commit fixes

* refactor: rename to _pybind_conduit_v1_

Signed-off-by: Henry Schreiner <[email protected]>

* Add test_home_planet_wrap_very_lonely_traveler(), test_exo_planet_pybind11_wrap_very_lonely_traveler()

* Resolve clang-tidy errors:

```
/__w/pybind11/pybind11/tests/test_cpp_conduit_traveler_bindings.h:39:32: error: parameter 'm' is passed by value and only copied once; consider moving it to avoid unnecessary copies [performance-unnecessary-value-param,-warnings-as-errors]
   10 |     py::class_<LonelyTraveler>(m, "LonelyTraveler");
      |                                ^
      |                                std::move( )
/__w/pybind11/pybind11/tests/test_cpp_conduit_traveler_bindings.h:43:52: error: parameter 'm' is passed by value and only copied once; consider moving it to avoid unnecessary copies [performance-unnecessary-value-param,-warnings-as-errors]
   43 |     py::class_<VeryLonelyTraveler, LonelyTraveler>(m, "VeryLonelyTraveler");
      |                                                    ^
      |                                                    std::move( )
```

---------

Signed-off-by: Henry Schreiner <[email protected]>
Co-authored-by: Ralf W. Grosse-Kunstleve <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <[email protected]>
Co-authored-by: Aaron Gokaslan <[email protected]>
@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

@henryiii What's the best way to handle the Changelog for v2.12.1, and the version change in pybind11/detail/common.h? Should I just make all the changes in this PR?

@rwgk rwgk mentioned this pull request Sep 13, 2024
@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

@henryiii What's the best way to handle the Changelog for v2.12.1, and the version change in pybind11/detail/common.h? Should I just make all the changes in this PR?

@henryiii — I went ahead and added all changes in this PR, with the idea to forward-port the Changelog addition to master after this PR is merged. Please let me know if there is a better way.

The Config and CI GitHub Actions workflows have failures, but they are unrelated to the changes under PR #5296. I created PR #5369 to verify that the exact same failures exist already for v2.12.0 as-is. The idea is to then ignore them here. — GitHub Actions are still running for both, this PR and PR #5369. I'll enumerate the failures here when both are done.

@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

The existing GitHub Actions failures are:

Config:

  • 🐍 3.7 • CMake 3.26 • macos-latest
  • 🐍 3.7 • CMake 3.7 • macos-latest

CI:

  • 🐍 3.6 • macos-latest • x64
  • 🐍 3.9 • macos-latest • x64
  • 🐍 pypy-3.8 • macos-latest • x64
  • 🐍 pypy-3.9 • macos-latest • x64
  • 🐍 pypy-3.10 • macos-latest • x64
  • 🐍 3 • centos:7 • x64
  • 🐍 3 • windows-latest • mingw32

These failures are identical to those under PR #5369. I.e., they are certainly unrelated to the changes under PR #5296.

@rwgk rwgk marked this pull request as ready for review September 13, 2024 17:36
@rwgk rwgk requested a review from henryiii as a code owner September 13, 2024 17:36
@henryiii
Copy link
Collaborator

I would not touch version numbers in a PR not related to version numbers. What I do is:

  • Merge this PR with the normal changes.
  • Make a Changelog PR toward master.
  • Once that's in, cherry-pick the changes and changelog commits to the vX.Y branches.
  • Commit the version bump to those branches (that commit won't ever be on master). Optionally make this as a PR to those branches, but I haven't bothered.

@henryiii
Copy link
Collaborator

Ahh, this is a PR to the branch. Please put the branch name in brackets in the PR title if you do that. I'd probably not bother making these PRs, they've already been PRs and passed testing. Just cherry pick them and push. If you want, I can take a stab at doing v2.12 in a few minutes.

@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

I reverted the two commits here (Changlog addition, version number change).

Could you please merge if this looks good to you? (No need to wait for GHA to finish, the code hasn't changed compared to what was tested before.)

My plan from here:

  1. Also backport to v2.11, just like this PR.
  2. Changelog updates towards master for both v2.11.2 and v2.12.1 (i.e. one PR).
  3. For each v2.11, v2.12: PR to increment patch version.
  4. For each v2.11, v2.12: Make the releases (I may need your advise again).

@rwgk rwgk changed the title Enable type-safe interoperability between different independent Python/C++ bindings systems. [v2.12] Backport: Enable type-safe interoperability between different independent Python/C++ bindings systems. Sep 13, 2024
@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

Ahh, this is a PR to the branch. Please put the branch name in brackets in the PR title if you do that. I'd probably not bother making these PRs, they've already been PRs and passed testing. Just cherry pick them and push. If you want, I can take a stab at doing v2.12 in a few minutes.

I saw this only just now.

Please put the branch name in brackets in the PR title if you do that.

Sorry I meant to do that, but then it slipped my mind. Fixed.

Just cherry pick them and push.

Note 8b93691. I'll do a PR for v2.11 as well, to be on the safe side.

@henryiii
Copy link
Collaborator

The CI isn't going to work for old branches.

#5330, #5322, #5321, and #5314 probably should all go into v2.12.

@henryiii
Copy link
Collaborator

henryiii commented Sep 13, 2024

I'll do it for v2.13, and record the process here as I do it:

  1. Run nox -s make_changelog, and update the PR descriptions so that comes out nice. Mostly fixing single-tickmarks to double tick marks (I will move the changelog from rst to md someday) and adding categories like feat: to PR titles.

Ahh, I'm off a version. I think I'm thinking 2.13? Current release is 2.13.6, shouldn't we get 2.13.7 out first?

@henryiii
Copy link
Collaborator

Okay, I'd cherry pick everything you want, make a rebase-and-merge PR, and then update the changelog with those versions to master. You might just need to make the same manual changes to the changelog in the PR, though, since otherwise you'd have to cherry pick all older changelog changes.

@henryiii
Copy link
Collaborator

(Sorry for the confusion, I was confused by the PR and then the version numbers. I'll try to do the next 2.13 release in a few minutes then)

@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

(Sorry for the confusion, I was confused by the PR and then the version numbers. I'll try to do the next 2.13 release in a few minutes then)

Oh, for v2.13 I was thinking of holding off until #5362 is merged. WDYT?

@henryiii
Copy link
Collaborator

I'd be fine to get this out now as a strict compatibility improvement, then do a 2.13.7 soon. I have a possible CMake issue I'd like to look into (with the classic search and mismatched bittiness) that we could get into the next version. The new 2.12 & 2.11 won't be very useful if they can't talk to 2.13?

Regardless, I"m going to follow the same procure (that I kind of accidentally stopped you from doing): make a PR with the changelog, then make a rebase-and-merge PR with the changes to v2.13. I'll go ahead and prepare the v* addition too.

@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

I'd be fine to get this out now as a strict compatibility improvement, then do a 2.13.7 soon. I have a possible CMake issue I'd like to look into (with the classic search and mismatched bittiness) that we could get into the next version. The new 2.12 & 2.11 won't be very useful if they can't talk to 2.13?

Regardless, I"m going to follow the same procure (that I kind of accidentally stopped you from doing): make a PR with the changelog, then make a rebase-and-merge PR with the changes to v2.13. I'll go ahead and prepare the v* addition too.

Awesome, thanks!

@rwgk
Copy link
Collaborator Author

rwgk commented Sep 13, 2024

Squash-merging, after coordinating with @henryiii on slack.

@rwgk rwgk merged commit b58436a into pybind:v2.12 Sep 13, 2024
75 of 84 checks passed
@rwgk rwgk deleted the pybind11_conduit_v1_backport_v2_12 branch September 13, 2024 21:51
@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Sep 13, 2024
@rwgk rwgk removed the needs changelog Possibly needs a changelog entry label Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants