Skip to content

Commit 42ef202

Browse files
committed
Add: staticmethod __init__
- PyStaticMethod struct field type change - Adding a .lock() due to adding a lock method - builtinfunc.rs file change due to type change
1 parent 8b7a3ea commit 42ef202

File tree

2 files changed

+53
-31
lines changed

2 files changed

+53
-31
lines changed

vm/src/builtins/builtinfunc.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,9 @@ impl PyNativeFuncDef {
5555
ctx: &Context,
5656
class: &'static Py<PyType>,
5757
) -> PyRef<PyStaticMethod> {
58+
// TODO: classmethod_descriptor
5859
let callable = self.build_method(ctx, class).into();
59-
PyRef::new_ref(
60-
PyStaticMethod { callable },
61-
ctx.types.staticmethod_type.to_owned(),
62-
None,
63-
)
60+
PyStaticMethod::new_ref(callable, ctx)
6461
}
6562
}
6663

vm/src/builtins/staticmethod.rs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
use super::{PyStr, PyType, PyTypeRef};
1+
use super::{PyBoundMethod, PyStr, PyType, PyTypeRef};
22
use crate::{
33
builtins::builtinfunc::PyBuiltinMethod,
44
class::PyClassImpl,
5+
common::lock::PyMutex,
56
function::{FuncArgs, IntoPyNativeFunc},
67
types::{Callable, Constructor, GetDescriptor, Initializer},
7-
Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
8+
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
89
};
910

1011
#[pyclass(module = false, name = "staticmethod")]
11-
#[derive(Clone, Debug)]
12+
#[derive(Debug)]
1213
pub struct PyStaticMethod {
13-
pub callable: PyObjectRef,
14+
pub callable: PyMutex<PyObjectRef>,
1415
}
1516

1617
impl PyPayload for PyStaticMethod {
@@ -22,18 +23,25 @@ impl PyPayload for PyStaticMethod {
2223
impl GetDescriptor for PyStaticMethod {
2324
fn descr_get(
2425
zelf: PyObjectRef,
25-
_obj: Option<PyObjectRef>,
26-
_cls: Option<PyObjectRef>,
26+
obj: Option<PyObjectRef>,
27+
cls: Option<PyObjectRef>,
2728
vm: &VirtualMachine,
2829
) -> PyResult {
29-
let zelf = Self::_zelf(zelf, vm)?;
30-
Ok(zelf.callable.clone())
30+
let (zelf, _obj) = Self::_unwrap(zelf, obj, vm)?;
31+
let cls = cls.unwrap_or_else(|| _obj.class().clone().into());
32+
let call_descr_get: PyResult<PyObjectRef> = zelf.callable.lock().get_attr("__get__", vm);
33+
match call_descr_get {
34+
Err(_) => Ok(PyBoundMethod::new_ref(cls, zelf.callable.lock().clone(), &vm.ctx).into()),
35+
Ok(call_descr_get) => vm.invoke(&call_descr_get, (cls.clone(), cls)),
36+
}
3137
}
3238
}
3339

3440
impl From<PyObjectRef> for PyStaticMethod {
3541
fn from(callable: PyObjectRef) -> Self {
36-
Self { callable }
42+
Self {
43+
callable: PyMutex::new(callable),
44+
}
3745
}
3846
}
3947

@@ -43,7 +51,10 @@ impl Constructor for PyStaticMethod {
4351
fn py_new(cls: PyTypeRef, callable: Self::Args, vm: &VirtualMachine) -> PyResult {
4452
let doc = callable.get_attr("__doc__", vm);
4553

46-
let result = PyStaticMethod { callable }.into_ref_with_type(vm, cls)?;
54+
let result = PyStaticMethod {
55+
callable: PyMutex::new(callable),
56+
}
57+
.into_ref_with_type(vm, cls)?;
4758
let obj = PyObjectRef::from(result);
4859

4960
if let Ok(doc) = doc {
@@ -54,6 +65,18 @@ impl Constructor for PyStaticMethod {
5465
}
5566
}
5667

68+
impl PyStaticMethod {
69+
pub fn new_ref(callable: PyObjectRef, ctx: &Context) -> PyRef<Self> {
70+
PyRef::new_ref(
71+
Self {
72+
callable: PyMutex::new(callable),
73+
},
74+
ctx.types.staticmethod_type.to_owned(),
75+
None,
76+
)
77+
}
78+
}
79+
5780
impl PyStaticMethod {
5881
pub fn new_builtin_ref<F, FKind>(
5982
name: impl Into<PyStr>,
@@ -66,7 +89,9 @@ impl PyStaticMethod {
6689
{
6790
let callable = PyBuiltinMethod::new_ref(name, class, f, ctx).into();
6891
PyRef::new_ref(
69-
Self { callable },
92+
Self {
93+
callable: PyMutex::new(callable),
94+
},
7095
ctx.types.staticmethod_type.to_owned(),
7196
None,
7297
)
@@ -76,49 +101,47 @@ impl PyStaticMethod {
76101
impl Initializer for PyStaticMethod {
77102
type Args = PyObjectRef;
78103

79-
fn init(_zelf: PyRef<Self>, _func: Self::Args, _vm: &VirtualMachine) -> PyResult<()> {
104+
fn init(zelf: PyRef<Self>, callable: Self::Args, _vm: &VirtualMachine) -> PyResult<()> {
105+
*zelf.callable.lock() = callable;
80106
Ok(())
81107
}
82108
}
83109

84-
#[pyclass(
85-
with(Callable, GetDescriptor, Constructor, Initializer),
86-
flags(BASETYPE, HAS_DICT)
87-
)]
110+
#[pyclass(with(Callable, Constructor, Initializer), flags(BASETYPE, HAS_DICT))]
88111
impl PyStaticMethod {
89112
#[pyproperty(magic)]
90113
fn func(&self) -> PyObjectRef {
91-
self.callable.clone()
114+
self.callable.lock().clone()
92115
}
93116

94117
#[pyproperty(magic)]
95118
fn wrapped(&self) -> PyObjectRef {
96-
self.callable.clone()
119+
self.callable.lock().clone()
97120
}
98121

99122
#[pyproperty(magic)]
100123
fn module(&self, vm: &VirtualMachine) -> PyResult {
101-
self.callable.get_attr("__module__", vm)
124+
self.callable.lock().get_attr("__module__", vm)
102125
}
103126

104127
#[pyproperty(magic)]
105128
fn qualname(&self, vm: &VirtualMachine) -> PyResult {
106-
self.callable.get_attr("__qualname__", vm)
129+
self.callable.lock().get_attr("__qualname__", vm)
107130
}
108131

109132
#[pyproperty(magic)]
110133
fn name(&self, vm: &VirtualMachine) -> PyResult {
111-
self.callable.get_attr("__name__", vm)
134+
self.callable.lock().get_attr("__name__", vm)
112135
}
113136

114137
#[pyproperty(magic)]
115138
fn annotations(&self, vm: &VirtualMachine) -> PyResult {
116-
self.callable.get_attr("__annotations__", vm)
139+
self.callable.lock().get_attr("__annotations__", vm)
117140
}
118141

119142
#[pymethod(magic)]
120143
fn repr(&self, vm: &VirtualMachine) -> Option<String> {
121-
let callable = self.callable.repr(vm).unwrap();
144+
let callable = self.callable.lock().repr(vm).unwrap();
122145
let class = Self::class(vm);
123146

124147
match (
@@ -138,15 +161,17 @@ impl PyStaticMethod {
138161

139162
#[pyproperty(magic)]
140163
fn isabstractmethod(&self, vm: &VirtualMachine) -> PyObjectRef {
141-
match vm.get_attribute_opt(self.callable.clone(), "__isabstractmethod__") {
164+
match vm.get_attribute_opt(self.callable.lock().clone(), "__isabstractmethod__") {
142165
Ok(Some(is_abstract)) => is_abstract,
143166
_ => vm.ctx.new_bool(false).into(),
144167
}
145168
}
146169

147170
#[pyproperty(magic, setter)]
148171
fn set_isabstractmethod(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
149-
self.callable.set_attr("__isabstractmethod__", value, vm)?;
172+
self.callable
173+
.lock()
174+
.set_attr("__isabstractmethod__", value, vm)?;
150175
Ok(())
151176
}
152177
}
@@ -155,7 +180,7 @@ impl Callable for PyStaticMethod {
155180
type Args = FuncArgs;
156181
#[inline]
157182
fn call(zelf: &crate::Py<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
158-
vm.invoke(&zelf.callable, args)
183+
vm.invoke(&zelf.callable.lock().clone(), args)
159184
}
160185
}
161186

0 commit comments

Comments
 (0)