@@ -24,6 +24,7 @@ pub fn init(context: &PyContext) {
2424 type_type. set_attr ( "__new__" , context. new_rustfunc ( type_new) ) ;
2525 type_type. set_attr ( "__mro__" , context. new_member_descriptor ( type_mro) ) ;
2626 type_type. set_attr ( "__class__" , context. new_member_descriptor ( type_new) ) ;
27+ type_type. set_attr ( "__str__" , context. new_rustfunc ( type_str) ) ;
2728}
2829
2930fn type_mro ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -54,6 +55,14 @@ pub fn issubclass(typ: PyObjectRef, cls: PyObjectRef) -> bool {
5455 mro. into_iter ( ) . any ( |c| c. is ( & cls) )
5556}
5657
58+ pub fn get_type_name ( typ : & PyObjectRef ) -> String {
59+ if let PyObjectKind :: Class { name, dict : _, mro : _ } = & typ. borrow ( ) . kind {
60+ name. clone ( )
61+ } else {
62+ panic ! ( "Cannot get type_name of non-type type" ) ;
63+ }
64+ }
65+
5766pub fn type_new ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
5867 debug ! ( "type.__new__{:?}" , args) ;
5968 if args. args . len ( ) == 2 {
@@ -170,6 +179,14 @@ pub fn new(typ: PyObjectRef, name: &str, bases: Vec<PyObjectRef>, dict: PyObject
170179 ) )
171180}
172181
182+ fn type_str ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
183+ // TODO: fix macro:
184+ // arg_check!(vm, args, required = [(obj, Some(vm.ctx.type_type()))]);
185+ let obj = args. args [ 0 ] . clone ( ) ;
186+ let type_name = get_type_name ( & obj) ;
187+ Ok ( vm. new_str ( format ! ( "<class '{}'>" , type_name) ) )
188+ }
189+
173190pub fn call ( vm : & mut VirtualMachine , typ : PyObjectRef , args : PyFuncArgs ) -> PyResult {
174191 let function = get_attribute ( vm, typ, & String :: from ( "__call__" ) ) ?;
175192 vm. invoke ( function, args)
0 commit comments