11use super :: objtype:: PyClassRef ;
2- use crate :: pyobject:: { PyContext , PyObjectRef , PyRef , PyResult , PyValue } ;
2+ use crate :: pyobject:: { PyClassImpl , PyContext , PyObjectRef , PyRef , PyResult , PyValue } ;
33use 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 ) ]
627pub 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
3862pub 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