Skip to content

Commit b720681

Browse files
committed
PyClassImpl for PyClassMethod
1 parent 0a683f2 commit b720681

1 file changed

Lines changed: 28 additions & 8 deletions

File tree

vm/src/obj/objclassmethod.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
11
use super::objtype::PyClassRef;
2-
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
2+
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
33
use crate::vm::VirtualMachine;
44

5+
/// classmethod(function) -> method
6+
///
7+
/// Convert a function to be a class method.
8+
///
9+
/// A class method receives the class as implicit first argument,
10+
/// just like an instance method receives the instance.
11+
/// To declare a class method, use this idiom:
12+
///
13+
/// class C:
14+
/// @classmethod
15+
/// def f(cls, arg1, arg2, ...):
16+
/// ...
17+
///
18+
/// It can be called either on the class (e.g. C.f()) or on an instance
19+
/// (e.g. C().f()). The instance is ignored except for its class.
20+
/// If a class method is called for a derived class, the derived class
21+
/// object is passed as the implied first argument.
22+
///
23+
/// Class methods are different than C++ or Java static methods.
24+
/// If you want those, see the staticmethod builtin.
25+
#[pyclass]
526
#[derive(Clone, Debug)]
627
pub struct PyClassMethod {
728
pub callable: PyObjectRef,
@@ -16,7 +37,9 @@ impl PyValue for PyClassMethod {
1637
}
1738
}
1839

19-
impl PyClassMethodRef {
40+
#[pyimpl]
41+
impl PyClassMethod {
42+
#[pymethod(name = "__new__")]
2043
fn new(
2144
cls: PyClassRef,
2245
callable: PyObjectRef,
@@ -28,17 +51,14 @@ impl PyClassMethodRef {
2851
.into_ref_with_type(vm, cls)
2952
}
3053

31-
fn get(self, _inst: PyObjectRef, owner: PyObjectRef, vm: &VirtualMachine) -> PyResult {
54+
#[pymethod(name = "__get__")]
55+
fn get(&self, _inst: PyObjectRef, owner: PyObjectRef, vm: &VirtualMachine) -> PyResult {
3256
Ok(vm
3357
.ctx
3458
.new_bound_method(self.callable.clone(), owner.clone()))
3559
}
3660
}
3761

3862
pub fn init(context: &PyContext) {
39-
let classmethod_type = &context.classmethod_type;
40-
extend_class!(context, classmethod_type, {
41-
"__get__" => context.new_rustfunc(PyClassMethodRef::get),
42-
"__new__" => context.new_rustfunc(PyClassMethodRef::new)
43-
});
63+
PyClassMethod::extend_class(context, &context.classmethod_type);
4464
}

0 commit comments

Comments
 (0)