@@ -23,7 +23,9 @@ use crate::{
2323 identifier,
2424 object:: { Traverse , TraverseFn } ,
2525 protocol:: { PyIterReturn , PyMappingMethods , PyNumberMethods , PySequenceMethods } ,
26- types:: { AsNumber , Callable , GetAttr , PyTypeFlags , PyTypeSlots , Representable , SetAttr } ,
26+ types:: {
27+ AsNumber , Callable , Constructor , GetAttr , PyTypeFlags , PyTypeSlots , Representable , SetAttr ,
28+ } ,
2729 AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject ,
2830 VirtualMachine ,
2931} ;
@@ -470,7 +472,7 @@ impl Py<PyType> {
470472}
471473
472474#[ pyclass(
473- with( Py , GetAttr , SetAttr , Callable , AsNumber , Representable ) ,
475+ with( Py , Constructor , GetAttr , SetAttr , Callable , AsNumber , Representable ) ,
474476 flags( BASETYPE )
475477) ]
476478impl PyType {
@@ -728,8 +730,66 @@ impl PyType {
728730 or_ ( zelf, other, vm)
729731 }
730732
731- #[ pyslot]
732- fn slot_new ( metatype : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
733+ #[ pygetset( magic) ]
734+ fn dict ( zelf : PyRef < Self > ) -> PyMappingProxy {
735+ PyMappingProxy :: from ( zelf)
736+ }
737+
738+ #[ pygetset( magic, setter) ]
739+ fn set_dict ( & self , _value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
740+ Err ( vm. new_not_implemented_error (
741+ "Setting __dict__ attribute on a type isn't yet implemented" . to_owned ( ) ,
742+ ) )
743+ }
744+
745+ fn check_set_special_type_attr (
746+ & self ,
747+ _value : & PyObject ,
748+ name : & PyStrInterned ,
749+ vm : & VirtualMachine ,
750+ ) -> PyResult < ( ) > {
751+ if self . slots . flags . has_feature ( PyTypeFlags :: IMMUTABLETYPE ) {
752+ return Err ( vm. new_type_error ( format ! (
753+ "cannot set '{}' attribute of immutable type '{}'" ,
754+ name,
755+ self . slot_name( )
756+ ) ) ) ;
757+ }
758+ Ok ( ( ) )
759+ }
760+
761+ #[ pygetset( magic, setter) ]
762+ fn set_name ( & self , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
763+ self . check_set_special_type_attr ( & value, identifier ! ( vm, __name__) , vm) ?;
764+ let name = value. downcast :: < PyStr > ( ) . map_err ( |value| {
765+ vm. new_type_error ( format ! (
766+ "can only assign string to {}.__name__, not '{}'" ,
767+ self . slot_name( ) ,
768+ value. class( ) . slot_name( ) ,
769+ ) )
770+ } ) ?;
771+ if name. as_str ( ) . as_bytes ( ) . contains ( & 0 ) {
772+ return Err ( vm. new_value_error ( "type name must not contain null characters" . to_owned ( ) ) ) ;
773+ }
774+
775+ * self . heaptype_ext . as_ref ( ) . unwrap ( ) . name . write ( ) = name;
776+
777+ Ok ( ( ) )
778+ }
779+
780+ #[ pygetset( magic) ]
781+ fn text_signature ( & self ) -> Option < String > {
782+ self . slots
783+ . doc
784+ . and_then ( |doc| get_text_signature_from_internal_doc ( & self . name ( ) , doc) )
785+ . map ( |signature| signature. to_string ( ) )
786+ }
787+ }
788+
789+ impl Constructor for PyType {
790+ type Args = FuncArgs ;
791+
792+ fn py_new ( metatype : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
733793 vm_trace ! ( "type.__new__ {:?}" , args) ;
734794
735795 let is_type_type = metatype. is ( vm. ctx . types . type_type ) ;
@@ -976,100 +1036,6 @@ impl PyType {
9761036
9771037 Ok ( typ. into ( ) )
9781038 }
979-
980- #[ pygetset( magic) ]
981- fn dict ( zelf : PyRef < Self > ) -> PyMappingProxy {
982- PyMappingProxy :: from ( zelf)
983- }
984-
985- #[ pygetset( magic, setter) ]
986- fn set_dict ( & self , _value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
987- Err ( vm. new_not_implemented_error (
988- "Setting __dict__ attribute on a type isn't yet implemented" . to_owned ( ) ,
989- ) )
990- }
991-
992- fn check_set_special_type_attr (
993- & self ,
994- _value : & PyObject ,
995- name : & PyStrInterned ,
996- vm : & VirtualMachine ,
997- ) -> PyResult < ( ) > {
998- if self . slots . flags . has_feature ( PyTypeFlags :: IMMUTABLETYPE ) {
999- return Err ( vm. new_type_error ( format ! (
1000- "cannot set '{}' attribute of immutable type '{}'" ,
1001- name,
1002- self . slot_name( )
1003- ) ) ) ;
1004- }
1005- Ok ( ( ) )
1006- }
1007-
1008- #[ pygetset( magic, setter) ]
1009- fn set_name ( & self , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
1010- self . check_set_special_type_attr ( & value, identifier ! ( vm, __name__) , vm) ?;
1011- let name = value. downcast :: < PyStr > ( ) . map_err ( |value| {
1012- vm. new_type_error ( format ! (
1013- "can only assign string to {}.__name__, not '{}'" ,
1014- self . slot_name( ) ,
1015- value. class( ) . slot_name( ) ,
1016- ) )
1017- } ) ?;
1018- if name. as_str ( ) . as_bytes ( ) . contains ( & 0 ) {
1019- return Err ( vm. new_value_error ( "type name must not contain null characters" . to_owned ( ) ) ) ;
1020- }
1021-
1022- * self . heaptype_ext . as_ref ( ) . unwrap ( ) . name . write ( ) = name;
1023-
1024- Ok ( ( ) )
1025- }
1026-
1027- #[ pygetset( magic) ]
1028- fn text_signature ( & self ) -> Option < String > {
1029- self . slots
1030- . doc
1031- . and_then ( |doc| get_text_signature_from_internal_doc ( & self . name ( ) , doc) )
1032- . map ( |signature| signature. to_string ( ) )
1033- }
1034- }
1035-
1036- #[ pyclass]
1037- impl Py < PyType > {
1038- #[ pygetset( name = "__mro__" ) ]
1039- fn get_mro ( & self ) -> PyTuple {
1040- let elements: Vec < PyObjectRef > = self . mro_map_collect ( |x| x. as_object ( ) . to_owned ( ) ) ;
1041- PyTuple :: new_unchecked ( elements. into_boxed_slice ( ) )
1042- }
1043-
1044- #[ pymethod( magic) ]
1045- fn dir ( & self ) -> PyList {
1046- let attributes: Vec < PyObjectRef > = self
1047- . get_attributes ( )
1048- . into_iter ( )
1049- . map ( |( k, _) | k. to_object ( ) )
1050- . collect ( ) ;
1051- PyList :: from ( attributes)
1052- }
1053-
1054- #[ pymethod( magic) ]
1055- fn instancecheck ( & self , obj : PyObjectRef ) -> bool {
1056- obj. fast_isinstance ( self )
1057- }
1058-
1059- #[ pymethod( magic) ]
1060- fn subclasscheck ( & self , subclass : PyTypeRef ) -> bool {
1061- subclass. fast_issubclass ( self )
1062- }
1063-
1064- #[ pyclassmethod( magic) ]
1065- fn subclasshook ( _args : FuncArgs , vm : & VirtualMachine ) -> PyObjectRef {
1066- vm. ctx . not_implemented ( )
1067- }
1068-
1069- #[ pymethod]
1070- fn mro ( & self ) -> Vec < PyObjectRef > {
1071- self . mro_map_collect ( |cls| cls. to_owned ( ) . into ( ) )
1072- }
10731039}
10741040
10751041const SIGNATURE_END_MARKER : & str = ")\n --\n \n " ;
@@ -1143,6 +1109,45 @@ impl GetAttr for PyType {
11431109 }
11441110}
11451111
1112+ #[ pyclass]
1113+ impl Py < PyType > {
1114+ #[ pygetset( name = "__mro__" ) ]
1115+ fn get_mro ( & self ) -> PyTuple {
1116+ let elements: Vec < PyObjectRef > = self . mro_map_collect ( |x| x. as_object ( ) . to_owned ( ) ) ;
1117+ PyTuple :: new_unchecked ( elements. into_boxed_slice ( ) )
1118+ }
1119+
1120+ #[ pymethod( magic) ]
1121+ fn dir ( & self ) -> PyList {
1122+ let attributes: Vec < PyObjectRef > = self
1123+ . get_attributes ( )
1124+ . into_iter ( )
1125+ . map ( |( k, _) | k. to_object ( ) )
1126+ . collect ( ) ;
1127+ PyList :: from ( attributes)
1128+ }
1129+
1130+ #[ pymethod( magic) ]
1131+ fn instancecheck ( & self , obj : PyObjectRef ) -> bool {
1132+ obj. fast_isinstance ( self )
1133+ }
1134+
1135+ #[ pymethod( magic) ]
1136+ fn subclasscheck ( & self , subclass : PyTypeRef ) -> bool {
1137+ subclass. fast_issubclass ( self )
1138+ }
1139+
1140+ #[ pyclassmethod( magic) ]
1141+ fn subclasshook ( _args : FuncArgs , vm : & VirtualMachine ) -> PyObjectRef {
1142+ vm. ctx . not_implemented ( )
1143+ }
1144+
1145+ #[ pymethod]
1146+ fn mro ( & self ) -> Vec < PyObjectRef > {
1147+ self . mro_map_collect ( |cls| cls. to_owned ( ) . into ( ) )
1148+ }
1149+ }
1150+
11461151impl SetAttr for PyType {
11471152 fn setattro (
11481153 zelf : & Py < Self > ,
0 commit comments