@@ -37,7 +37,7 @@ use std::{borrow::Borrow, collections::HashSet, ops::Deref, pin::Pin, ptr::NonNu
37
37
pub struct PyType {
38
38
pub base : Option < PyTypeRef > ,
39
39
pub bases : PyRwLock < Vec < PyTypeRef > > ,
40
- pub mro : PyRwLock < Vec < PyTypeRef > > ,
40
+ pub mro : PyRwLock < Vec < PyTypeRef > > , // TODO: PyTypedTuple<PyTypeRef>
41
41
pub subclasses : PyRwLock < Vec < PyRef < PyWeak > > > ,
42
42
pub attributes : PyRwLock < PyAttributes > ,
43
43
pub slots : PyTypeSlots ,
@@ -48,7 +48,7 @@ unsafe impl crate::object::Traverse for PyType {
48
48
fn traverse ( & self , tracer_fn : & mut crate :: object:: TraverseFn < ' _ > ) {
49
49
self . base . traverse ( tracer_fn) ;
50
50
self . bases . traverse ( tracer_fn) ;
51
- self . mro . traverse ( tracer_fn) ;
51
+ // self.mro.traverse(tracer_fn);
52
52
self . subclasses . traverse ( tracer_fn) ;
53
53
self . attributes
54
54
. read_recursive ( )
@@ -238,8 +238,6 @@ impl PyType {
238
238
metaclass : PyRef < Self > ,
239
239
ctx : & Context ,
240
240
) -> Result < PyRef < Self > , String > {
241
- let mro = Self :: resolve_mro ( & bases) ?;
242
-
243
241
if base. slots . flags . has_feature ( PyTypeFlags :: HAS_DICT ) {
244
242
slots. flags |= PyTypeFlags :: HAS_DICT
245
243
}
@@ -256,6 +254,7 @@ impl PyType {
256
254
}
257
255
}
258
256
257
+ let mro = Self :: resolve_mro ( & bases) ?;
259
258
let new_type = PyRef :: new_ref (
260
259
PyType {
261
260
base : Some ( base) ,
@@ -269,6 +268,7 @@ impl PyType {
269
268
metaclass,
270
269
None ,
271
270
) ;
271
+ new_type. mro . write ( ) . insert ( 0 , new_type. clone ( ) ) ;
272
272
273
273
new_type. init_slots ( ctx) ;
274
274
@@ -300,7 +300,6 @@ impl PyType {
300
300
301
301
let bases = PyRwLock :: new ( vec ! [ base. clone( ) ] ) ;
302
302
let mro = base. mro_map_collect ( |x| x. to_owned ( ) ) ;
303
-
304
303
let new_type = PyRef :: new_ref (
305
304
PyType {
306
305
base : Some ( base) ,
@@ -314,6 +313,7 @@ impl PyType {
314
313
metaclass,
315
314
None ,
316
315
) ;
316
+ new_type. mro . write ( ) . insert ( 0 , new_type. clone ( ) ) ;
317
317
318
318
let weakref_type = super :: PyWeak :: static_type ( ) ;
319
319
for base in new_type. bases . read ( ) . iter ( ) {
@@ -332,7 +332,7 @@ impl PyType {
332
332
#[ allow( clippy:: mutable_key_type) ]
333
333
let mut slot_name_set = std:: collections:: HashSet :: new ( ) ;
334
334
335
- for cls in self . mro . read ( ) . iter ( ) {
335
+ for cls in self . mro . read ( ) [ 1 .. ] . iter ( ) {
336
336
for & name in cls. attributes . read ( ) . keys ( ) {
337
337
if name == identifier ! ( ctx, __new__) {
338
338
continue ;
@@ -381,18 +381,15 @@ impl PyType {
381
381
}
382
382
383
383
pub fn get_super_attr ( & self , attr_name : & ' static PyStrInterned ) -> Option < PyObjectRef > {
384
- self . mro
385
- . read ( )
384
+ self . mro . read ( ) [ 1 ..]
386
385
. iter ( )
387
386
. find_map ( |class| class. attributes . read ( ) . get ( attr_name) . cloned ( ) )
388
387
}
389
388
390
389
// This is the internal has_attr implementation for fast lookup on a class.
391
390
pub fn has_attr ( & self , attr_name : & ' static PyStrInterned ) -> bool {
392
391
self . attributes . read ( ) . contains_key ( attr_name)
393
- || self
394
- . mro
395
- . read ( )
392
+ || self . mro . read ( ) [ 1 ..]
396
393
. iter ( )
397
394
. any ( |c| c. attributes . read ( ) . contains_key ( attr_name) )
398
395
}
@@ -401,10 +398,7 @@ impl PyType {
401
398
// Gather all members here:
402
399
let mut attributes = PyAttributes :: default ( ) ;
403
400
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 ( ) {
408
402
for ( name, value) in bc. attributes . read ( ) . iter ( ) {
409
403
attributes. insert ( name. to_owned ( ) , value. clone ( ) ) ;
410
404
}
@@ -468,22 +462,21 @@ impl Py<PyType> {
468
462
/// so only use this if `cls` is known to have not overridden the base __subclasscheck__ magic
469
463
/// method.
470
464
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 ( ) ) )
472
466
}
473
467
474
468
pub fn mro_map_collect < F , R > ( & self , f : F ) -> Vec < R >
475
469
where
476
470
F : Fn ( & Self ) -> R ,
477
471
{
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 ( )
482
473
}
483
474
484
475
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 ( ) )
487
480
. map ( |x| x. to_owned ( ) )
488
481
. collect ( )
489
482
}
@@ -497,7 +490,7 @@ impl Py<PyType> {
497
490
if let Some ( r) = f ( self ) {
498
491
Some ( r)
499
492
} else {
500
- self . mro . read ( ) . iter ( ) . find_map ( |cls| f ( cls) )
493
+ self . mro . read ( ) [ 1 .. ] . iter ( ) . find_map ( |cls| f ( cls) )
501
494
}
502
495
}
503
496
@@ -556,8 +549,10 @@ impl PyType {
556
549
* zelf. bases . write ( ) = bases;
557
550
// Recursively update the mros of this class and all subclasses
558
551
fn update_mro_recursively ( cls : & PyType , vm : & VirtualMachine ) -> PyResult < ( ) > {
559
- * cls . mro . write ( ) =
552
+ let mut mro =
560
553
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;
561
556
for subclass in cls. subclasses . write ( ) . iter ( ) {
562
557
let subclass = subclass. upgrade ( ) . unwrap ( ) ;
563
558
let subclass: & PyType = subclass. payload ( ) . unwrap ( ) ;
0 commit comments