@@ -56,26 +56,26 @@ impl PyValue for PyType {
56
56
}
57
57
}
58
58
59
- impl PyTypeRef {
60
- fn tp_name ( zelf : Self , vm : & VirtualMachine ) -> String {
61
- let opt_name = zelf . slots . name . read ( ) . clone ( ) ;
59
+ impl PyType {
60
+ fn tp_name ( & self , vm : & VirtualMachine ) -> String {
61
+ let opt_name = self . slots . name . read ( ) . clone ( ) ;
62
62
opt_name. unwrap_or_else ( || {
63
- let module = zelf . attributes . read ( ) . get ( "__module__" ) . cloned ( ) ;
63
+ let module = self . attributes . read ( ) . get ( "__module__" ) . cloned ( ) ;
64
64
let new_name = if let Some ( module) = module {
65
65
// FIXME: "unknown" case is a bug.
66
66
let module_str = PyStrRef :: try_from_object ( vm, module)
67
67
. map_or ( "<unknown>" . to_owned ( ) , |m| m. borrow_value ( ) . to_owned ( ) ) ;
68
- format ! ( "{}.{}" , module_str, & zelf . name)
68
+ format ! ( "{}.{}" , module_str, & self . name)
69
69
} else {
70
- zelf . name . clone ( )
70
+ self . name . clone ( )
71
71
} ;
72
- * zelf . slots . name . write ( ) = Some ( new_name. clone ( ) ) ;
72
+ * self . slots . name . write ( ) = Some ( new_name. clone ( ) ) ;
73
73
new_name
74
74
} )
75
75
}
76
76
77
- pub fn iter_mro ( & self ) -> impl Iterator < Item = & PyTypeRef > + DoubleEndedIterator {
78
- std:: iter:: once ( self ) . chain ( self . mro . iter ( ) )
77
+ pub fn iter_mro ( & self ) -> impl Iterator < Item = & PyType > + DoubleEndedIterator {
78
+ std:: iter:: once ( self ) . chain ( self . mro . iter ( ) . map ( |cls| cls . deref ( ) ) )
79
79
}
80
80
81
81
pub ( crate ) fn first_in_mro < F , R > ( & self , f : F ) -> Option < R >
@@ -87,27 +87,50 @@ impl PyTypeRef {
87
87
if let Some ( r) = f ( self ) {
88
88
Some ( r)
89
89
} else {
90
- self . mro . iter ( ) . filter_map ( |cls| f ( cls) ) . next ( )
90
+ self . mro . iter ( ) . find_map ( |cls| f ( & cls) )
91
91
}
92
92
}
93
93
94
- pub fn iter_base_chain ( & self ) -> impl Iterator < Item = & PyTypeRef > {
95
- std:: iter:: successors ( Some ( self ) , |cls| cls. base . as_ref ( ) )
96
- }
97
-
98
94
// This is used for class initialisation where the vm is not yet available.
99
95
pub fn set_str_attr < V : Into < PyObjectRef > > ( & self , attr_name : & str , value : V ) {
100
96
self . attributes
101
97
. write ( )
102
98
. insert ( attr_name. to_owned ( ) , value. into ( ) ) ;
103
99
}
104
100
101
+ /// This is the internal get_attr implementation for fast lookup on a class.
102
+ pub fn get_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
103
+ flame_guard ! ( format!( "class_get_attr({:?})" , attr_name) ) ;
104
+
105
+ self . get_direct_attr ( attr_name)
106
+ . or_else ( || self . get_super_attr ( attr_name) )
107
+ }
108
+
109
+ pub fn get_direct_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
110
+ self . attributes . read ( ) . get ( attr_name) . cloned ( )
111
+ }
112
+
113
+ pub fn get_super_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
114
+ self . mro
115
+ . iter ( )
116
+ . find_map ( |class| class. attributes . read ( ) . get ( attr_name) . cloned ( ) )
117
+ }
118
+
119
+ // This is the internal has_attr implementation for fast lookup on a class.
120
+ pub fn has_attr ( & self , attr_name : & str ) -> bool {
121
+ self . attributes . read ( ) . contains_key ( attr_name)
122
+ || self
123
+ . mro
124
+ . iter ( )
125
+ . any ( |c| c. attributes . read ( ) . contains_key ( attr_name) )
126
+ }
127
+
105
128
pub fn get_attributes ( & self ) -> PyAttributes {
106
129
// Gather all members here:
107
130
let mut attributes = PyAttributes :: new ( ) ;
108
131
109
132
for bc in self . iter_mro ( ) . rev ( ) {
110
- for ( name, value) in bc. attributes . read ( ) . clone ( ) . iter ( ) {
133
+ for ( name, value) in bc. attributes . read ( ) . iter ( ) {
111
134
attributes. insert ( name. to_owned ( ) , value. clone ( ) ) ;
112
135
}
113
136
}
@@ -177,6 +200,16 @@ impl PyTypeRef {
177
200
}
178
201
}
179
202
203
+ impl PyTypeRef {
204
+ pub fn iter_mro ( & self ) -> impl Iterator < Item = & PyTypeRef > + DoubleEndedIterator {
205
+ std:: iter:: once ( self ) . chain ( self . mro . iter ( ) )
206
+ }
207
+
208
+ pub fn iter_base_chain ( & self ) -> impl Iterator < Item = & PyTypeRef > {
209
+ std:: iter:: successors ( Some ( self ) , |cls| cls. base . as_ref ( ) )
210
+ }
211
+ }
212
+
180
213
#[ inline]
181
214
fn get_class_magic ( zelf : & PyObjectRef , name : & str ) -> PyObjectRef {
182
215
zelf. get_class_attr ( name) . unwrap ( )
@@ -237,8 +270,8 @@ impl PyType {
237
270
}
238
271
239
272
#[ pymethod( magic) ]
240
- fn repr ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> String {
241
- format ! ( "<class '{}'>" , PyRef :: < Self > :: tp_name( zelf , vm) )
273
+ fn repr ( & self , vm : & VirtualMachine ) -> String {
274
+ format ! ( "<class '{}'>" , self . tp_name( vm) )
242
275
}
243
276
244
277
#[ pyproperty( magic) ]
@@ -471,8 +504,8 @@ impl PyType {
471
504
}
472
505
473
506
impl SlotGetattro for PyType {
474
- fn getattro ( zelf : PyRef < Self > , name_ref : PyStrRef , vm : & VirtualMachine ) -> PyResult {
475
- let name = name_ref . borrow_value ( ) ;
507
+ fn getattro ( zelf : PyRef < Self > , name_str : PyStrRef , vm : & VirtualMachine ) -> PyResult {
508
+ let name = name_str . borrow_value ( ) ;
476
509
vm_trace ! ( "type.__getattribute__({:?}, {:?})" , zelf, name) ;
477
510
let mcl = zelf. lease_class ( ) ;
478
511
@@ -510,7 +543,7 @@ impl SlotGetattro for PyType {
510
543
getter,
511
544
vec ! [
512
545
PyLease :: into_pyref( mcl) . into_object( ) ,
513
- name_ref . into_object( ) ,
546
+ name_str . into_object( ) ,
514
547
] ,
515
548
)
516
549
} else {
@@ -638,7 +671,7 @@ fn call_tp_new(
638
671
args : PyFuncArgs ,
639
672
vm : & VirtualMachine ,
640
673
) -> PyResult {
641
- for cls in typ. iter_mro ( ) {
674
+ for cls in typ. deref ( ) . iter_mro ( ) {
642
675
if let Some ( new_meth) = cls. get_attr ( "__new__" ) {
643
676
if !vm. ctx . is_tp_new_wrapper ( & new_meth) {
644
677
let new_meth = vm. call_if_get_descriptor ( new_meth, typ. clone ( ) . into_object ( ) ) ?;
@@ -668,35 +701,6 @@ pub fn tp_new_wrapper(
668
701
call_tp_new ( zelf, cls, args, vm)
669
702
}
670
703
671
- impl PyType {
672
- /// This is the internal get_attr implementation for fast lookup on a class.
673
- pub fn get_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
674
- flame_guard ! ( format!( "class_get_attr({:?})" , attr_name) ) ;
675
-
676
- self . get_direct_attr ( attr_name)
677
- . or_else ( || self . get_super_attr ( attr_name) )
678
- }
679
-
680
- pub fn get_direct_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
681
- self . attributes . read ( ) . get ( attr_name) . cloned ( )
682
- }
683
-
684
- pub fn get_super_attr ( & self , attr_name : & str ) -> Option < PyObjectRef > {
685
- self . mro
686
- . iter ( )
687
- . find_map ( |class| class. attributes . read ( ) . get ( attr_name) . cloned ( ) )
688
- }
689
-
690
- // This is the internal has_attr implementation for fast lookup on a class.
691
- pub fn has_attr ( & self , attr_name : & str ) -> bool {
692
- self . attributes . read ( ) . contains_key ( attr_name)
693
- || self
694
- . mro
695
- . iter ( )
696
- . any ( |c| c. attributes . read ( ) . contains_key ( attr_name) )
697
- }
698
- }
699
-
700
704
fn take_next_base ( mut bases : Vec < Vec < PyTypeRef > > ) -> ( Option < PyTypeRef > , Vec < Vec < PyTypeRef > > ) {
701
705
bases = bases. into_iter ( ) . filter ( |x| !x. is_empty ( ) ) . collect ( ) ;
702
706
0 commit comments