@@ -49,6 +49,61 @@ impl PyValue for PyType {
49
49
}
50
50
51
51
impl 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
+
52
107
pub fn tp_name ( & self ) -> String {
53
108
self . slots . name . read ( ) . as_ref ( ) . unwrap ( ) . to_string ( )
54
109
}
@@ -493,7 +548,7 @@ impl PyType {
493
548
let flags = PyTpFlags :: heap_type_flags ( ) | PyTpFlags :: HAS_DICT ;
494
549
let slots = PyTypeSlots :: from_flags ( flags) ;
495
550
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)
497
552
. map_err ( |e| vm. new_type_error ( e) ) ?;
498
553
499
554
// avoid deadlock
@@ -844,61 +899,6 @@ fn linearise_mro(mut bases: Vec<Vec<PyTypeRef>>) -> Result<Vec<PyTypeRef>, Strin
844
899
Ok ( result)
845
900
}
846
901
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
-
902
902
fn calculate_meta_class (
903
903
metatype : PyTypeRef ,
904
904
bases : & [ PyTypeRef ] ,
@@ -986,7 +986,7 @@ mod tests {
986
986
let object = & context. types . object_type ;
987
987
let type_type = & context. types . type_type ;
988
988
989
- let a = new (
989
+ let a = PyType :: new (
990
990
type_type. clone ( ) ,
991
991
"A" ,
992
992
object. clone ( ) ,
@@ -995,7 +995,7 @@ mod tests {
995
995
Default :: default ( ) ,
996
996
)
997
997
. unwrap ( ) ;
998
- let b = new (
998
+ let b = PyType :: new (
999
999
type_type. clone ( ) ,
1000
1000
"B" ,
1001
1001
object. clone ( ) ,
0 commit comments