mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Allow creating PyCapsule objects (#7595)
This commit is contained in:
1 parent
76755524df
commit
4875323705
2 files changed
+51
-11
No files matched your search
@@ -1,14 +1,19 @@
|
||||
use super::PyType;
|
||||
use crate::{Context, Py, PyPayload, PyResult, class::PyClassImpl, types::Representable};
|
||||
use crate::{
|
||||
AsObject, Context, Py, PyObject, PyPayload, PyResult, VirtualMachine,
|
||||
class::PyClassImpl,
|
||||
types::{Destructor, Representable},
|
||||
};
|
||||
use core::ffi::c_void;
|
||||
use core::sync::atomic::AtomicPtr;
|
||||
|
||||
/// PyCapsule - a container for C pointers.
|
||||
/// In RustPython, this is a minimal implementation for compatibility.
|
||||
#[pyclass(module = false, name = "PyCapsule")]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug)]
|
||||
pub struct PyCapsule {
|
||||
// Capsules store opaque pointers; we don't expose the actual pointer functionality
|
||||
// since RustPython doesn't have the same C extension model as CPython.
|
||||
_private: (),
|
||||
ptr: AtomicPtr<c_void>,
|
||||
destructor: Option<unsafe extern "C" fn(_: *mut PyObject)>,
|
||||
}
|
||||
|
||||
impl PyPayload for PyCapsule {
|
||||
@@ -18,8 +23,26 @@ impl PyPayload for PyCapsule {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Representable), flags(DISALLOW_INSTANTIATION))]
|
||||
impl PyCapsule {}
|
||||
#[pyclass(with(Representable, Destructor), flags(DISALLOW_INSTANTIATION))]
|
||||
impl PyCapsule {
|
||||
pub fn new(
|
||||
ptr: *mut c_void,
|
||||
destructor: Option<unsafe extern "C" fn(_: *mut PyObject)>,
|
||||
) -> Self {
|
||||
Self {
|
||||
ptr: ptr.into(),
|
||||
destructor,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pointer(&self) -> *mut c_void {
|
||||
self.ptr.load(core::sync::atomic::Ordering::Relaxed)
|
||||
}
|
||||
|
||||
fn destructor(&self) -> Option<unsafe extern "C" fn(_: *mut PyObject)> {
|
||||
self.destructor
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyCapsule {
|
||||
#[inline]
|
||||
@@ -28,6 +51,15 @@ impl Representable for PyCapsule {
|
||||
}
|
||||
}
|
||||
|
||||
impl Destructor for PyCapsule {
|
||||
fn del(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
if let Some(destructor) = zelf.destructor() {
|
||||
unsafe { destructor(zelf.as_object().as_raw().cast_mut()) };
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &'static Context) {
|
||||
PyCapsule::extend_class(context, context.types.capsule_type);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
PyResult, VirtualMachine,
|
||||
PyObject, PyResult, VirtualMachine,
|
||||
builtins::{
|
||||
PyByteArray, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet,
|
||||
PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyStrInterned,
|
||||
PyTuple, PyTupleRef, PyType, PyTypeRef, PyUtf8Str,
|
||||
PyByteArray, PyBytes, PyCapsule, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat,
|
||||
PyFrozenSet, PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr,
|
||||
PyStrInterned, PyTuple, PyTupleRef, PyType, PyTypeRef, PyUtf8Str,
|
||||
bool_::PyBool,
|
||||
code::{self, PyCode},
|
||||
descriptor::{
|
||||
@@ -752,6 +752,14 @@ impl Context {
|
||||
let code = code.into_code_object(self);
|
||||
PyRef::new_ref(PyCode::new(code), self.types.code_type.to_owned(), None)
|
||||
}
|
||||
|
||||
pub fn new_capsule(
|
||||
&self,
|
||||
ptr: *mut core::ffi::c_void,
|
||||
destructor: Option<unsafe extern "C" fn(_: *mut PyObject)>,
|
||||
) -> PyRef<PyCapsule> {
|
||||
PyCapsule::new(ptr, destructor).into_ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Self> for Context {
|
||||
|
||||
Reference in new issue
Block a user