@@ -448,12 +448,14 @@ def __getattribute__(self, attr):
448
448
449
449
# At this point obj will always be a recarray, since (see
450
450
# PyArray_GetField) the type of obj is inherited. Next, if obj.dtype is
451
- # non-structured, convert it to an ndarray. If obj is structured leave
452
- # it as a recarray, but make sure to convert to the same dtype.type (eg
453
- # to preserve numpy.record type if present), since nested structured
454
- # fields do not inherit type .
451
+ # non-structured, convert it to an ndarray. Then if obj is structured
452
+ # with void type convert it to the same dtype.type (eg to preserve
453
+ # numpy.record type if present), since nested structured fields do not
454
+ # inherit type. Don't do this for non-void structures though .
455
455
if obj .dtype .fields :
456
- return obj .view (dtype = (self .dtype .type , obj .dtype .fields ))
456
+ if issubclass (obj .dtype .type , nt .void ):
457
+ return obj .view (dtype = (self .dtype .type , obj .dtype ))
458
+ return obj
457
459
else :
458
460
return obj .view (ndarray )
459
461
@@ -463,8 +465,9 @@ def __getattribute__(self, attr):
463
465
# Thus, you can't create attributes on-the-fly that are field names.
464
466
def __setattr__ (self , attr , val ):
465
467
466
- # Automatically convert (void) dtypes to records.
467
- if attr == 'dtype' and issubclass (val .type , nt .void ):
468
+ # Automatically convert (void) structured types to records
469
+ # (but not non-void structures, subarrays, or non-structured voids)
470
+ if attr == 'dtype' and issubclass (val .type , nt .void ) and val .fields :
468
471
val = sb .dtype ((record , val ))
469
472
470
473
newattr = attr not in self .__dict__
@@ -499,7 +502,9 @@ def __getitem__(self, indx):
499
502
# we might also be returning a single element
500
503
if isinstance (obj , ndarray ):
501
504
if obj .dtype .fields :
502
- return obj .view (dtype = (self .dtype .type , obj .dtype .fields ))
505
+ if issubclass (obj .dtype .type , nt .void ):
506
+ return obj .view (dtype = (self .dtype .type , obj .dtype ))
507
+ return obj
503
508
else :
504
509
return obj .view (type = ndarray )
505
510
else :
@@ -519,11 +524,14 @@ def __repr__(self):
519
524
# If this is a full record array (has numpy.record dtype),
520
525
# or if it has a scalar (non-void) dtype with no records,
521
526
# represent it using the rec.array function. Since rec.array
522
- # converts dtype to a numpy.record for us, use only dtype.descr,
523
- # not repr(dtype).
527
+ # converts dtype to a numpy.record for us, convert back
528
+ # to non-record before printing
529
+ plain_dtype = self .dtype
530
+ if plain_dtype .type is record :
531
+ plain_dtype = sb .dtype ((nt .void , plain_dtype ))
524
532
lf = '\n ' + ' ' * len ("rec.array(" )
525
533
return ('rec.array(%s, %sdtype=%s)' %
526
- (lst , lf , repr ( self . dtype . descr ) ))
534
+ (lst , lf , plain_dtype ))
527
535
else :
528
536
# otherwise represent it using np.array plus a view
529
537
# This should only happen if the user is playing
0 commit comments