Skip to content

PyCapsule: allow zero-sized types#5889

Merged
davidhewitt merged 1 commit intoPyO3:mainfrom
Tpt:tpt/allow-zero-sized-capsule
Mar 22, 2026
Merged

PyCapsule: allow zero-sized types#5889
davidhewitt merged 1 commit intoPyO3:mainfrom
Tpt:tpt/allow-zero-sized-capsule

Conversation

@Tpt
Copy link
Contributor

@Tpt Tpt commented Mar 17, 2026

Box::into_raw never returns a null pointer so it seems safe

Alternative to #5882, see this MR for context

@Tpt Tpt force-pushed the tpt/allow-zero-sized-capsule branch from 1fc4d3a to c5a29a9 Compare March 17, 2026 11:12
@davidhewitt
Copy link
Member

I think I'm in favour of this, seems like no technical reason we should restrict users in this way 👍

`Box::into_raw` never returns a null pointer so it seems safe
@Tpt Tpt force-pushed the tpt/allow-zero-sized-capsule branch from c5a29a9 to 70c66a0 Compare March 17, 2026 14:16
@Tpt Tpt marked this pull request as ready for review March 17, 2026 14:51
@Icxolu
Copy link
Member

Icxolu commented Mar 17, 2026

Do we need to consider that the ZST story in C is at least somewhat convoluted? Or do we want to support this as a way of Rust to Rust communication over the C ABI?

@Tpt
Copy link
Contributor Author

Tpt commented Mar 18, 2026

Do we need to consider that the ZST story in C is at least somewhat convoluted? Or do we want to support this as a way of Rust to Rust communication over the C ABI?

Good question. My "hot" take would be that if the user plans to dereference the pointer from C then they already need to care about the ABI of the pointed data, and care about ZST is part of it. So, preventing ZST is only a very small part of making this safe.

@davidhewitt
Copy link
Member

I think I agree with that statement. Probably the real requirement is that the data in every capsule should probably be #[repr(C)] or another repr which guarantees the layout is independent of compiler version. But I doubt there's a way we can enforce that... probably we should just document it?

... or thinking about it more, does that actually imply that PyCapsule constructors should always be unsafe because it's likely accidental UB to stick a type that doesn't have a stable layout into it? I guess it would be sound to read it within the same extension, but in that case it'd arguably be more correct to use a #[pyclass] instead of a capsule anyway, to leverage the type safety.

@Tpt
Copy link
Contributor Author

Tpt commented Mar 22, 2026

Probably the real requirement is that the data in every capsule should probably be #[repr(C)] or another repr which guarantees the layout is independent of compiler version

Yes!

probably we should just document it?

Yes! I don't see an other way with current Rust (it would be nice to have a StableABI trait but sadly it does not exist).

... or thinking about it more, does that actually imply that PyCapsule constructors should always be unsafe because it's likely accidental UB to stick a type that doesn't have a stable layout into it?

Yes on the UB issue. Not sure about making the PyCapsule constructor unsafe because there is already the "unsafe" operation of dereferencing the pointer from the capsule and it's this operation that actually triggers the UB if the type does not have a stable layout.

@davidhewitt
Copy link
Member

Ah yes, you're of course right - just like creating a pointer is safe, we can create a capsule as long as it's not dereferenced.

So I think we just need to ensure the layout stability is appropriately documented, probably both on constructors and the pointer retrieval ops.

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

In which case let's just merge this and make sure the documentation pass on #5881 is appropriately covered.

@davidhewitt davidhewitt added this pull request to the merge queue Mar 22, 2026
Merged via the queue into PyO3:main with commit f94f753 Mar 22, 2026
45 of 46 checks passed
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.

4 participants