mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
feat: reuse weak callable proxy (#8618)
This commit is contained in:
1 parent
2c8d3ce50b
commit
8b65a5455f
6 files changed
+39
-8
No files matched your search
Vendored
-1
@@ -403,7 +403,6 @@ class ReferencesTestCase(TestBase):
|
||||
p2 = makeref(o)
|
||||
self.assertIs(p1, p2, "callbacks were None, NULL in the C API")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_callable_proxy(self):
|
||||
o = Callable()
|
||||
ref1 = weakref.proxy(o)
|
||||
|
||||
@@ -90,7 +90,7 @@ pub use traceback::PyTraceback;
|
||||
pub(crate) mod tuple;
|
||||
pub use tuple::{PyTuple, PyTupleRef};
|
||||
pub(crate) mod weakproxy;
|
||||
pub use weakproxy::PyWeakProxy;
|
||||
pub use weakproxy::{PyWeakCallableProxy, PyWeakProxy};
|
||||
pub(crate) mod weakref;
|
||||
pub use weakref::PyWeak;
|
||||
pub(crate) mod zip;
|
||||
|
||||
@@ -8,8 +8,8 @@ use crate::{
|
||||
protocol::{PyIter, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
|
||||
stdlib::builtins::reversed,
|
||||
types::{
|
||||
AsMapping, AsNumber, AsSequence, Comparable, Constructor, GetAttr, Hashable, IterNext,
|
||||
Iterable, PyComparisonOp, Representable, SetAttr,
|
||||
AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, GetAttr, Hashable,
|
||||
IterNext, Iterable, PyComparisonOp, Representable, SetAttr,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -67,7 +67,11 @@ impl PyWeakProxy {
|
||||
callback: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<PyWeak>> {
|
||||
let typ = vm.ctx.types.weakproxy_type.to_owned();
|
||||
let typ = if referent.is_callable() {
|
||||
vm.ctx.types.weakcallableproxy_type.to_owned()
|
||||
} else {
|
||||
vm.ctx.types.weakproxy_type.to_owned()
|
||||
};
|
||||
referent.downgrade_with_typ(callback, typ, vm)
|
||||
}
|
||||
|
||||
@@ -77,6 +81,28 @@ impl PyWeakProxy {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
module = false,
|
||||
name = "weakcallableproxy",
|
||||
base = PyWeakProxy,
|
||||
ctx = "weakcallableproxy_type",
|
||||
unhashable = true
|
||||
)]
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct PyWeakCallableProxy(PyWeakProxy);
|
||||
|
||||
#[pyclass(with(Callable))]
|
||||
impl PyWeakCallableProxy {}
|
||||
|
||||
impl Callable for PyWeakCallableProxy {
|
||||
type Args = FuncArgs;
|
||||
|
||||
fn call(zelf: &Py<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
zelf.0.try_upgrade(vm)?.call(args, vm)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(
|
||||
GetAttr,
|
||||
SetAttr,
|
||||
@@ -371,6 +397,7 @@ impl Representable for PyWeakProxy {
|
||||
|
||||
pub(crate) fn init(context: &'static Context) {
|
||||
PyWeakProxy::extend_class(context, context.types.weakproxy_type);
|
||||
PyWeakCallableProxy::extend_class(context, context.types.weakcallableproxy_type);
|
||||
}
|
||||
|
||||
impl Hashable for PyWeakProxy {
|
||||
|
||||
@@ -771,10 +771,12 @@ impl WeakRefList {
|
||||
Some(candidate) => {
|
||||
let node = unsafe { candidate.as_ref() };
|
||||
let has_callback = unsafe { (&*node.0.payload.callback.get()).is_some() };
|
||||
let node_cls = node.class();
|
||||
// PyWeakref_CheckProxy: the basic-proxy slot is reserved for
|
||||
// the canonical proxy type; subclasses and callback-less ref
|
||||
// subclasses must not be mistaken for it.
|
||||
let is_proxy = node.class().is(crate::builtins::PyWeakProxy::static_type());
|
||||
let is_proxy = node_cls.is(crate::builtins::PyWeakProxy::static_type())
|
||||
|| node_cls.is(crate::builtins::PyWeakCallableProxy::static_type());
|
||||
if has_callback || !is_proxy {
|
||||
ptr::null_mut()
|
||||
} else {
|
||||
@@ -1602,7 +1604,8 @@ impl PyObject {
|
||||
None
|
||||
};
|
||||
let cls_is_weakref = typ.is(vm.ctx.types.weakref_type);
|
||||
let cls_is_weakproxy = typ.is(vm.ctx.types.weakproxy_type);
|
||||
let cls_is_weakproxy =
|
||||
typ.is(vm.ctx.types.weakproxy_type) || typ.is(vm.ctx.types.weakcallableproxy_type);
|
||||
let wrl = self.weak_ref_list().ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"cannot create weak reference to '{}' object",
|
||||
|
||||
@@ -35,7 +35,7 @@ mod _weakref {
|
||||
|
||||
#[pyattr(name = "CallableProxyType")]
|
||||
fn callable_proxy_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakproxy_type.to_owned()
|
||||
vm.ctx.types.weakcallableproxy_type.to_owned()
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
@@ -86,6 +86,7 @@ pub struct TypeZoo {
|
||||
pub bound_method_type: &'static Py<PyType>,
|
||||
pub weakref_type: &'static Py<PyType>,
|
||||
pub weakproxy_type: &'static Py<PyType>,
|
||||
pub weakcallableproxy_type: &'static Py<PyType>,
|
||||
pub mappingproxy_type: &'static Py<PyType>,
|
||||
pub traceback_type: &'static Py<PyType>,
|
||||
pub object_type: &'static Py<PyType>,
|
||||
@@ -198,6 +199,7 @@ impl TypeZoo {
|
||||
traceback_type: traceback::PyTraceback::init_builtin_type(),
|
||||
tuple_iterator_type: tuple::PyTupleIterator::init_builtin_type(),
|
||||
weakproxy_type: weakproxy::PyWeakProxy::init_builtin_type(),
|
||||
weakcallableproxy_type: weakproxy::PyWeakCallableProxy::init_builtin_type(),
|
||||
method_descriptor_type: descriptor::PyMethodDescriptor::init_builtin_type(),
|
||||
none_type: singletons::PyNone::init_builtin_type(),
|
||||
typing_no_default_type: crate::stdlib::_typing::NoDefault::init_builtin_type(),
|
||||
|
||||
Reference in new issue
Block a user