Skip to content

Capsule: simplify non zero size assertion#5882

Open
Tpt wants to merge 2 commits intoPyO3:mainfrom
Tpt:tpt/capsule-check
Open

Capsule: simplify non zero size assertion#5882
Tpt wants to merge 2 commits intoPyO3:mainfrom
Tpt:tpt/capsule-check

Conversation

@Tpt
Copy link
Contributor

@Tpt Tpt commented Mar 16, 2026

It is now possible to do assertions in const functions, let's use that

@Tpt Tpt self-assigned this Mar 16, 2026
@Tpt Tpt added the CI-skip-changelog Skip checking changelog entry label Mar 16, 2026
@Tpt Tpt force-pushed the tpt/capsule-check branch 2 times, most recently from c312410 to 6d3815e Compare March 16, 2026 09:47
@Tpt Tpt force-pushed the tpt/capsule-check branch from 6d3815e to 9ddcb4c Compare March 16, 2026 09:48
@Tpt Tpt marked this pull request as ready for review March 16, 2026 10:44
@Icxolu
Copy link
Member

Icxolu commented Mar 16, 2026

Do we need the trait anymore than? We could use a const fn now or potentially even inline it in a const { ... } block. It might be worth to check how the error message looked like before and after to make sure we don't make this too confusing. (Do we need #[track_caller] for a const panic?)

@Tpt
Copy link
Contributor Author

Tpt commented Mar 16, 2026

We could use a const fn now or potentially even inline it in a const { ... } block.

Great call! I tried calling directly the const fn but it was not working because the evaluation was done at runtime. Wrapping it in a const { works. I have not inlined it to make code I think a bit cleaner. Done.

It might be worth to check how the error message looked like before and after to make sure we don't make this too confusing

Yes! The new one is quite nice:

error[E0080]: evaluation panicked: PyCapsule value type T must not be zero-sized!
   --> src/types/capsule.rs:109:17
    |
109 |         const { assert_not_zero_size::<T>() }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `types::capsule::PyCapsule::new_with_destructor::<(), {closure@src/types/capsule.rs:93:52: 93:58}>::{constant#0}` failed here

Do we need #[track_caller] for a const panic?

Yes, this way we avoid the not useful note:

note: inside `assert_not_zero_size::<()>`
   --> src/types/capsule.rs:566:5
    |
566 | /     assert!(
567 | |         size_of::<T>() != 0,
568 | |         "PyCapsule value type T must not be zero-sized!"
569 | |     )
    | |_____^ the failure occurred here

T: 'static + Send + AssertNotZeroSized,
F: FnOnce(T, *mut c_void) + Send,
>(
pub fn new_with_destructor<T: 'static + Send, F: FnOnce(T, *mut c_void) + Send>(
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to add a #[track_caller] here (and above) as well, so that the error does not point into pyo3 code?

@davidhewitt
Copy link
Member

I wonder, do we even need this assertion? I confess I forget why the original restriction was necessary, the best source I can find is #1980 (comment), where the restriction supposedly fixed a segfault (which might have just been due to an incorrect cast of the value coming out of the box).

I can see why it's not helpful to ever want a ZST in a capsule (serves no purpose), so maybe we can keep this restriction and just clarify better for users why we don't accept it?

@Tpt
Copy link
Contributor Author

Tpt commented Mar 17, 2026

I wonder, do we even need this assertion?

Great point! Box::into_raw never returns a null pointer so it seems safe to me.

I can see why it's not helpful to ever want a ZST in a capsule (serves no purpose), so maybe we can keep this restriction and just clarify better for users why we don't accept it?

Maybe this restriction can be painful for some generic code? If they work, it seems more the realm of a warning than of an error. But I do not have a strong opinion on that, glad to tweak the MR to whatever the consensus is.

@Tpt
Copy link
Contributor Author

Tpt commented Mar 17, 2026

I have opened #5889 that remove the zero-sized type limit and added a test that seems to pass

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.

4 participants