@@ -205,6 +205,9 @@ impl PyType {
205
205
if base. slots . flags . has_feature ( PyTypeFlags :: HAS_DICT ) {
206
206
slots. flags |= PyTypeFlags :: HAS_DICT
207
207
}
208
+ if slots. basicsize == 0 {
209
+ slots. basicsize = base. slots . basicsize ;
210
+ }
208
211
209
212
if let Some ( qualname) = attrs. get ( identifier ! ( ctx, __qualname__) ) {
210
213
if !qualname. fast_isinstance ( ctx. types . str_type ) {
@@ -253,6 +256,9 @@ impl PyType {
253
256
if base. slots . flags . has_feature ( PyTypeFlags :: HAS_DICT ) {
254
257
slots. flags |= PyTypeFlags :: HAS_DICT
255
258
}
259
+ if slots. basicsize == 0 {
260
+ slots. basicsize = base. slots . basicsize ;
261
+ }
256
262
257
263
let bases = vec ! [ base. clone( ) ] ;
258
264
let mro = base. iter_mro ( ) . map ( |x| x. to_owned ( ) ) . collect ( ) ;
@@ -470,6 +476,11 @@ impl PyType {
470
476
self . slots . flags . bits ( )
471
477
}
472
478
479
+ #[ pygetset( magic) ]
480
+ fn basicsize ( & self ) -> usize {
481
+ self . slots . basicsize
482
+ }
483
+
473
484
#[ pygetset]
474
485
pub fn __name__ ( & self , vm : & VirtualMachine ) -> PyStrRef {
475
486
self . name_inner (
@@ -1313,22 +1324,29 @@ fn calculate_meta_class(
1313
1324
Ok ( winner)
1314
1325
}
1315
1326
1327
+ fn solid_base ( typ : & PyTypeRef , vm : & VirtualMachine ) -> PyTypeRef {
1328
+ let base = if let Some ( base) = & typ. base {
1329
+ solid_base ( base, vm)
1330
+ } else {
1331
+ vm. ctx . types . object_type . to_owned ( )
1332
+ } ;
1333
+
1334
+ // TODO: itemsize comparation also needed
1335
+ if typ. basicsize ( ) != base. basicsize ( ) {
1336
+ typ. clone ( )
1337
+ } else {
1338
+ base
1339
+ }
1340
+ }
1341
+
1316
1342
fn best_base ( bases : & [ PyTypeRef ] , vm : & VirtualMachine ) -> PyResult < PyTypeRef > {
1317
- // let mut base = None;
1318
- // let mut winner = None;
1343
+ let mut base: Option < PyTypeRef > = None ;
1344
+ let mut winner: Option < PyTypeRef > = None ;
1319
1345
1320
1346
for base_i in bases {
1321
- // base_proto = PyTuple_GET_ITEM(bases, i);
1322
- // if (!PyType_Check(base_proto)) {
1323
- // PyErr_SetString(
1324
- // PyExc_TypeError,
1325
- // "bases must be types");
1326
- // return NULL;
1327
- // }
1328
- // base_i = (PyTypeObject *)base_proto;
1329
- // if (base_i->slot_dict == NULL) {
1330
- // if (PyType_Ready(base_i) < 0)
1331
- // return NULL;
1347
+ // if !base_i.fast_issubclass(vm.ctx.types.type_type) {
1348
+ // println!("base_i type : {}", base_i.name());
1349
+ // return Err(vm.new_type_error("best must be types".into()));
1332
1350
// }
1333
1351
1334
1352
if !base_i. slots . flags . has_feature ( PyTypeFlags :: BASETYPE ) {
@@ -1337,28 +1355,25 @@ fn best_base(bases: &[PyTypeRef], vm: &VirtualMachine) -> PyResult<PyTypeRef> {
1337
1355
base_i. name( )
1338
1356
) ) ) ;
1339
1357
}
1340
- // candidate = solid_base(base_i);
1341
- // if (winner == NULL) {
1342
- // winner = candidate;
1343
- // base = base_i;
1344
- // }
1345
- // else if (PyType_IsSubtype(winner, candidate))
1346
- // ;
1347
- // else if (PyType_IsSubtype(candidate, winner)) {
1348
- // winner = candidate;
1349
- // base = base_i;
1350
- // }
1351
- // else {
1352
- // PyErr_SetString(
1353
- // PyExc_TypeError,
1354
- // "multiple bases have "
1355
- // "instance lay-out conflict");
1356
- // return NULL;
1357
- // }
1358
+
1359
+ let candidate = solid_base ( base_i, vm) ;
1360
+ if winner. is_none ( ) {
1361
+ winner = Some ( candidate. clone ( ) ) ;
1362
+ base = Some ( base_i. clone ( ) ) ;
1363
+ } else if winner. as_ref ( ) . unwrap ( ) . fast_issubclass ( & candidate) {
1364
+ // Do nothing
1365
+ } else if candidate. fast_issubclass ( winner. as_ref ( ) . unwrap ( ) ) {
1366
+ winner = Some ( candidate. clone ( ) ) ;
1367
+ base = Some ( base_i. clone ( ) ) ;
1368
+ } else {
1369
+ return Err (
1370
+ vm. new_type_error ( "multiple bases have instance layout conflict" . to_string ( ) )
1371
+ ) ;
1372
+ }
1358
1373
}
1359
1374
1360
- // FIXME: Ok (base.unwrap ()) is expected
1361
- Ok ( bases [ 0 ] . clone ( ) )
1375
+ debug_assert ! ( base. is_some ( ) ) ;
1376
+ Ok ( base . unwrap ( ) )
1362
1377
}
1363
1378
1364
1379
#[ cfg( test) ]
0 commit comments