@@ -37,7 +37,7 @@ use std::{borrow::Borrow, collections::HashSet, ops::Deref, pin::Pin, ptr::NonNu
3737pub struct PyType {
3838 pub base : Option < PyTypeRef > ,
3939 pub bases : PyRwLock < Vec < PyTypeRef > > ,
40- pub mro : PyRwLock < Vec < PyTypeRef > > ,
40+ pub mro : PyRwLock < Vec < PyTypeRef > > , // TODO: PyTypedTuple<PyTypeRef>
4141 pub subclasses : PyRwLock < Vec < PyRef < PyWeak > > > ,
4242 pub attributes : PyRwLock < PyAttributes > ,
4343 pub slots : PyTypeSlots ,
@@ -48,7 +48,7 @@ unsafe impl crate::object::Traverse for PyType {
4848 fn traverse ( & self , tracer_fn : & mut crate :: object:: TraverseFn < ' _ > ) {
4949 self . base . traverse ( tracer_fn) ;
5050 self . bases . traverse ( tracer_fn) ;
51- self . mro . traverse ( tracer_fn) ;
51+ // self.mro.traverse(tracer_fn);
5252 self . subclasses . traverse ( tracer_fn) ;
5353 self . attributes
5454 . read_recursive ( )
@@ -238,8 +238,6 @@ impl PyType {
238238 metaclass : PyRef < Self > ,
239239 ctx : & Context ,
240240 ) -> Result < PyRef < Self > , String > {
241- let mro = Self :: resolve_mro ( & bases) ?;
242-
243241 if base. slots . flags . has_feature ( PyTypeFlags :: HAS_DICT ) {
244242 slots. flags |= PyTypeFlags :: HAS_DICT
245243 }
@@ -256,6 +254,7 @@ impl PyType {
256254 }
257255 }
258256
257+ let mro = Self :: resolve_mro ( & bases) ?;
259258 let new_type = PyRef :: new_ref (
260259 PyType {
261260 base : Some ( base) ,
@@ -269,6 +268,7 @@ impl PyType {
269268 metaclass,
270269 None ,
271270 ) ;
271+ new_type. mro . write ( ) . insert ( 0 , new_type. clone ( ) ) ;
272272
273273 new_type. init_slots ( ctx) ;
274274
@@ -300,7 +300,6 @@ impl PyType {
300300
301301 let bases = PyRwLock :: new ( vec ! [ base. clone( ) ] ) ;
302302 let mro = base. mro_map_collect ( |x| x. to_owned ( ) ) ;
303-
304303 let new_type = PyRef :: new_ref (
305304 PyType {
306305 base : Some ( base) ,
@@ -314,6 +313,7 @@ impl PyType {
314313 metaclass,
315314 None ,
316315 ) ;
316+ new_type. mro . write ( ) . insert ( 0 , new_type. clone ( ) ) ;
317317
318318 let weakref_type = super :: PyWeak :: static_type ( ) ;
319319 for base in new_type. bases . read ( ) . iter ( ) {
@@ -332,7 +332,7 @@ impl PyType {
332332 #[ allow( clippy:: mutable_key_type) ]
333333 let mut slot_name_set = std:: collections:: HashSet :: new ( ) ;
334334
335- for cls in self . mro . read ( ) . iter ( ) {
335+ for cls in self . mro . read ( ) [ 1 .. ] . iter ( ) {
336336 for & name in cls. attributes . read ( ) . keys ( ) {
337337 if name == identifier ! ( ctx, __new__) {
338338 continue ;
@@ -381,18 +381,15 @@ impl PyType {
381381 }
382382
383383 pub fn get_super_attr ( & self , attr_name : & ' static PyStrInterned ) -> Option < PyObjectRef > {
384- self . mro
385- . read ( )
384+ self . mro . read ( ) [ 1 ..]
386385 . iter ( )
387386 . find_map ( |class| class. attributes . read ( ) . get ( attr_name) . cloned ( ) )
388387 }
389388
390389 // This is the internal has_attr implementation for fast lookup on a class.
391390 pub fn has_attr ( & self , attr_name : & ' static PyStrInterned ) -> bool {
392391 self . attributes . read ( ) . contains_key ( attr_name)
393- || self
394- . mro
395- . read ( )
392+ || self . mro . read ( ) [ 1 ..]
396393 . iter ( )
397394 . any ( |c| c. attributes . read ( ) . contains_key ( attr_name) )
398395 }
@@ -401,10 +398,7 @@ impl PyType {
401398 // Gather all members here:
402399 let mut attributes = PyAttributes :: default ( ) ;
403400
404- for bc in std:: iter:: once ( self )
405- . chain ( self . mro . read ( ) . iter ( ) . map ( |cls| -> & PyType { cls } ) )
406- . rev ( )
407- {
401+ for bc in self . mro . read ( ) . iter ( ) . map ( |cls| -> & PyType { cls } ) . rev ( ) {
408402 for ( name, value) in bc. attributes . read ( ) . iter ( ) {
409403 attributes. insert ( name. to_owned ( ) , value. clone ( ) ) ;
410404 }
@@ -468,22 +462,21 @@ impl Py<PyType> {
468462 /// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
469463 /// method.
470464 pub fn fast_issubclass ( & self , cls : & impl Borrow < PyObject > ) -> bool {
471- self . as_object ( ) . is ( cls. borrow ( ) ) || self . mro . read ( ) . iter ( ) . any ( |c| c. is ( cls. borrow ( ) ) )
465+ self . as_object ( ) . is ( cls. borrow ( ) ) || self . mro . read ( ) [ 1 .. ] . iter ( ) . any ( |c| c. is ( cls. borrow ( ) ) )
472466 }
473467
474468 pub fn mro_map_collect < F , R > ( & self , f : F ) -> Vec < R >
475469 where
476470 F : Fn ( & Self ) -> R ,
477471 {
478- std:: iter:: once ( self )
479- . chain ( self . mro . read ( ) . iter ( ) . map ( |x| x. deref ( ) ) )
480- . map ( f)
481- . collect ( )
472+ self . mro . read ( ) . iter ( ) . map ( |x| x. deref ( ) ) . map ( f) . collect ( )
482473 }
483474
484475 pub fn mro_collect ( & self ) -> Vec < PyRef < PyType > > {
485- std:: iter:: once ( self )
486- . chain ( self . mro . read ( ) . iter ( ) . map ( |x| x. deref ( ) ) )
476+ self . mro
477+ . read ( )
478+ . iter ( )
479+ . map ( |x| x. deref ( ) )
487480 . map ( |x| x. to_owned ( ) )
488481 . collect ( )
489482 }
@@ -497,7 +490,7 @@ impl Py<PyType> {
497490 if let Some ( r) = f ( self ) {
498491 Some ( r)
499492 } else {
500- self . mro . read ( ) . iter ( ) . find_map ( |cls| f ( cls) )
493+ self . mro . read ( ) [ 1 .. ] . iter ( ) . find_map ( |cls| f ( cls) )
501494 }
502495 }
503496
@@ -556,8 +549,10 @@ impl PyType {
556549 * zelf. bases . write ( ) = bases;
557550 // Recursively update the mros of this class and all subclasses
558551 fn update_mro_recursively ( cls : & PyType , vm : & VirtualMachine ) -> PyResult < ( ) > {
559- * cls . mro . write ( ) =
552+ let mut mro =
560553 PyType :: resolve_mro ( & cls. bases . read ( ) ) . map_err ( |msg| vm. new_type_error ( msg) ) ?;
554+ mro. insert ( 0 , cls. mro . read ( ) [ 0 ] . to_owned ( ) ) ;
555+ * cls. mro . write ( ) = mro;
561556 for subclass in cls. subclasses . write ( ) . iter ( ) {
562557 let subclass = subclass. upgrade ( ) . unwrap ( ) ;
563558 let subclass: & PyType = subclass. payload ( ) . unwrap ( ) ;
0 commit comments