cpython/objects/capsule.rs
1//! Work wih Python capsules
2//!
3use libc::c_void;
4use std::ffi::{CStr, CString, NulError};
5use std::mem;
6
7use super::object::PyObject;
8use crate::err::{self, PyErr, PyResult};
9use crate::ffi::{PyCapsule_GetPointer, PyCapsule_Import, PyCapsule_New};
10use crate::python::{Python, ToPythonPointer};
11
12/// Capsules are the preferred way to export/import C APIs between extension modules,
13/// see [Providing a C API for an Extension Module](https://docs.python.org/3/extending/extending.html#using-capsules).
14///
15/// In particular, capsules can be very useful to start adding Rust extensions besides
16/// existing traditional C ones, be it for gradual rewrites or to extend with new functionality.
17/// They can also be used for interaction between independently compiled Rust extensions if needed.
18///
19/// Capsules can point to data, usually static arrays of constants and function pointers,
20/// or to function pointers directly. These two cases have to be handled differently in Rust,
21/// and the latter is possible only for architectures were data and function pointers have
22/// the same sizes.
23///
24/// # Examples
25/// ## Using a capsule defined in another extension module
26/// This retrieves and use one of the simplest capsules in the Python standard library, found in
27/// the `unicodedata` module. The C API enclosed in this capsule is the same for all Python
28/// versions supported by this crate. This is not the case of all capsules from the standard
29/// library. For instance the `struct` referenced by `datetime.datetime_CAPI` gets a new member
30/// in version 3.7.
31///
32/// Note: this example is a lower-level version of the [`py_capsule!`] example. Only the
33/// capsule retrieval actually differs.
34/// ```no_run
35/// use cpython::{Python, PyCapsule};
36/// use libc::{c_void, c_char, c_int};
37/// use std::ffi::{CStr, CString};
38/// use std::mem;
39/// use std::ptr::null;
40///
41/// #[allow(non_camel_case_types)]
42/// type Py_UCS4 = u32;
43/// const UNICODE_NAME_MAXLEN: usize = 256;
44///
45/// #[repr(C)]
46/// pub struct unicode_name_CAPI {
47/// // the `ucd` signature arguments are actually optional (can be `NULL`) FFI PyObject
48/// // pointers used to pass alternate (former) versions of Unicode data.
49/// // We won't need to use them with an actual value in these examples, so it's enough to
50/// // specify them as `*const c_void`, and it spares us a direct reference to the lower
51/// // level Python FFI bindings.
52/// size: c_int,
53/// getname: unsafe extern "C" fn(
54/// ucd: *const c_void,
55/// code: Py_UCS4,
56/// buffer: *const c_char,
57/// buflen: c_int,
58/// with_alias_and_seq: c_int,
59/// ) -> c_int,
60/// getcode: unsafe extern "C" fn(
61/// ucd: *const c_void,
62/// name: *const c_char,
63/// namelen: c_int,
64/// code: *const Py_UCS4,
65/// ) -> c_int,
66/// }
67///
68/// #[derive(Debug, PartialEq)]
69/// pub enum UnicodeDataError {
70/// InvalidCode,
71/// UnknownName,
72/// }
73///
74/// impl unicode_name_CAPI {
75/// pub fn get_name(&self, code: Py_UCS4) -> Result<CString, UnicodeDataError> {
76/// let mut buf: Vec<c_char> = Vec::with_capacity(UNICODE_NAME_MAXLEN);
77/// let buf_ptr = buf.as_mut_ptr();
78/// if unsafe {
79/// ((*self).getname)(null(), code, buf_ptr, UNICODE_NAME_MAXLEN as c_int, 0)
80/// } != 1 {
81/// return Err(UnicodeDataError::InvalidCode);
82/// }
83/// mem::forget(buf);
84/// Ok(unsafe { CString::from_raw(buf_ptr) })
85/// }
86///
87/// pub fn get_code(&self, name: &CStr) -> Result<Py_UCS4, UnicodeDataError> {
88/// let namelen = name.to_bytes().len() as c_int;
89/// let mut code: [Py_UCS4; 1] = [0; 1];
90/// if unsafe {
91/// ((*self).getcode)(null(), name.as_ptr(), namelen, code.as_mut_ptr())
92/// } != 1 {
93/// return Err(UnicodeDataError::UnknownName);
94/// }
95/// Ok(code[0])
96/// }
97/// }
98///
99/// let gil = Python::acquire_gil();
100/// let py = gil.python();
101///
102/// let capi: &unicode_name_CAPI = unsafe {
103/// PyCapsule::import_data(
104/// py,
105/// CStr::from_bytes_with_nul_unchecked(b"unicodedata.ucnhash_CAPI\0"),
106/// )
107/// }
108/// .unwrap();
109///
110/// assert_eq!(capi.get_name(32).unwrap().to_str(), Ok("SPACE"));
111/// assert_eq!(capi.get_name(0), Err(UnicodeDataError::InvalidCode));
112///
113/// assert_eq!(
114/// capi.get_code(CStr::from_bytes_with_nul(b"COMMA\0").unwrap()),
115/// Ok(44)
116/// );
117/// assert_eq!(
118/// capi.get_code(CStr::from_bytes_with_nul(b"\0").unwrap()),
119/// Err(UnicodeDataError::UnknownName)
120/// );
121/// ```
122///
123/// ## Creating a capsule from Rust
124/// In this example, we enclose some data and a function in a capsule, using an intermediate
125/// `struct` as enclosing type, then retrieve them back and use them.
126///
127/// Warning: you definitely need to declare the data as `static`. If it's
128/// only `const`, it's possible it would get cloned elsewhere, with the orginal
129/// location being deallocated before it's actually used from another Python
130/// extension.
131///
132///
133/// ```
134/// use libc::{c_void, c_int};
135/// use cpython::{PyCapsule, Python};
136/// use std::ffi::{CStr, CString};
137///
138/// #[repr(C)]
139/// struct CapsData {
140/// value: c_int,
141/// fun: fn(c_int, c_int) -> c_int,
142/// }
143///
144/// fn add(a: c_int, b: c_int) -> c_int {
145/// a + b
146/// }
147///
148/// static DATA: CapsData = CapsData{value: 1, fun: add};
149///
150/// fn main() {
151/// let gil = Python::acquire_gil();
152/// let py = gil.python();
153/// let caps = PyCapsule::new_data(py, &DATA, "somemod.capsdata").unwrap();
154///
155/// let retrieved: &CapsData = unsafe {caps.data_ref("somemod.capsdata")}.unwrap();
156/// assert_eq!(retrieved.value, 1);
157/// assert_eq!((retrieved.fun)(2 as c_int, 3 as c_int), 5);
158/// }
159/// ```
160///
161/// Of course, a more realistic example would be to store the capsule in a Python module,
162/// allowing another extension (possibly foreign) to retrieve and use it.
163/// Note that in that case, the capsule `name` must be full dotted name of the capsule object,
164/// as we're doing here.
165/// ```
166/// # use libc::c_int;
167/// # use cpython::{PyCapsule, py_module_initializer};
168/// # #[repr(C)]
169/// # struct CapsData {
170/// # value: c_int,
171/// # fun: fn(c_int, c_int) -> c_int,
172/// # }
173/// # fn add(a: c_int, b: c_int) -> c_int {
174/// # a + b
175/// # }
176/// # static DATA: CapsData = CapsData{value: 1, fun: add};
177/// py_module_initializer!(somemod, |py, m| {
178/// m.add(py, "__doc__", "A module holding a capsule")?;
179/// m.add(py, "capsdata", PyCapsule::new_data(py, &DATA, "somemod.capsdata").unwrap())?;
180/// Ok(())
181/// });
182/// # fn main() {}
183/// ```
184/// Another Rust extension could then declare `CapsData` and use `PyCapsule::import_data` to
185/// fetch it back.
186///
187/// [`py_capsule!`]: macro.py_capsule.html
188pub struct PyCapsule(PyObject);
189
190pyobject_newtype!(PyCapsule, PyCapsule_CheckExact, PyCapsule_Type);
191
192/// Macro to retrieve a Python capsule pointing to an array of data, with a layer of caching.
193///
194/// For more details on capsules, see [`PyCapsule`]
195///
196/// The caller has to define an appropriate `repr(C)` `struct` first, and put it in
197/// scope (`use`) if needed along the macro invocation.
198///
199/// # Usage
200///
201/// ```ignore
202/// py_capsule!(from some.python.module import capsulename as rustmodule for CapsuleStruct)
203/// ```
204///
205/// where `CapsuleStruct` is the above mentioned `struct` defined by the caller.
206///
207/// The macro defines a Rust module named `rustmodule`, as specified by the caller.
208/// This module provides a retrieval function with the following signature:
209///
210/// ```ignore
211/// mod rustmodule {
212/// pub unsafe fn retrieve<'a>(py: Python) -> PyResult<&'a CapsuleStruct> { ... }
213/// }
214/// ```
215///
216/// The `retrieve()` function is unsafe for the same reasons as [`PyCapsule::import_data`],
217/// upon which it relies.
218///
219/// The newly defined module also contains a `RawPyObject` type suitable to represent C-level
220/// Python objects. It can be used in `cpython` public API involving raw FFI pointers, such as
221/// [`from_owned_ptr`].
222///
223/// # Examples
224/// ## Using a capsule from the standard library
225///
226/// This retrieves and uses one of the simplest capsules in the Python standard library, found in
227/// the `unicodedata` module. The C API enclosed in this capsule is the same for all Python
228/// versions supported by this crate.
229///
230/// In this case, as with all capsules from the Python standard library, the capsule data
231/// is an array (`static struct`) with constants and function pointers.
232/// ```no_run
233/// use cpython::{Python, PyCapsule, py_capsule};
234/// use libc::{c_char, c_int};
235/// use std::ffi::{c_void, CStr, CString};
236/// use std::mem;
237/// use std::ptr::null;
238///
239/// #[allow(non_camel_case_types)]
240/// type Py_UCS4 = u32;
241/// const UNICODE_NAME_MAXLEN: usize = 256;
242///
243/// #[repr(C)]
244/// pub struct unicode_name_CAPI {
245/// // the `ucd` signature arguments are actually optional (can be `NULL`) FFI PyObject
246/// // pointers used to pass alternate (former) versions of Unicode data.
247/// // We won't need to use them with an actual value in these examples, so it's enough to
248/// // specify them as `const c_void`, and it spares us a direct reference to the lower
249/// // level Python FFI bindings.
250/// size: c_int,
251/// getname: unsafe extern "C" fn(
252/// ucd: *const c_void,
253/// code: Py_UCS4,
254/// buffer: *const c_char,
255/// buflen: c_int,
256/// with_alias_and_seq: c_int,
257/// ) -> c_int,
258/// getcode: unsafe extern "C" fn(
259/// ucd: *const c_void,
260/// name: *const c_char,
261/// namelen: c_int,
262/// code: *const Py_UCS4,
263/// ) -> c_int,
264/// }
265///
266/// #[derive(Debug, PartialEq)]
267/// pub enum UnicodeDataError {
268/// InvalidCode,
269/// UnknownName,
270/// }
271///
272/// impl unicode_name_CAPI {
273/// pub fn get_name(&self, code: Py_UCS4) -> Result<CString, UnicodeDataError> {
274/// let mut buf: Vec<c_char> = Vec::with_capacity(UNICODE_NAME_MAXLEN);
275/// let buf_ptr = buf.as_mut_ptr();
276/// if unsafe {
277/// ((*self).getname)(null(), code, buf_ptr, UNICODE_NAME_MAXLEN as c_int, 0)
278/// } != 1 {
279/// return Err(UnicodeDataError::InvalidCode);
280/// }
281/// mem::forget(buf);
282/// Ok(unsafe { CString::from_raw(buf_ptr) })
283/// }
284///
285/// pub fn get_code(&self, name: &CStr) -> Result<Py_UCS4, UnicodeDataError> {
286/// let namelen = name.to_bytes().len() as c_int;
287/// let mut code: [Py_UCS4; 1] = [0; 1];
288/// if unsafe {
289/// ((*self).getcode)(null(), name.as_ptr(), namelen, code.as_mut_ptr())
290/// } != 1 {
291/// return Err(UnicodeDataError::UnknownName);
292/// }
293/// Ok(code[0])
294/// }
295/// }
296///
297/// py_capsule!(from unicodedata import ucnhash_CAPI as capsmod for unicode_name_CAPI);
298///
299/// fn main() {
300/// let gil = Python::acquire_gil();
301/// let py = gil.python();
302///
303/// let capi = unsafe { capsmod::retrieve(py).unwrap() };
304/// assert_eq!(capi.get_name(32).unwrap().to_str(), Ok("SPACE"));
305/// assert_eq!(capi.get_name(0), Err(UnicodeDataError::InvalidCode));
306///
307/// assert_eq!(capi.get_code(CStr::from_bytes_with_nul(b"COMMA\0").unwrap()), Ok(44));
308/// assert_eq!(capi.get_code(CStr::from_bytes_with_nul(b"\0").unwrap()),
309/// Err(UnicodeDataError::UnknownName));
310/// }
311/// ```
312///
313/// ## With Python objects
314///
315/// In this example, we lend a Python object and receive a new one of which we take ownership.
316///
317/// ```
318/// use cpython::{PyCapsule, PyObject, PyResult, Python, py_capsule};
319/// use libc::c_void;
320///
321/// // In the struct, we still have to use c_void for C-level Python objects.
322/// #[repr(C)]
323/// pub struct spawn_CAPI {
324/// spawnfrom: unsafe extern "C" fn(obj: *const c_void) -> *mut c_void,
325/// }
326///
327/// py_capsule!(from some.mod import CAPI as capsmod for spawn_CAPI);
328///
329/// impl spawn_CAPI {
330/// pub fn spawn_from(&self, py: Python, obj: PyObject) -> PyResult<PyObject> {
331/// let raw = obj.as_ptr() as *const c_void;
332/// Ok(unsafe {
333/// PyObject::from_owned_ptr(
334/// py,
335/// ((*self).spawnfrom)(raw) as *mut capsmod::RawPyObject)
336/// })
337/// }
338/// }
339///
340/// # fn main() {} // just to avoid confusion with use due to insertion of main() in doctests
341/// ```
342///
343/// [`PyCapsule`]: struct.PyCapsule.html
344/// [`PyCapsule::import_data`]: struct.PyCapsule.html#method.import_data
345#[macro_export]
346macro_rules! py_capsule {
347 (from $($capsmod:ident).+ import $capsname:ident as $rustmod:ident for $ruststruct: ident ) => (
348 mod $rustmod {
349 use super::*;
350 use std::sync::Once;
351 use $crate::PyClone;
352
353 static mut CAPS_DATA: Option<$crate::PyResult<&$ruststruct>> = None;
354
355 static INIT: Once = Once::new();
356
357 pub type RawPyObject = $crate::_detail::ffi::PyObject;
358
359 pub unsafe fn retrieve<'a>(py: $crate::Python) -> $crate::PyResult<&'a $ruststruct> {
360 INIT.call_once(|| {
361 let caps_name =
362 std::ffi::CStr::from_bytes_with_nul_unchecked(
363 concat!($( stringify!($capsmod), "."),*,
364 stringify!($capsname),
365 "\0").as_bytes());
366 CAPS_DATA = Some($crate::PyCapsule::import_data(py, caps_name));
367 });
368 match CAPS_DATA {
369 Some(Ok(d)) => Ok(d),
370 Some(Err(ref e)) => Err(e.clone_ref(py)),
371 _ => panic!("Uninitialized"), // can't happen
372 }
373 }
374 }
375 )
376}
377
378/// Macro to retrieve a function pointer capsule.
379///
380/// This is not suitable for architectures where the sizes of function and data pointers
381/// differ.
382/// For general explanations about capsules, see [`PyCapsule`].
383///
384/// # Usage
385///
386/// ```ignore
387/// py_capsule_fn!(from some.python.module import capsulename as rustmodule
388/// signature (args) -> ret_type)
389/// ```
390///
391/// Similarly to [py_capsule!](macro_py_capsule), the macro defines
392///
393/// - a Rust module according to the name provided by the caller (here, `rustmodule`)
394/// - a type alias for the given signature
395/// - a retrieval function:
396///
397/// ```ignore
398/// mod $rustmod {
399/// pub type CapsuleFn = unsafe extern "C" (args) -> ret_type ;
400/// pub unsafe fn retrieve<'a>(py: Python) -> PyResult<CapsuleFn) { ... }
401/// }
402/// ```
403/// - a `RawPyObject` type suitable for signatures that involve Python C objects;
404/// it can be used in `cpython` public API involving raw FFI pointers, such as
405/// [`from_owned_ptr`].
406///
407/// The first call to `retrieve()` is cached for subsequent calls.
408///
409/// # Examples
410/// ## Full example with primitive types
411/// There is in the Python library no capsule enclosing a function pointer directly,
412/// although the documentation presents it as a valid use-case. For this example, we'll
413/// therefore have to create one, using the [`PyCapsule`] constructor, and to set it in an
414/// existing module (not to imply that a real extension should follow that example
415/// and set capsules in modules they don't define!)
416///
417///
418/// ```
419/// use cpython::{PyCapsule, Python, FromPyObject, py_capsule_fn};
420/// use libc::{c_int, c_void};
421///
422/// extern "C" fn inc(a: c_int) -> c_int {
423/// a + 1
424/// }
425///
426/// /// for testing purposes, stores a capsule named `sys.capsfn`` pointing to `inc()`.
427/// fn create_capsule() {
428/// let gil = Python::acquire_gil();
429/// let py = gil.python();
430/// let pymod = py.import("sys").unwrap();
431/// let caps = PyCapsule::new(py, inc as *const c_void, "sys.capsfn").unwrap();
432/// pymod.add(py, "capsfn", caps).unwrap();
433/// }
434///
435/// py_capsule_fn!(from sys import capsfn as capsmod signature (a: c_int) -> c_int);
436///
437/// // One could, e.g., reexport if needed:
438/// pub use capsmod::CapsuleFn;
439///
440/// fn retrieve_use_capsule() {
441/// let gil = Python::acquire_gil();
442/// let py = gil.python();
443/// let fun = capsmod::retrieve(py).unwrap();
444/// assert_eq!( unsafe { fun(1) }, 2);
445///
446/// // let's demonstrate the (reexported) function type
447/// let g: CapsuleFn = fun;
448/// }
449///
450/// fn main() {
451/// create_capsule();
452/// retrieve_use_capsule();
453/// // second call uses the cached function pointer
454/// retrieve_use_capsule();
455/// }
456/// ```
457///
458/// ## With Python objects
459///
460/// In this example, we lend a Python object and receive a new one of which we take ownership.
461///
462/// ```
463/// use cpython::{PyCapsule, PyObject, PyResult, Python, py_capsule_fn};
464///
465/// py_capsule_fn!(from some.mod import capsfn as capsmod
466/// signature (raw: *mut RawPyObject) -> *mut RawPyObject);
467///
468/// fn retrieve_use_capsule(py: Python, obj: PyObject) -> PyResult<PyObject> {
469/// let fun = capsmod::retrieve(py)?;
470/// let raw = obj.as_ptr();
471/// Ok(unsafe { PyObject::from_owned_ptr(py, fun(raw)) })
472/// }
473///
474/// # fn main() {} // avoid problems with injection of declarations with Rust 1.25
475///
476/// ```
477///
478/// [`PyCapsule`]: struct.PyCapsule.html
479/// [`from_owned_ptr`]: struct.PyObject.html#method.from_owned_ptr`
480#[macro_export]
481macro_rules! py_capsule_fn {
482 (from $($capsmod:ident).+ import $capsname:ident as $rustmod:ident signature $( $sig: tt)* ) => (
483 mod $rustmod {
484 use super::*;
485 use std::sync::Once;
486 use $crate::PyClone;
487
488 pub type CapsuleFn = unsafe extern "C" fn $( $sig )*;
489 pub type RawPyObject = $crate::_detail::ffi::PyObject;
490
491 static mut CAPS_FN: Option<$crate::PyResult<CapsuleFn>> = None;
492
493 static INIT: Once = Once::new();
494
495 fn import(py: $crate::Python) -> $crate::PyResult<CapsuleFn> {
496 unsafe {
497 let caps_name =
498 std::ffi::CStr::from_bytes_with_nul_unchecked(
499 concat!($( stringify!($capsmod), "."),*,
500 stringify!($capsname),
501 "\0").as_bytes());
502 Ok(::std::mem::transmute($crate::PyCapsule::import(py, caps_name)?))
503 }
504 }
505
506 pub fn retrieve(py: $crate::Python) -> $crate::PyResult<CapsuleFn> {
507 unsafe {
508 INIT.call_once(|| { CAPS_FN = Some(import(py)) });
509 match CAPS_FN.as_ref().unwrap() {
510 &Ok(f) => Ok(f),
511 &Err(ref e) => Err(e.clone_ref(py)),
512 }
513 }
514 }
515 }
516 )
517}
518
519impl PyCapsule {
520 /// Retrieve the contents of a capsule pointing to some data as a reference.
521 ///
522 /// The retrieved data would typically be an array of static data and/or function pointers.
523 /// This method doesn't work for standalone function pointers.
524 ///
525 /// # Safety
526 /// This method is unsafe, because
527 /// - nothing guarantees that the `T` type is appropriate for the data referenced by the capsule
528 /// pointer
529 /// - the returned lifetime doesn't guarantee either to cover the actual lifetime of the data
530 /// (although capsule data is usually static)
531 pub unsafe fn import_data<'a, T>(py: Python, name: &CStr) -> PyResult<&'a T> {
532 Ok(&*(Self::import(py, name)? as *const T))
533 }
534
535 /// Retrieves the contents of a capsule as a void pointer by its name.
536 ///
537 /// This is suitable in particular for later conversion as a function pointer
538 /// with `mem::transmute`, for architectures where data and function pointers have
539 /// the same size (see details about this in the
540 /// [documentation](https://doc.rust-lang.org/std/mem/fn.transmute.html#examples)
541 /// of the Rust standard library).
542 pub fn import(py: Python, name: &CStr) -> PyResult<*const c_void> {
543 let caps_ptr = unsafe { PyCapsule_Import(name.as_ptr(), 0) };
544 if caps_ptr.is_null() {
545 return Err(PyErr::fetch(py));
546 }
547 Ok(caps_ptr)
548 }
549
550 /// Convenience method to create a capsule for some data
551 ///
552 /// The encapsuled data may be an array of functions, but it can't be itself a
553 /// function directly.
554 ///
555 /// May panic when running out of memory.
556 ///
557 pub fn new_data<T, N>(py: Python, data: &'static T, name: N) -> Result<Self, NulError>
558 where
559 N: Into<Vec<u8>>,
560 {
561 Self::new(py, data as *const T as *const c_void, name)
562 }
563
564 /// Creates a new capsule from a raw void pointer
565 ///
566 /// This is suitable in particular to store a function pointer in a capsule. These
567 /// can be obtained simply by a simple cast:
568 ///
569 /// ```
570 /// use libc::c_void;
571 ///
572 /// extern "C" fn inc(a: i32) -> i32 {
573 /// a + 1
574 /// }
575 ///
576 /// fn main() {
577 /// let ptr = inc as *const c_void;
578 /// }
579 /// ```
580 ///
581 /// # Errors
582 /// This method returns `NulError` if `name` contains a 0 byte (see also `CString::new`)
583 pub fn new<N>(py: Python, pointer: *const c_void, name: N) -> Result<Self, NulError>
584 where
585 N: Into<Vec<u8>>,
586 {
587 let name = CString::new(name)?;
588 let caps = unsafe {
589 Ok(err::cast_from_owned_ptr_or_panic(
590 py,
591 PyCapsule_New(pointer as *mut c_void, name.as_ptr(), None),
592 ))
593 };
594 // it is required that the capsule name outlives the call as a char*
595 // TODO implement a proper PyCapsule_Destructor to release it properly
596 mem::forget(name);
597 caps
598 }
599
600 /// Returns a reference to the capsule data.
601 ///
602 /// The name must match exactly the one given at capsule creation time (see `new_data`) and
603 /// is converted to a C string under the hood. If that's too much overhead, consider using
604 /// `data_ref_cstr()` or caching strategies.
605 ///
606 /// This is unsafe, because
607 /// - nothing guarantees that the `T` type is appropriate for the data referenced by the capsule
608 /// pointer
609 /// - the returned lifetime doesn't guarantee either to cover the actual lifetime of the data
610 /// (although capsule data is usually static)
611 ///
612 /// # Errors
613 /// This method returns `NulError` if `name` contains a 0 byte (see also `CString::new`)
614 pub unsafe fn data_ref<'a, T, N>(&self, name: N) -> Result<&'a T, NulError>
615 where
616 N: Into<Vec<u8>>,
617 {
618 Ok(self.data_ref_cstr(&CString::new(name)?))
619 }
620
621 /// Returns a reference to the capsule data.
622 ///
623 /// This is identical to `data_ref`, except for the name passing. This allows to use
624 /// lower level constructs without overhead, such as `CStr::from_bytes_with_nul_unchecked`
625 /// or the `cstr!` macro of `rust-cpython`
626 pub unsafe fn data_ref_cstr<'a, T>(&self, name: &CStr) -> &'a T {
627 &*(PyCapsule_GetPointer(self.as_ptr(), name.as_ptr()) as *const T)
628 }
629}