@@ -49,6 +49,61 @@ impl PyValue for PyType {
4949}
5050
5151impl PyType {
52+ pub fn new (
53+ metaclass : PyRef < Self > ,
54+ name : & str ,
55+ base : PyRef < Self > ,
56+ bases : Vec < PyRef < Self > > ,
57+ attrs : PyAttributes ,
58+ mut slots : PyTypeSlots ,
59+ ) -> Result < PyRef < Self > , String > {
60+ // Check for duplicates in bases.
61+ let mut unique_bases = HashSet :: new ( ) ;
62+ for base in bases. iter ( ) {
63+ if !unique_bases. insert ( base. get_id ( ) ) {
64+ return Err ( format ! ( "duplicate base class {}" , base. name( ) ) ) ;
65+ }
66+ }
67+
68+ let mros = bases
69+ . iter ( )
70+ . map ( |x| x. iter_mro ( ) . cloned ( ) . collect ( ) )
71+ . collect ( ) ;
72+ let mro = linearise_mro ( mros) ?;
73+
74+ if base. slots . flags . has_feature ( PyTpFlags :: HAS_DICT ) {
75+ slots. flags |= PyTpFlags :: HAS_DICT
76+ }
77+
78+ * slots. name . write ( ) = Some ( String :: from ( name) ) ;
79+
80+ let new_type = PyRef :: new_ref (
81+ PyType {
82+ base : Some ( base) ,
83+ bases,
84+ mro,
85+ subclasses : PyRwLock :: default ( ) ,
86+ attributes : PyRwLock :: new ( attrs) ,
87+ slots,
88+ } ,
89+ metaclass,
90+ None ,
91+ ) ;
92+
93+ for attr_name in new_type. attributes . read ( ) . keys ( ) {
94+ if attr_name. starts_with ( "__" ) && attr_name. ends_with ( "__" ) {
95+ new_type. update_slot ( attr_name, true ) ;
96+ }
97+ }
98+ for base in & new_type. bases {
99+ base. subclasses
100+ . write ( )
101+ . push ( PyWeak :: downgrade ( new_type. as_object ( ) ) ) ;
102+ }
103+
104+ Ok ( new_type)
105+ }
106+
52107 pub fn tp_name ( & self ) -> String {
53108 self . slots . name . read ( ) . as_ref ( ) . unwrap ( ) . to_string ( )
54109 }
@@ -493,7 +548,7 @@ impl PyType {
493548 let flags = PyTpFlags :: heap_type_flags ( ) | PyTpFlags :: HAS_DICT ;
494549 let slots = PyTypeSlots :: from_flags ( flags) ;
495550
496- let typ = new ( metatype, name. as_str ( ) , base, bases, attributes, slots)
551+ let typ = Self :: new ( metatype, name. as_str ( ) , base, bases, attributes, slots)
497552 . map_err ( |e| vm. new_type_error ( e) ) ?;
498553
499554 // avoid deadlock
@@ -844,61 +899,6 @@ fn linearise_mro(mut bases: Vec<Vec<PyTypeRef>>) -> Result<Vec<PyTypeRef>, Strin
844899 Ok ( result)
845900}
846901
847- pub fn new (
848- typ : PyTypeRef ,
849- name : & str ,
850- base : PyTypeRef ,
851- bases : Vec < PyTypeRef > ,
852- attrs : PyAttributes ,
853- mut slots : PyTypeSlots ,
854- ) -> Result < PyTypeRef , String > {
855- // Check for duplicates in bases.
856- let mut unique_bases = HashSet :: new ( ) ;
857- for base in bases. iter ( ) {
858- if !unique_bases. insert ( base. get_id ( ) ) {
859- return Err ( format ! ( "duplicate base class {}" , base. name( ) ) ) ;
860- }
861- }
862-
863- let mros = bases
864- . iter ( )
865- . map ( |x| x. iter_mro ( ) . cloned ( ) . collect ( ) )
866- . collect ( ) ;
867- let mro = linearise_mro ( mros) ?;
868-
869- if base. slots . flags . has_feature ( PyTpFlags :: HAS_DICT ) {
870- slots. flags |= PyTpFlags :: HAS_DICT
871- }
872-
873- * slots. name . write ( ) = Some ( String :: from ( name) ) ;
874-
875- let new_type = PyRef :: new_ref (
876- PyType {
877- base : Some ( base) ,
878- bases,
879- mro,
880- subclasses : PyRwLock :: default ( ) ,
881- attributes : PyRwLock :: new ( attrs) ,
882- slots,
883- } ,
884- typ,
885- None ,
886- ) ;
887-
888- for attr_name in new_type. attributes . read ( ) . keys ( ) {
889- if attr_name. starts_with ( "__" ) && attr_name. ends_with ( "__" ) {
890- new_type. update_slot ( attr_name, true ) ;
891- }
892- }
893- for base in & new_type. bases {
894- base. subclasses
895- . write ( )
896- . push ( PyWeak :: downgrade ( new_type. as_object ( ) ) ) ;
897- }
898-
899- Ok ( new_type)
900- }
901-
902902fn calculate_meta_class (
903903 metatype : PyTypeRef ,
904904 bases : & [ PyTypeRef ] ,
0 commit comments