astropy/astropy — pull request #133 by eteq (2012-01-20 08:20:12+00:00)
Title: fix for errors caused by passing lists to pyfit's _fix_dtype

This is a fix for an error that seems to result if you have pyfits 3.0.4 installed in py 3.2.2 (I was using Mac OS X 10.6, with the macports python, although I don't think that matters here). All the vo tests were failing due to the same error, the relevant parts of which I've included below.

The key point is that the `_fix_dtype` function in pyfits (which is used in numpy's recarrays via monkeypatching to prevent a segfault) fails if the dtype is a list of name/type pairs. @iguananaut, you may want to fix this in pyfits, as well, but this patch just prevents the problem in the first place in `io.vo.tree`.

The final part of the traceback is shown below - this is in common to all the vo errors that result *without* this pull request:

```
self = , nrows = 0
config = {'_current_table_number': 1, '_warning_counts': {: 1, : 1, : 5, ...}, 'chunk_size': 256, 'columns': None, ...}

def create_arrays(self, nrows=0, config={}):
"""
Create new arrays to hold the data based on the current set of
fields, and store them in the *array* and *mask* member
variables. Any data in existing arrays will be lost.

*nrows*, if provided, is the number of rows to allocate.
"""
if nrows is None:
nrows = 0

fields = self.fields

if len(fields) == 0:
array = np.recarray((nrows,), dtype='O')
mask = np.zeros((nrows,), dtype='b')
else:
# for field in fields: field._setup(config)
Field.uniqify_names(fields)

dtype = []
for x in fields:
if x._unique_name == x.ID:
id = x.ID
else:
id = (x._unique_name, x.ID)
dtype.append((id, x.converter.format))

> array = np.recarray((nrows,), dtype=dtype)

astropy/io/vo/tree.py:1923:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

subtype = , shape = (0,)
dtype = [(('string test', 'string_test'), 'O'), (('fixed string test', 'string_test_2'), 'S10'), ('unicode_test', 'O'), (('uni... test', 'fixed_unicode_test'), 'U10'), (('string array test', 'string_array_test'), 'S4'), ('unsignedByte', 'u1'), ...]
buf = None, offset = 0, strides = None, formats = None, names = None
titles = None, byteorder = None, aligned = False, order = 'C'

def __new__(subtype, shape, dtype=None, buf=None, offset=0,
strides=None, formats=None, names=None, titles=None,
byteorder=None, aligned=False, order='C'):
if dtype is not None:
> dtype = _fix_dtype(dtype)

/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/pyfits/py3compat.py:131:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

dtype = [(('string test', 'string_test'), 'O'), (('fixed string test', 'string_test_2'), 'S10'), ('unicode_test', 'O'), (('uni... test', 'fixed_unicode_test'), 'U10'), (('string array test', 'string_array_test'), 'S4'), ('unsignedByte', 'u1'), ...]

def _fix_dtype(dtype):
"""
Numpy has a bug (in Python3 only) that causes a segfault when
accessing the data of arrays containing nested arrays. Specifically,
this happens if the shape of the subarray is not given as a tuple.
See http://projects.scipy.org/numpy/ticket/1766.
"""

> if dtype.fields is None:
E AttributeError: 'list' object has no attribute 'fields'

/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/pyfits/py3compat.py:110: AttributeError
```