[Scipy-svn] r5025 - in trunk/scipy/io/matlab: . tests

scipy-svn@scip... scipy-svn@scip...
Sat Nov 8 18:44:50 CST 2008


Author: matthew.brett@gmail.com
Date: 2008-11-08 18:44:40 -0600 (Sat, 08 Nov 2008)
New Revision: 5025

Added:
   trunk/scipy/io/matlab/tests/gen_mat4files.m
   trunk/scipy/io/matlab/tests/gen_mat5files.m
   trunk/scipy/io/matlab/tests/save_matfile.m
Removed:
   trunk/scipy/io/matlab/tests/gen_unittests.m
   trunk/scipy/io/matlab/tests/gen_unittests4.m
   trunk/scipy/io/matlab/tests/save_test.m
Modified:
   trunk/scipy/io/matlab/mio.py
   trunk/scipy/io/matlab/mio4.py
   trunk/scipy/io/matlab/mio5.py
   trunk/scipy/io/matlab/miobase.py
   trunk/scipy/io/matlab/tests/test_mio.py
Log:
Re-enabled matlab io tests, partial fixes for errors

Modified: trunk/scipy/io/matlab/mio.py
===================================================================
--- trunk/scipy/io/matlab/mio.py	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/mio.py	2008-11-09 00:44:40 UTC (rev 5025)
@@ -8,17 +8,19 @@
 import sys
 import warnings
 
-from miobase import get_matfile_version
+from miobase import get_matfile_version, filldoc
 from mio4 import MatFile4Reader, MatFile4Writer
 from mio5 import MatFile5Reader, MatFile5Writer
 
 __all__ = ['find_mat_file', 'mat_reader_factory', 'loadmat', 'savemat']
 
+@filldoc
 def find_mat_file(file_name, appendmat=True):
     ''' Try to find .mat file on system path
 
-    file_name     - file name string
-    append_mat    - If True, and file_name does not end in '.mat', appends it
+    file_name : string
+        file name for mat file
+    %(append_arg)s
     '''
     if appendmat and file_name[-4:] == ".mat":
         file_name = file_name[:-4]
@@ -42,10 +44,15 @@
                 pass
     return full_name
 
+@filldoc
 def mat_reader_factory(file_name, appendmat=True, **kwargs):
-    """Create reader for matlab (TM) .mat format files
+    """Create reader for matlab .mat format files
 
-    See docstring for loadmat for input options
+    %(file_arg)s                          
+    %(append_arg)s                          
+    %(basename_arg)s
+    %(load_args)s
+    %(struct_arg)s
     """
     if isinstance(file_name, basestring):
         full_name = find_mat_file(file_name, appendmat)
@@ -58,54 +65,42 @@
         except AttributeError:
             raise IOError, 'Reader needs file name or open file-like object'
         byte_stream = file_name
-
+    # Deal with deprecations
+    if kwargs.has_key('basename'):
+        warnings.warn(
+            'basename argument will be removed in future scipy versions',
+            DeprecationWarning, stacklevel=2)
+        del kwargs['basename']
     mjv, mnv = get_matfile_version(byte_stream)
     if mjv == 0:
         return MatFile4Reader(byte_stream, **kwargs)
     elif mjv == 1:
         return MatFile5Reader(byte_stream, **kwargs)
     elif mjv == 2:
-        raise NotImplementedError('Please use PyTables for matlab v7.3 (HDF) files')
+        raise NotImplementedError('Please use HDF reader for matlab v7.3 files')
     else:
         raise TypeError('Did not recognize version %s' % mv)
 
-def loadmat(file_name,  mdict=None, appendmat=True, basename='raw', **kwargs):
+@filldoc
+def loadmat(file_name,  mdict=None, appendmat=True, **kwargs):
     ''' Load Matlab(tm) file
 
-    file_name          - Name of the mat file
-                         (do not need .mat extension if appendmat==True)
-                         If name not a full path name, search for the file on
-                         the sys.path list and use the first one found (the
-                         current directory is searched first).
-                         Can also pass open file-like object
-    m_dict             - optional dictionary in which to insert matfile variables
-    appendmat          - True to append the .mat extension to the end of the
-                         given filename, if not already present
-    base_name          - base name for unnamed variables (unused in code)
-    byte_order         - byte order ('native', 'little', 'BIG')
-                          in ('native', '=')
-                          or in ('little', '<')
-                          or in ('BIG', '>')
-    mat_dtype          - return arrays in same dtype as loaded into matlab
-                          (instead of the dtype with which they are saved)
-    squeeze_me         - whether to squeeze matrix dimensions or not
-    chars_as_strings   - whether to convert char arrays to string arrays
-    mat_dtype          - return matrices with datatype that matlab would load as
-                          (rather than in the datatype matlab saves as)
-    matlab_compatible   - returns matrices as would be loaded by matlab
-                          (implies squeeze_me=False, chars_as_strings=False,
-                          mat_dtype=True)
-    struct_as_record    - whether to load matlab structs as numpy record arrays, or
-                          as old-style numpy arrays with dtype=object.
-                          (warns if not set, and defaults to False.  non-recarrays
-                          cannot be exported via savemat.)
+    %(file_arg)s                          
+    m_dict : dict, optional
+        dictionary in which to insert matfile variables
+    %(append_arg)s                          
+    %(basename_arg)s
+    %(load_args)s
+    %(struct_arg)s
+    
+    Notes
+    -----
+    v4 (Level 1.0), v6 and v7 to 7.2 matfiles are supported.
 
-    v4 (Level 1.0), v6 and v7.1 matfiles are supported.
-
+    You will need an HDF5 python library to read matlab 7.3 format mat
+    files.  Because scipy does not supply one, we do not implement the
+    HDF5 / 7.3 interface here.
     '''
-    if not kwargs.get('struct_as_record', False):
-        warnings.warn("loading matlab structures as arrays of dtype=object is deprecated",
-                      DeprecationWarning, stacklevel=2)
     MR = mat_reader_factory(file_name, appendmat, **kwargs)
     matfile_dict = MR.get_variables()
     if mdict is not None:
@@ -114,14 +109,22 @@
         mdict = matfile_dict
     return mdict
 
+@filldoc
 def savemat(file_name, mdict, appendmat=True, format='4'):
     """Save a dictionary of names and arrays into the MATLAB-style .mat file.
 
     This saves the arrayobjects in the given dictionary to a matlab
     style .mat file.
 
-    appendmat  - if true, appends '.mat' extension to filename, if not present
-    format     - '4' for matlab 4 mat files, '5' for matlab 5 onwards
+    file_name : {string, file-like object}
+        Name of the mat file (do not need .mat extension if
+    	appendmat==True) Can also pass open file-like object
+    m_dict : dict
+        dictionary from which to save matfile variables
+    %(append_arg)s
+    format : {'4', '5'} string, optional
+        '4' for matlab 4 mat files, '5' for matlab 5 (up to matlab
+        7.2)
     """
     file_is_string = isinstance(file_name, basestring)
     if file_is_string:

Modified: trunk/scipy/io/matlab/mio4.py
===================================================================
--- trunk/scipy/io/matlab/mio4.py	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/mio4.py	2008-11-09 00:44:40 UTC (rev 5025)
@@ -5,7 +5,7 @@
 import numpy as np
 
 from miobase import MatFileReader, MatArrayReader, MatMatrixGetter, \
-     MatFileWriter, MatStreamWriter, spsparse
+     MatFileWriter, MatStreamWriter, spsparse, filldoc
 
 SYS_LITTLE_ENDIAN = sys.byteorder == 'little'
 
@@ -186,7 +186,13 @@
 
 class MatFile4Reader(MatFileReader):
     ''' Reader for Mat4 files '''
+    @filldoc
     def __init__(self, mat_stream, *args, **kwargs):
+        ''' Initialize matlab 4 file reader
+        
+    %(matstream_arg)s
+    %(load_args)s
+        '''
         self._array_reader = Mat4ArrayReader(
             mat_stream,
             None,

Modified: trunk/scipy/io/matlab/mio5.py
===================================================================
--- trunk/scipy/io/matlab/mio5.py	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/mio5.py	2008-11-09 00:44:40 UTC (rev 5025)
@@ -6,13 +6,14 @@
 
 import sys
 import zlib
-from cStringIO import StringIO
+from StringIO import StringIO
 from copy import copy as pycopy
+import warnings
 
 import numpy as np
 
 from miobase import MatFileReader, MatArrayReader, MatMatrixGetter, \
-     MatFileWriter, MatStreamWriter, spsparse
+     MatFileWriter, MatStreamWriter, spsparse, filldoc
 
 miINT8 = 1
 miUINT8 = 2
@@ -161,6 +162,102 @@
     mxUINT64_CLASS,
     )
 
+
+class mat_struct(object):
+    ''' Placeholder for holding read data from structs
+
+    We will deprecate this method of holding struct information in a
+    future version of scipy, in favor of the recarray method (see
+    loadmat doctstring)
+    '''
+    pass
+
+
+class MatlabObject(object):
+    ''' Class to contain data read from matlab objects 
+
+    Contains classname, and record array for field names and values
+
+    Attribute access fetches and sets record array fields if present
+
+    '''
+    def __init__(self, classname, fields):
+        """ Initialize MatlabObject
+
+        Parameters
+        ----------
+	self : object
+	classname : string
+	    class name for matlab object
+	fields : {recarray, string list}
+            either a recarray or a list of field names
+
+        >>> import numpy as np
+        >>> arr = np.zeros((1,1),dtype=[('field1','i2'),('field2','i2')])
+        >>> obj = MatlabObject('myclass', arr)
+        >>> obj = MatlabObject('myclass', ['field1', 'field2'])
+
+        """
+        # Initialize to make field setting work with __setattr__
+        self.__dict__['_fields'] = []
+        self.classname = classname
+        try: # recarray
+            fdict = fields.dtype.fields
+        except AttributeError: # something else
+            fields = tuple(fields)
+        else: # recarray again
+            self._fields = fdict.keys()
+            self.mobj_recarray = fields
+            return
+        # something else again
+        self._fields = fields
+        dtype = [(field, object) for field in fields]
+        self.mobj_recarray = np.zeros((1,1), dtype)
+    
+    def __getattr__(self, name):
+        ''' get attributes from object
+
+        Get attribute if present, otherwise field from recarray
+        
+        >>> import numpy as np
+        >>> arr = np.zeros((1,1),dtype=[('field1','i2'),('field2','i2')])
+        >>> obj = MatlabObject('myclass', arr)
+        >>> obj.field1
+        array([[0]], dtype=int16)
+        >>> obj = MatlabObject('myclass', ['field1', 'field2'])
+        >>> obj.field1
+        array([[0]], dtype=object)
+        >>> obj.classname
+        'myclass'
+        '''
+        if name in self.__dict__:
+            return self.__dict__[name]
+        mobj_recarray = self.__dict__['mobj_recarray']
+        if name in self.__dict__['_fields']:
+            return mobj_recarray[name]
+        else:
+            raise AttributeError(
+                "no field named %s in MatlabObject" % name)
+
+    def __setattr__(self, name, value):
+        ''' set attributes in object
+
+        Set field value from recarray, if present, else attribute
+
+        >>> import numpy as np
+        >>> arr = np.zeros((1,1),dtype=[('field1','i2'),('field2','i2')])
+        >>> obj = MatlabObject('myclass', arr)
+        >>> obj.field1[0,0] = 1
+        >>> obj.strangename = 'test'
+        >>> obj.strangename
+        'test'
+        '''
+        if name in self._fields:
+            self.mobj_recarray[name] = value
+        else:
+            self.__dict__[name] = value
+
+
 class Mat5ArrayReader(MatArrayReader):
     ''' Class to get Mat5 arrays
 
@@ -411,10 +508,6 @@
     def get_item(self):
         return self.read_element()
 
-class mat_struct(object):
-    ''' Placeholder for holding read data from structs '''
-    pass
-
 class Mat5StructMatrixGetter(Mat5MatrixGetter):
     def __init__(self, array_reader, header):
         super(Mat5StructMatrixGetter, self).__init__(array_reader, header)
@@ -445,27 +538,7 @@
 
         return result.reshape(tupdims).T
 
-class MatlabObject(object):
-    ''' Class to contain read data from matlab objects '''
-    def __init__(self, classname, field_names):
-        self.__dict__['classname'] = classname
-        self.__dict__['mobj_recarray'] = np.empty((1,1), dtype=[(field_name, object)
-                                            for field_name in field_names])
 
-    def __getattr__(self, name):
-        mobj_recarray = self.__dict__['mobj_recarray']
-        if name in mobj_recarray.dtype.fields:
-            return mobj_recarray[0,0][name]
-        else:
-            raise AttributeError, "no field named %s in MatlabObject"%(name)
-
-    def __setattr__(self, name, value):
-        if name in self.__dict__['mobj_recarray'].dtype.fields:
-            self.__dict__['mobj_recarray'][0,0][name] = value
-        else:
-            self.__dict__[name] = value
-
-
 class Mat5ObjectMatrixGetter(Mat5MatrixGetter):
     def get_array(self):
         '''Matlab ojects are essentially structs, with an extra field, the classname.'''
@@ -499,7 +572,7 @@
     uint16_codec       - char codec to use for uint16 char arrays
                           (defaults to system default codec)
    '''
-
+    @filldoc
     def __init__(self,
                  mat_stream,
                  byte_order=None,
@@ -507,34 +580,24 @@
                  squeeze_me=False,
                  chars_as_strings=True,
                  matlab_compatible=False,
-                 struct_as_record=False,
+                 struct_as_record=None, # default False, for now
                  uint16_codec=None
                  ):
+        '''Initializer for matlab 5 file format reader
+        
+    %(matstream_arg)s
+    %(load_args)s
+    %(struct_arg)s
+    uint16_codec : {None, string}
+        Set codec to use for uint16 char arrays (e.g. 'utf-8').
+        Use system default codec if None
         '''
-        mat_stream : file-like
-                     object with file API, open for reading
-        byte_order : {None, string}
-                      specification of byte order, one of:
-                      ('native', '=', 'little', '<', 'BIG', '>')
-        mat_dtype : {True, False} boolean
-                     If True, return arrays in same dtype as loaded into matlab
-                     otherwise return with dtype with which they were saved
-        squeeze_me : {False, True} boolean
-                     If True, squeezes dimensions of size 1 from arrays
-        chars_as_strings : {True, False} boolean
-                     If True, convert char arrays to string arrays
-        matlab_compatible : {False, True} boolean
-                     If True, returns matrices as would be loaded by matlab
-                     (implies squeeze_me=False, chars_as_strings=False
-                     mat_dtype=True, struct_as_record=True)
-        struct_as_record : {False, True} boolean
-                     If True, return strutures as numpy records,
-                     otherwise, return as custom object (for
-                     compatibility with scipy 0.6)
-        uint16_codec : {None, string}
-                     Set codec to use for uint16 char arrays
-                     (e.g. 'utf-8').  Use system default codec if None
-        '''
+        # Deal with deprecations
+        if struct_as_record is None:
+            warnings.warn("Using struct_as_record default value (False)" +
+                          " This will change to True in future versions", 
+                          DeprecationWarning, stacklevel=2)
+            struct_as_record = False
         self.codecs = {}
         # Missing inputs to array reader set later (processor func
         # below, dtypes, codecs via our own set_dtype function, called

Modified: trunk/scipy/io/matlab/miobase.py
===================================================================
--- trunk/scipy/io/matlab/miobase.py	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/miobase.py	2008-11-09 00:44:40 UTC (rev 5025)
@@ -14,6 +14,60 @@
 except ImportError:
     spsparse = None
 
+def filldoc(func):
+    ''' Decorator to put recurring doc elements into mio doc strings '''
+    doc_dict = \
+   {'file_arg':
+    '''file_name : string
+        Name of the mat file (do not need .mat extension if
+    	appendmat==True) If name not a full path name, search for the
+    	file on the sys.path list and use the first one found (the
+    	current directory is searched first).  Can also pass open
+    	file-like object''',
+    'append_arg':
+    '''appendmat : {True, False} optional
+        True to append the .mat extension to the end of the given
+	filename, if not already present''',
+    'basename_arg':
+    '''base_name : string, optional, unused
+        base name for unnamed variables.  The code no longer uses
+        this.  We deprecate for this version of scipy, and will remove
+        it in future versions''',
+    'load_args':
+    '''byte_order : {None, string}, optional
+    	None by default, implying byte order guessed from mat
+	file. Otherwise can be one of ('native', '=', 'little', '<',
+	'BIG', '>')
+    mat_dtype : {False, True} optional
+         If True, return arrays in same dtype as would be loaded into
+	 matlab (instead of the dtype with which they are saved)
+    squeeze_me : {False, True} optional
+         whether to squeeze unit matrix dimensions or not
+    chars_as_strings : {True, False} optional
+         whether to convert char arrays to string arrays
+    matlab_compatible : {False, True}
+         returns matrices as would be loaded by matlab (implies
+         squeeze_me=False, chars_as_strings=False, mat_dtype=True,
+         struct_as_record=True)''',
+    'struct_arg':
+    '''struct_as_record : {False, True} optional
+        Whether to load matlab structs as numpy record arrays, or as
+	old-style numpy arrays with dtype=object.  Setting this flag
+	to False replicates the behaviour of scipy version 0.6
+	(returning numpy object arrays).  The preferred setting is
+	True, because it allows easier round-trip load and save of
+	matlab files.  In a future version of scipy, we will change
+	the default setting to True, and following versions may remove
+	this flag entirely.  For now, we set the default to False, for
+	backwards compatibility, but issue a deprecation warning.
+	Note that non-record arrays cannot be exported via savemat.''',
+    'matstream_arg':
+    '''mat_stream : file-like
+        object with file API, open for reading'''}
+    func.__doc__ = func.__doc__ % doc_dict
+    return func
+
+
 def small_product(arr):
     ''' Faster than product for small arrays '''
     res = 1
@@ -84,7 +138,6 @@
 scipy.io.matlab.byteordercodes module instead.
 """)(ByteOrder)
 
-
 class MatStreamAgent(object):
     ''' Base object for readers / getters from mat file streams
 
@@ -133,32 +186,21 @@
     guess_byte_order        - guesses file byte order from file
     """
 
+    @filldoc
     def __init__(self, mat_stream,
                  byte_order=None,
                  mat_dtype=False,
                  squeeze_me=False,
                  chars_as_strings=True,
                  matlab_compatible=False,
-                 struct_as_record=False
+                 struct_as_record=None
                  ):
         '''
+        Initializer for mat file reader
+        
         mat_stream : file-like
-                     object with file API, open for reading
-        byte_order : {None, string}
-                      specification of byte order, one of:
-                      ('native', '=', 'little', '<', 'BIG', '>')
-        mat_dtype : {True, False} boolean
-                     If True, return arrays in same dtype as loaded into matlab
-                     otherwise return with dtype with which they were saved
-        squeeze_me : {False, True} boolean
-                     If True, squeezes dimensions of size 1 from arrays
-        chars_as_strings : {True, False} boolean
-                     If True, convert char arrays to string arrays
-        matlab_compatible : {False, True} boolean
-                     If True, returns matrices as would be loaded by matlab
-                     (implies squeeze_me=False, chars_as_strings=False
-                     mat_dtype=True)
-
+            object with file API, open for reading
+    %(load_args)s
         '''
         # Initialize stream
         self.mat_stream = mat_stream

Copied: trunk/scipy/io/matlab/tests/gen_mat4files.m (from rev 4827, trunk/scipy/io/matlab/tests/gen_unittests4.m)
===================================================================
--- trunk/scipy/io/matlab/tests/gen_unittests4.m	2008-10-22 13:52:41 UTC (rev 4827)
+++ trunk/scipy/io/matlab/tests/gen_mat4files.m	2008-11-09 00:44:40 UTC (rev 5025)
@@ -0,0 +1,50 @@
+% Generates mat files for loadmat unit tests
+% Uses save_matfile.m function
+% This is the version for matlab 4
+
+% work out matlab version and file suffix for test files
+global FILEPREFIX FILESUFFIX
+sepchar = '/';
+if strcmp(computer, 'PCWIN'), sepchar = '\'; end
+FILEPREFIX = [pwd sepchar 'data' sepchar];
+mlv = version;
+FILESUFFIX = ['_' mlv '_' computer '.mat'];
+
+% basic double array
+theta = 0:pi/4:2*pi;
+save_matfile('testdouble', theta);
+
+% string
+save_matfile('teststring', '"Do nine men interpret?" "Nine men," I nod.')
+
+% complex
+save_matfile('testcomplex', cos(theta) + 1j*sin(theta));
+
+% asymmetric array to check indexing
+a = zeros(3, 5);
+a(:,1) = [1:3]';
+a(1,:) = 1:5;
+
+% 2D matrix
+save_matfile('testmatrix', a);
+
+% minus number - tests signed int 
+save_matfile('testminus', -1);
+
+% single character
+save_matfile('testonechar', 'r');
+
+% string array
+save_matfile('teststringarray', ['one  '; 'two  '; 'three']);
+
+% sparse array
+save_matfile('testsparse', sparse(a));
+
+% sparse complex array
+b = sparse(a);
+b(1,1) = b(1,1) + j;
+save_matfile('testsparsecomplex', b);
+
+% Two variables in same file
+save([FILEPREFIX 'testmulti' FILESUFFIX], 'a', 'theta')
+

Copied: trunk/scipy/io/matlab/tests/gen_mat5files.m (from rev 4827, trunk/scipy/io/matlab/tests/gen_unittests.m)
===================================================================
--- trunk/scipy/io/matlab/tests/gen_unittests.m	2008-10-22 13:52:41 UTC (rev 4827)
+++ trunk/scipy/io/matlab/tests/gen_mat5files.m	2008-11-09 00:44:40 UTC (rev 5025)
@@ -0,0 +1,92 @@
+% Generates mat files for loadmat unit tests
+% This is the version for matlab 5 and higher
+% Uses save_matfile.m function
+
+% work out matlab version and file suffix for test files
+global FILEPREFIX FILESUFFIX
+FILEPREFIX = [fullfile(pwd, 'data') filesep];
+temp = ver('MATLAB');
+mlv = temp.Version;
+FILESUFFIX = ['_' mlv '_' computer '.mat'];
+
+% basic double array
+theta = 0:pi/4:2*pi;
+save_matfile('testdouble', theta);
+
+% string
+save_matfile('teststring', '"Do nine men interpret?" "Nine men," I nod.')
+
+% complex
+save_matfile('testcomplex', cos(theta) + 1j*sin(theta));
+
+% asymmetric array to check indexing
+a = zeros(3, 5);
+a(:,1) = [1:3]';
+a(1,:) = 1:5;
+
+% 2D matrix
+save_matfile('testmatrix', a);
+
+% minus number - tests signed int 
+save_matfile('testminus', -1);
+
+% single character
+save_matfile('testonechar', 'r');
+
+% string array
+save_matfile('teststringarray', ['one  '; 'two  '; 'three']);
+
+% sparse array
+save_matfile('testsparse', sparse(a));
+
+% sparse complex array
+b = sparse(a);
+b(1,1) = b(1,1) + j;
+save_matfile('testsparsecomplex', b);
+
+% Two variables in same file
+save([FILEPREFIX 'testmulti' FILESUFFIX], 'a', 'theta')
+
+
+% struct
+save_matfile('teststruct', ...
+	  struct('stringfield','Rats live on no evil star.',...
+		 'doublefield',[sqrt(2) exp(1) pi],...
+		 'complexfield',(1+1j)*[sqrt(2) exp(1) pi]));
+
+% cell
+save_matfile('testcell', ...
+	  {['This cell contains this string and 3 arrays of increasing' ...
+	    ' length'], 1., 1.:2., 1.:3.});
+
+% Empty cells in two cell matrices
+save_matfile('testemptycell', {1, 2, [], [], 3});
+
+% 3D matrix
+save_matfile('test3dmatrix', reshape(1:24,[2 3 4]))
+
+% nested cell array
+save_matfile('testcellnest', {1, {2, 3, {4, 5}}});
+
+% nested struct
+save_matfile('teststructnest', struct('one', 1, 'two', ...
+				   struct('three', 'number 3')));
+
+% array of struct
+save_matfile('teststructarr', [struct('one', 1, 'two', 2) ...
+		    struct('one', 'number 1', 'two', 'number 2')]);
+
+% matlab object
+save_matfile('testobject', inline('x'))
+
+% array of matlab objects
+%save_matfile('testobjarr', [inline('x') inline('y')])
+
+% unicode test
+if str2num(mlv) > 7  % function added 7.0.1
+  fid = fopen([FILEPREFIX 'japanese_utf8.txt']);
+  from_japan = fread(fid, 'uint8')';
+  fclose(fid);
+  save_matfile('testunicode', native2unicode(from_japan, 'utf-8'));
+end
+  
\ No newline at end of file

Deleted: trunk/scipy/io/matlab/tests/gen_unittests.m
===================================================================
--- trunk/scipy/io/matlab/tests/gen_unittests.m	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/tests/gen_unittests.m	2008-11-09 00:44:40 UTC (rev 5025)
@@ -1,92 +0,0 @@
-% Generates mat files for loadmat unit tests
-% This is the version for matlab 5 and higher
-% Uses save_test.m function
-
-% work out matlab version and file suffix for test files
-global FILEPREFIX FILESUFFIX
-FILEPREFIX = [fullfile(pwd, 'data') filesep];
-temp = ver('MATLAB');
-mlv = temp.Version;
-FILESUFFIX = ['_' mlv '_' computer '.mat'];
-
-% basic double array
-save_test('testdouble', 0:pi/4:2*pi);
-
-% string
-save_test('teststring', '"Do nine men interpret?" "Nine men," I nod.')
-
-% complex
-theta = 0:pi/4:2*pi;
-save_test('testcomplex', cos(theta) + 1j*sin(theta));
-
-% asymmetric array to check indexing
-a = zeros(3, 5);
-a(:,1) = [1:3]';
-a(1,:) = 1:5;
-
-% 2D matrix
-save_test('testmatrix', a);
-
-% minus number - tests signed int 
-save_test('testminus', -1);
-
-% single character
-save_test('testonechar', 'r');
-
-% string array
-save_test('teststringarray', ['one  '; 'two  '; 'three']);
-
-% sparse array
-save_test('testsparse', sparse(a));
-
-% sparse complex array
-b = sparse(a);
-b(1,1) = b(1,1) + j;
-save_test('testsparsecomplex', b);
-
-% Two variables in same file
-save([FILEPREFIX 'testmulti' FILESUFFIX], 'a', 'theta')
-
-
-% struct
-save_test('teststruct', ...
-	  struct('stringfield','Rats live on no evil star.',...
-		 'doublefield',[sqrt(2) exp(1) pi],...
-		 'complexfield',(1+1j)*[sqrt(2) exp(1) pi]));
-
-% cell
-save_test('testcell', ...
-	  {['This cell contains this string and 3 arrays of increasing' ...
-	    ' length'], 1., 1.:2., 1.:3.});
-
-% Empty cells in two cell matrices
-save_test('testemptycell', {1, 2, [], [], 3});
-
-% 3D matrix
-save_test('test3dmatrix', reshape(1:24,[2 3 4]))
-
-% nested cell array
-save_test('testcellnest', {1, {2, 3, {4, 5}}});
-
-% nested struct
-save_test('teststructnest', struct('one', 1, 'two', ...
-				   struct('three', 'number 3')));
-
-% array of struct
-save_test('teststructarr', [struct('one', 1, 'two', 2) ...
-		    struct('one', 'number 1', 'two', 'number 2')]);
-
-% matlab object
-save_test('testobject', inline('x'))
-
-% array of matlab objects
-%save_test('testobjarr', [inline('x') inline('y')])
-
-% unicode test
-if str2num(mlv) > 7  % function added 7.0.1
-  fid = fopen([FILEPREFIX 'japanese_utf8.txt']);
-  from_japan = fread(fid, 'uint8')';
-  fclose(fid);
-  save_test('testunicode', native2unicode(from_japan, 'utf-8'));
-end
-  
\ No newline at end of file

Deleted: trunk/scipy/io/matlab/tests/gen_unittests4.m
===================================================================
--- trunk/scipy/io/matlab/tests/gen_unittests4.m	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/tests/gen_unittests4.m	2008-11-09 00:44:40 UTC (rev 5025)
@@ -1,50 +0,0 @@
-% Generates mat files for loadmat unit tests
-% Uses save_test.m function
-% This is the version for matlab 4
-
-% work out matlab version and file suffix for test files
-global FILEPREFIX FILESUFFIX
-sepchar = '/';
-if strcmp(computer, 'PCWIN'), sepchar = '\'; end
-FILEPREFIX = [pwd sepchar 'data' sepchar];
-mlv = version;
-FILESUFFIX = ['_' mlv '_' computer '.mat'];
-
-% basic double array
-save_test('testdouble', 0:pi/4:2*pi);
-
-% string
-save_test('teststring', '"Do nine men interpret?" "Nine men," I nod.')
-
-% complex
-theta = 0:pi/4:2*pi;
-save_test('testcomplex', cos(theta) + 1j*sin(theta));
-
-% asymmetric array to check indexing
-a = zeros(3, 5);
-a(:,1) = [1:3]';
-a(1,:) = 1:5;
-
-% 2D matrix
-save_test('testmatrix', a);
-
-% minus number - tests signed int 
-save_test('testminus', -1);
-
-% single character
-save_test('testonechar', 'r');
-
-% string array
-save_test('teststringarray', ['one  '; 'two  '; 'three']);
-
-% sparse array
-save_test('testsparse', sparse(a));
-
-% sparse complex array
-b = sparse(a);
-b(1,1) = b(1,1) + j;
-save_test('testsparsecomplex', b);
-
-% Two variables in same file
-save([FILEPREFIX 'testmulti' FILESUFFIX], 'a', 'theta')
-

Copied: trunk/scipy/io/matlab/tests/save_matfile.m (from rev 4827, trunk/scipy/io/matlab/tests/save_test.m)

Deleted: trunk/scipy/io/matlab/tests/save_test.m
===================================================================
--- trunk/scipy/io/matlab/tests/save_test.m	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/tests/save_test.m	2008-11-09 00:44:40 UTC (rev 5025)
@@ -1,6 +0,0 @@
-function save_test(test_name, v)
-% saves variable passed in m with filename from prefix
-  
-global FILEPREFIX FILESUFFIX
-eval([test_name ' = v;']);
-save([FILEPREFIX test_name FILESUFFIX], test_name, '-V7.3')
\ No newline at end of file

Modified: trunk/scipy/io/matlab/tests/test_mio.py
===================================================================
--- trunk/scipy/io/matlab/tests/test_mio.py	2008-11-08 07:59:38 UTC (rev 5024)
+++ trunk/scipy/io/matlab/tests/test_mio.py	2008-11-09 00:44:40 UTC (rev 5025)
@@ -1,30 +1,41 @@
 #!/usr/bin/env python
 ''' Nose test generators '''
-import os
+from os.path import join, dirname
 from glob import glob
-from cStringIO import StringIO
+from StringIO import StringIO
 from tempfile import mkdtemp
-from numpy.testing import *
-from numpy import arange, array, pi, cos, exp, sin, sqrt, ndarray,  \
-     zeros, reshape, transpose, dtype, empty
+import warnings
+import shutil
+import gzip
+
+from numpy.testing import \
+     assert_array_almost_equal, \
+     assert_equal, \
+     assert_raises
+
+from nose.tools import assert_true
+
+import numpy as np
+from numpy import array
 import scipy.sparse as SP
 
 from scipy.io.matlab.mio import loadmat, savemat
 from scipy.io.matlab.mio5 import MatlabObject
 
-import shutil
-import gzip
+test_data_path = join(dirname(__file__), 'data')
 
-test_data_path = os.path.join(os.path.dirname(__file__), 'data')
-
 def _check_level(label, expected, actual):
     """ Check one level of a potentially nested object / list """
     # object array is returned from cell array in mat file
     typex = type(expected)
     typac = type(actual)
-    if isinstance(expected, ndarray) and expected.dtype.hasobject:
+    if isinstance(expected, np.ndarray) and expected.dtype.hasobject:
         assert typex is typac, "Different types at %s" % label
-        assert len(expected) == len(actual), "Different list lengths at %s" % label
+        assert len(expected) == len(actual), \
+               "Expected list length %d, got %d at %s" % (
+            len(expected),
+            len(actual),
+            label)
         for i, ev in enumerate(expected):
             level_label = "%s, [%d], " % (label, i)
             _check_level(level_label, ev, actual[i])
@@ -38,7 +49,8 @@
         for k in ex_fields:
             if k.startswith('__') and k.endswith('__'):
                 continue
-            assert k in ac_fields, "Missing property at %s" % label
+            assert k in ac_fields, \
+                   "Missing expected property %s for %s" % (k, label)
             ev = expected.__dict__[k]
             v = actual.__dict__[k]
             level_label = "%s, property %s, " % (label, k)
@@ -51,9 +63,14 @@
                                   expected.todense(),
                                   err_msg = label,
                                   decimal = 5)
-    elif isinstance(expected, ndarray):
+    elif isinstance(expected, np.ndarray) and \
+         expected.dtype.type not in (np.void,
+                                     np.unicode,
+                                     np.object,
+                                     np.unicode_):
         if expected.shape: # allow scalar and 0d array comparisons
-            assert isinstance(actual, ndarray), "Expected ndarray at %s" % label
+            assert isinstance(actual, np.ndarray), \
+                   "Expected ndarray at %s" % label
         assert_array_almost_equal(actual, expected, err_msg=label, decimal=5)
     else:
         assert isinstance(expected, typac), \
@@ -78,20 +95,21 @@
     _check_case(name, [mat_stream], expected)
 
 # Define cases to test
-theta = pi/4*arange(9,dtype=float).reshape(9,1)
+theta = np.pi/4*np.arange(9,dtype=float).reshape(1,9)
 case_table4 = [
     {'name': 'double',
      'expected': {'testdouble': theta}
      }]
 case_table4.append(
     {'name': 'string',
-     'expected': {'teststring': u'"Do nine men interpret?" "Nine men," I nod.'},
+     'expected': {'teststring':
+                  array([u'"Do nine men interpret?" "Nine men," I nod.'])},
      })
 case_table4.append(
     {'name': 'complex',
-     'expected': {'testcomplex': cos(theta) + 1j*sin(theta)}
+     'expected': {'testcomplex': np.cos(theta) + 1j*np.sin(theta)}
      })
-A = zeros((3,5))
+A = np.zeros((3,5))
 A[0] = range(1,6)
 A[:,0] = range(1,4)
 case_table4.append(
@@ -119,34 +137,42 @@
      })
 case_table4.append(
     {'name': 'onechar',
-     'expected': {'testonechar': u'r'},
+     'expected': {'testonechar': array([u'r'])},
      })
 case_table5 = [
     {'name': 'cell',
      'expected': {'testcell':
-                  array([u'This cell contains this string and 3 arrays of '+\
-                         'increasing length',
-                         array(1), array([1,2]), array([1,2,3])],
-                        dtype=object)}
+                  array([[
+    array([u'This cell contains this string and 3 arrays of increasing length']),
+    array([[1]]),
+    array([[1,2]]),
+    array([[1,2,3]])
+    ]], dtype=object)}
      }]
 case_table5.append(
     {'name': 'emptycell',
      'expected': {'testemptycell':
-                  array([array(1), array(2), array([]),
-                         array([]), array(3)], dtype=object)}
+                  array([[
+    array([[1]]),
+    array([[2]]),
+    array([[]]), # This not returning with correct shape
+    array([[]]),
+    array([[3]])]], dtype=object)}
      })
 case_table5.append(
     {'name': 'stringarray',
      'expected': {'teststringarray': array(
-    [u'one  ', u'two  ', u'three'], dtype=object)},
+    [u'one  ', u'two  ', u'three'])},
      })
 case_table5.append(
     {'name': '3dmatrix',
-     'expected': {'test3dmatrix': transpose(reshape(range(1,25), (4,3,2)))}
+     'expected': {
+    'test3dmatrix': np.transpose(np.reshape(range(1,25), (4,3,2)))}
      })
 case_table5_rt = [
     {'name': '3dmatrix',
-     'expected': {'test3dmatrix': transpose(reshape(range(1,25), (4,3,2)))}
+     'expected': {
+    'test3dmatrix': np.transpose(np.reshape(range(1,25), (4,3,2)))}
      },
     {'name': 'sparsefloat',
      'expected': {'testsparsefloat': SP.csc_matrix(array([[1,0,2],[0,-3.5,0]]))},
@@ -155,11 +181,16 @@
      'expected': {'testsparsefloat': SP.csc_matrix(array([[-1+2j,0,2],[0,-3j,0]]))},
      },
     ]
-st = array([(u'Rats live on no evil star.', array([sqrt(2),exp(1),pi]), (1+1j)*array([sqrt(2),exp(1),pi]))],
-           dtype=[(n, object) for n in ['stringfield', 'doublefield', 'complexfield']])
+sr2 = np.sqrt(2)
+dtype = [(n, object) for n in ['stringfield', 'doublefield', 'complexfield']]
+st1 = array([
+    [(u'Rats live on no evil star.',
+      array([sr2,np.exp(1), np.pi]),
+      (1+1j)*array([sr2,np.exp(1), np.pi]))]
+    ], dtype=dtype)
 case_table5.append(
     {'name': 'struct',
-     'expected': {'teststruct': st}
+     'expected': {'teststruct': st1}
      })
 a = array([array(1),
            array([array(2), array(3),
@@ -171,15 +202,15 @@
     {'name': 'cellnest',
      'expected': {'testcellnest': a},
      })
-st = empty((1,1), dtype=[(n, object) for n in ['one', 'two']])
-st[0,0]['one'] = array(1)
-st[0,0]['two'] = empty((1,1), dtype=[('three', object)])
-st[0,0]['two'][0,0]['three'] = u'number 3'
+st2 = np.empty((1,1), dtype=[(n, object) for n in ['one', 'two']])
+st2[0,0]['one'] = array(1)
+st2[0,0]['two'] = np.empty((1,1), dtype=[('three', object)])
+st2[0,0]['two'][0,0]['three'] = u'number 3'
 case_table5.append(
     {'name': 'structnest',
-     'expected': {'teststructnest': st}
+     'expected': {'teststructnest': st2}
      })
-a = empty((2,1), dtype=[(n, object) for n in ['one', 'two']])
+a = np.empty((2,1), dtype=[(n, object) for n in ['one', 'two']])
 a[0,0]['one'] = array(1)
 a[0,0]['two'] = array(2)
 a[1,0]['one'] = u'number 1'
@@ -188,7 +219,9 @@
     {'name': 'structarr',
      'expected': {'teststructarr': a}
      })
-a = MatlabObject('inline', ['expr', 'args', 'isEmpty', 'numArgs', 'version'])
+a = MatlabObject('inline',
+                 ['expr', 'inputExpr', 'args',
+                  'isEmpty', 'numArgs', 'version'])
 a.expr = u'x'
 a.inputExpr = u' x = INLINE_INPUTS_{1};'
 a.args = u'x'
@@ -200,35 +233,33 @@
      'expected': {'testobject': a}
      })
 u_str = file(
-    os.path.join(test_data_path, 'japanese_utf8.txt'),
+    join(test_data_path, 'japanese_utf8.txt'),
     'rb').read().decode('utf-8')
 case_table5.append(
     {'name': 'unicode',
-    'expected': {'testunicode': u_str}
+    'expected': {'testunicode': array(u_str)}
     })
 
 # generator for load tests
-@dec.knownfailureif(True)
 def test_load():
     for case in case_table4 + case_table5:
         name = case['name']
         expected = case['expected']
-        filt = os.path.join(test_data_path, 'test%s_*.mat' % name)
+        filt = join(test_data_path, 'test%s_*.mat' % name)
         files = glob(filt)
         assert files, "No files for test %s using filter %s" % (name, filt)
         yield _check_case, name, files, expected
 
 # generator for round trip tests
-@dec.knownfailureif(True)
 def test_round_trip():
     for case in case_table4 + case_table5_rt:
         name = case['name'] + '_round_trip'
         expected = case['expected']
         format = case in case_table4 and '4' or '5'
-        #yield _rt_check_case, name, expected, format
+        yield _rt_check_case, name, expected, format
 
 def test_gzip_simple():
-    xdense = zeros((20,20))
+    xdense = np.zeros((20,20))
     xdense[2,3]=2.3
     xdense[4,5]=4.5
     x = SP.csc_matrix(xdense)
@@ -239,7 +270,7 @@
 
     tmpdir = mkdtemp()
     try:
-        fname = os.path.join(tmpdir,name)
+        fname = join(tmpdir,name)
         mat_stream = gzip.open( fname,mode='wb')
         savemat(mat_stream, expected, format=format)
         mat_stream.close()
@@ -257,6 +288,28 @@
 def test_mat73():
     # Check any hdf5 files raise an error
     filenames = glob(
-        os.path.join(test_data_path, 'testhdf5*.mat'))
+        join(test_data_path, 'testhdf5*.mat'))
+    assert len(filenames)
     for filename in filenames:
         assert_raises(NotImplementedError, loadmat, filename, struct_as_record=True)
+
+def test_warn_struct_record():
+    # Use buffer hack to test for deprecation warning
+    warn_buf = StringIO()
+    base_show = warnings.showwarning
+    def showwarn(*args):
+        base_show(*args, **{'file':warn_buf})
+    fname = join(test_data_path, 'testdouble_7.1_GLNX86.mat')
+    try:
+        warnings.showwarning = showwarn
+        # This should not generate a deprecation warning
+        mres = loadmat(fname, struct_as_record=True)
+        yield assert_true, warn_buf.tell() == 0
+        # This neither
+        mres = loadmat(fname, struct_as_record=False)
+        yield assert_true, warn_buf.tell() == 0
+        # This should
+        mres = loadmat(fname)
+        yield assert_true, warn_buf.tell() > 0
+    finally:
+        warnings.showwarning = base_show



More information about the Scipy-svn mailing list