mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
tp_del
This commit is contained in:
1 parent
9e71cb3bcc
commit
d9b1ae296b
5 files changed
+43
-6
No files matched your search
+5
-2
@@ -47,11 +47,14 @@ macro_rules! py_class {
|
||||
py_class
|
||||
}
|
||||
};
|
||||
(@extract_slots($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {
|
||||
$slots.$slot_name = Some(
|
||||
(@extract_slots($ctx:expr, $slots:expr, (slot new), $value:expr)) => {
|
||||
$slots.new = Some(
|
||||
$crate::function::IntoPyNativeFunc::into_func($value)
|
||||
);
|
||||
};
|
||||
(@extract_slots($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {
|
||||
$slots.$slot_name.store(Some($value));
|
||||
};
|
||||
(@extract_slots($ctx:expr, $class:expr, $name:expr, $value:expr)) => {};
|
||||
(@extract_attrs($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {};
|
||||
(@extract_attrs($ctx:expr, $class:expr, $name:expr, $value:expr)) => {
|
||||
|
||||
@@ -150,6 +150,13 @@ impl PyClassRef {
|
||||
} as _;
|
||||
self.slots.hash.store(Some(func));
|
||||
}
|
||||
"__del__" => {
|
||||
let func: slots::DelFunc = |zelf, vm| {
|
||||
let magic = get_class_magic(&zelf, "__del__");
|
||||
vm.invoke(&magic, vec![zelf.clone()]).map(|_| ())
|
||||
} as _;
|
||||
self.slots.del.store(Some(func));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,11 +146,12 @@ where
|
||||
|
||||
// CPython-compatible drop implementation
|
||||
let zelf = Self::into_ref(self.clone());
|
||||
if let Some(del_method) = zelf.inner.get_class_attr("__del__") {
|
||||
if let Some(del_slot) = zelf.class().first_in_mro(|cls| cls.slots.del.load()) {
|
||||
crate::vm::thread::with_vm(&zelf, |vm| {
|
||||
if let Err(e) = vm.invoke(&del_method, vec![zelf.clone()]) {
|
||||
if let Err(e) = del_slot(&zelf, vm) {
|
||||
// exception in del will be ignored but printed
|
||||
print!("Exception ignored in: ",);
|
||||
let del_method = zelf.get_class_attr("__del__").unwrap();
|
||||
let repr = vm.to_repr(&del_method);
|
||||
match repr {
|
||||
Ok(v) => println!("{}", v.to_string()),
|
||||
|
||||
@@ -41,6 +41,7 @@ impl Default for PyTpFlags {
|
||||
}
|
||||
|
||||
pub(crate) type GenericMethod = fn(PyObjectRef, PyFuncArgs, &VirtualMachine) -> PyResult;
|
||||
pub(crate) type DelFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<()>;
|
||||
pub(crate) type DescrGetFunc =
|
||||
fn(PyObjectRef, Option<PyObjectRef>, Option<PyObjectRef>, &VirtualMachine) -> PyResult;
|
||||
pub(crate) type HashFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<PyHash>;
|
||||
@@ -50,6 +51,7 @@ pub struct PyClassSlots {
|
||||
pub flags: PyTpFlags,
|
||||
pub name: PyRwLock<Option<String>>, // tp_name, not class name
|
||||
pub new: Option<PyNativeFunc>,
|
||||
pub del: AtomicCell<Option<DelFunc>>,
|
||||
pub call: AtomicCell<Option<GenericMethod>>,
|
||||
pub descr_get: AtomicCell<Option<DescrGetFunc>>,
|
||||
pub hash: AtomicCell<Option<HashFunc>>,
|
||||
@@ -82,6 +84,25 @@ impl std::fmt::Debug for PyClassSlots {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
pub trait SlotDesctuctor: PyValue {
|
||||
#[pyslot]
|
||||
fn tp_del(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
if let Some(zelf) = zelf.downcast_ref() {
|
||||
Self::del(zelf, vm)
|
||||
} else {
|
||||
Err(vm.new_type_error("unexpected payload for __del__".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn __del__(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
Self::del(&zelf, vm)
|
||||
}
|
||||
|
||||
fn del(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<()>;
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
pub trait SlotCall: PyValue {
|
||||
#[pymethod(magic)]
|
||||
|
||||
+7
-2
@@ -416,11 +416,15 @@ fn io_base_cm_enter(instance: PyObjectRef) -> PyObjectRef {
|
||||
instance
|
||||
}
|
||||
|
||||
fn io_base_cm_del(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
vm.call_method(&instance, "close", vec![])?;
|
||||
fn io_base_cm_del_slot(instance: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
vm.call_method(instance, "close", vec![])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn io_base_cm_del(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
io_base_cm_del_slot(&instance, vm)
|
||||
}
|
||||
|
||||
fn io_base_cm_exit(instance: PyObjectRef, _args: PyFuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
vm.call_method(&instance, "close", vec![])?;
|
||||
Ok(())
|
||||
@@ -1271,6 +1275,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let io_base = py_class!(ctx, "_IOBase", &ctx.types.object_type, {
|
||||
"__enter__" => ctx.new_method(io_base_cm_enter),
|
||||
"__del__" => ctx.new_method(io_base_cm_del),
|
||||
(slot del) => io_base_cm_del_slot,
|
||||
"__exit__" => ctx.new_method(io_base_cm_exit),
|
||||
"seekable" => ctx.new_method(io_base_seekable),
|
||||
"readable" => ctx.new_method(io_base_readable),
|
||||
|
||||
Reference in new issue
Block a user