@@ -56,29 +56,29 @@ 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
- pub ( crate ) fn first_in_mro < F , R > ( & self , f : F ) -> Option < R >
81
+ pub ( crate ) fn mro_find_map < F , R > ( & self , f : F ) -> Option < R >
82
82
where
83
83
F : Fn ( & Self ) -> Option < R > ,
84
84
{
@@ -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
@@ -482,7 +515,7 @@ impl SlotGetattro for PyType {
482
515
let attr_class = attr. lease_class ( ) ;
483
516
if attr_class. has_attr ( "__set__" ) {
484
517
if let Some ( ref descr_get) =
485
- PyLease :: into_pyref ( attr_class) . first_in_mro ( |cls| cls. slots . descr_get . load ( ) )
518
+ attr_class. mro_find_map ( |cls| cls. slots . descr_get . load ( ) )
486
519
{
487
520
let mcl = PyLease :: into_pyref ( mcl) . into_object ( ) ;
488
521
return descr_get ( attr. clone ( ) , Some ( zelf. into_object ( ) ) , Some ( mcl) , vm) ;
@@ -493,8 +526,10 @@ impl SlotGetattro for PyType {
493
526
let zelf_attr = zelf. get_attr ( name) ;
494
527
495
528
if let Some ( ref attr) = zelf_attr {
496
- let attr_class = attr. class ( ) ;
497
- if let Some ( descr_get) = attr_class. first_in_mro ( |cls| cls. slots . descr_get . load ( ) ) {
529
+ if let Some ( descr_get) = attr
530
+ . lease_class ( )
531
+ . mro_find_map ( |cls| cls. slots . descr_get . load ( ) )
532
+ {
498
533
drop ( mcl) ;
499
534
return descr_get ( attr. clone ( ) , None , Some ( zelf. into_object ( ) ) , vm) ;
500
535
}
@@ -510,7 +545,7 @@ impl SlotGetattro for PyType {
510
545
getter,
511
546
vec ! [
512
547
PyLease :: into_pyref( mcl) . into_object( ) ,
513
- name_ref . into_object( ) ,
548
+ name_str . into_object( ) ,
514
549
] ,
515
550
)
516
551
} else {
@@ -596,25 +631,25 @@ pub(crate) fn init(ctx: &PyContext) {
596
631
PyType :: extend_class ( ctx, & ctx. types . type_type ) ;
597
632
}
598
633
599
- pub trait DerefToPyClass {
600
- fn deref_to_class ( & self ) -> & PyType ;
634
+ pub trait DerefToPyType {
635
+ fn deref_to_type ( & self ) -> & PyType ;
601
636
}
602
637
603
- impl DerefToPyClass for PyTypeRef {
604
- fn deref_to_class ( & self ) -> & PyType {
638
+ impl DerefToPyType for PyTypeRef {
639
+ fn deref_to_type ( & self ) -> & PyType {
605
640
self . deref ( )
606
641
}
607
642
}
608
643
609
- impl < ' a > DerefToPyClass for PyLease < ' a , PyType > {
610
- fn deref_to_class ( & self ) -> & PyType {
644
+ impl < ' a > DerefToPyType for PyLease < ' a , PyType > {
645
+ fn deref_to_type ( & self ) -> & PyType {
611
646
self . deref ( )
612
647
}
613
648
}
614
649
615
- impl < T : DerefToPyClass > DerefToPyClass for & ' _ T {
616
- fn deref_to_class ( & self ) -> & PyType {
617
- ( & * * self ) . deref_to_class ( )
650
+ impl < T : DerefToPyType > DerefToPyType for & ' _ T {
651
+ fn deref_to_type ( & self ) -> & PyType {
652
+ ( & * * self ) . deref_to_type ( )
618
653
}
619
654
}
620
655
@@ -628,8 +663,8 @@ pub fn isinstance<T: TypeProtocol>(obj: &T, cls: &PyTypeRef) -> bool {
628
663
/// Determines if `subclass` is actually a subclass of `cls`, this doesn't call __subclasscheck__,
629
664
/// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
630
665
/// method.
631
- pub fn issubclass < T : DerefToPyClass + IdProtocol , R : IdProtocol > ( subclass : T , cls : R ) -> bool {
632
- subclass. is ( & cls) || subclass. deref_to_class ( ) . mro . iter ( ) . any ( |c| c. is ( & cls) )
666
+ pub fn issubclass < T : DerefToPyType + IdProtocol , R : IdProtocol > ( subclass : T , cls : R ) -> bool {
667
+ subclass. is ( & cls) || subclass. deref_to_type ( ) . mro . iter ( ) . any ( |c| c. is ( & cls) )
633
668
}
634
669
635
670
fn call_tp_new (
@@ -638,7 +673,7 @@ fn call_tp_new(
638
673
args : PyFuncArgs ,
639
674
vm : & VirtualMachine ,
640
675
) -> PyResult {
641
- for cls in typ. iter_mro ( ) {
676
+ for cls in typ. deref ( ) . iter_mro ( ) {
642
677
if let Some ( new_meth) = cls. get_attr ( "__new__" ) {
643
678
if !vm. ctx . is_tp_new_wrapper ( & new_meth) {
644
679
let new_meth = vm. call_if_get_descriptor ( new_meth, typ. clone ( ) . into_object ( ) ) ?;
@@ -668,35 +703,6 @@ pub fn tp_new_wrapper(
668
703
call_tp_new ( zelf, cls, args, vm)
669
704
}
670
705
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
706
fn take_next_base ( mut bases : Vec < Vec < PyTypeRef > > ) -> ( Option < PyTypeRef > , Vec < Vec < PyTypeRef > > ) {
701
707
bases = bases. into_iter ( ) . filter ( |x| !x. is_empty ( ) ) . collect ( ) ;
702
708
0 commit comments