Skip to content

Conversation

davidhewitt
Copy link
Member

Extension of #5229

I could not push to that PR.

I'm too tired to continue tonight, will most likely revisit this tomorrow evening.

Comment on lines 265 to 269
/// This method returns `*const c_char` instead of `&CStr` because it's possible for
/// arbitrary Python code to change the capsule name. Callers can use `NonNull::from_ptr()`
/// to get a `&CStr` if they want to, however they should beware the fact that the pointer
/// may become invalid after arbitrary Python code has run.
fn name(&self) -> PyResult<*const c_char>;
Copy link
Member Author

Choose a reason for hiding this comment

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

I changed this because the &CStr had the same problematic lifetime as .reference(). Also CStr::from_ptr is linear complexity so this is potentially more efficient depending on what the user is doing with it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can use Option<NonNull<c_char>> here, to enforce the check for the null pointer?

Copy link
Member Author

Choose a reason for hiding this comment

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

I played around with this just now but the NonNull doesn't carry the const-ness of the value. It's also a fairly nested type, overall it just didn't feel that good.

One option is we could have a type CapsuleName which has an unsafe .as_cstr() method. (unsafe because it's legal for callers to change the capsule name later.)

Copy link
Member Author

Choose a reason for hiding this comment

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

(So -> PyResult<Option<CapsuleName>>)

@davidhewitt
Copy link
Member Author

I wonder if the new names should be introduced as get_pointer, get_reference etc, which are verbose but not overly so.

@honzasp
Copy link

honzasp commented Sep 28, 2025

Thanks for taking over and extending the PR :) As a user of PyO3 I'd prefer the xxx_checked() names rather than get_xxx(), because using the get_ prefix in Rust is frowned upon, and there is a strong precedent of the checked/unchecked dichotomy in the standard library.

I think it would be best to eventually rename pointer_checked() back to pointer(), after a sufficiently long period of the old unchecked pointer() being deprecated.

By the way, thanks for all the work that you put into this excellent crate!

@davidhewitt davidhewitt marked this pull request as ready for review September 28, 2025 14:38
@davidhewitt
Copy link
Member Author

I took another pass at this file.

I added SAFETY notes on the whole file as per #5487, and attempted to use CapsuleName to make the name consumption slightly more ergonomic / type-safe.

Possibly in the future it might be correct to use PyResult<Option<NonNull<CStr>> as the return type for .name(), but at the moment NonNull<CStr> is a wide pointer and creating it incurs a length check (which may change in future).

Comment on lines +271 to +275
/// This method returns a `NonNull<CStr>` instead of `&CStr` because it's possible for
/// arbitrary Python code to change the capsule name. Callers can use [`.as_ref()`][NonNull::as_ref]
/// to get a `&CStr` when needed, however they should beware the fact that the pointer
/// may become invalid after arbitrary Python code has run.
fn name(&self) -> PyResult<Option<CapsuleName>>;
Copy link

Choose a reason for hiding this comment

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

Nitpick: this method now returns an Option<CapsuleName>, not NonNull<CStr> as written in the comment.

/// This is a thin wrapper around `*const c_char`, which can be accessed with the [`as_ptr`][Self::as_ptr]
/// method. The [`as_cstr`][Self::as_cstr] method can be used as a convenience to access the name as a `&CStr`.
#[derive(Clone, Copy)]
pub struct CapsuleName {
Copy link

Choose a reason for hiding this comment

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

We probably want to reexport this type in src/types/mod.rs, to make sure that it appears in the docs and that users of the crate can name this type.

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.

3 participants