[Git][debian-gis-team/netcdf4-python][master] 4 commits: New upstream version 1.4.1

Bas Couwenberg gitlab at salsa.debian.org
Wed Aug 15 06:29:08 BST 2018


Bas Couwenberg pushed to branch master at Debian GIS Project / netcdf4-python


Commits:
629b13b4 by Bas Couwenberg at 2018-08-15T05:01:43Z
New upstream version 1.4.1
- - - - -
44868a4f by Bas Couwenberg at 2018-08-15T05:01:45Z
Merge tag 'upstream/1.4.1'

Upstream version 1.4.1

- - - - -
eba2a003 by Bas Couwenberg at 2018-08-15T05:02:04Z
New upstream release.

- - - - -
3218ad8f by Bas Couwenberg at 2018-08-15T05:02:54Z
Set distribution to unstable.

- - - - -


11 changed files:

- Changelog
- PKG-INFO
- README.md
- debian/changelog
- docs/netCDF4/index.html
- netCDF4/_netCDF4.pyx
- setup.py
- test/tst_cdf5.py
- + test/tst_masked6.py
- test/tst_multifile.py
- test/tst_multifile2.py


Changes:

=====================================
Changelog
=====================================
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,12 @@
- version 1.4.0 (not yet released)
+ version 1.4.1 (tag v1.4.1rel)
+=============================
+ * disable workaround for slow nc_get_vars for __netcdflibversion__ >= 4.6.2,
+   since a fix was added to speed up nc_get_vars in the C library.  Issue 680.
+ * new Dataset and Variable methods (set_always_mask) to optionally
+   re-enable old behaviour (return masked arrays
+   only if selected slice contains missing values) (issue #809).
+	
+ version 1.4.0 (tag v1.4.0rel)
 =============================
  * fixed bug in detection of CDF5 library support in setup.py (pull request
    #736, issue #713).


=====================================
PKG-INFO
=====================================
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: netCDF4
-Version: 1.4.0
+Version: 1.4.1
 Author: Jeff Whitaker
 Author-email: jeffrey s whitaker at noaa gov
 Home-page: https://github.com/Unidata/netcdf4-python


=====================================
README.md
=====================================
--- a/README.md
+++ b/README.md
@@ -8,7 +8,11 @@
 ## News
 For details on the latest updates, see the [Changelog](https://github.com/Unidata/netcdf4-python/blob/master/Changelog).
 
-??/??/2018: Version [1.4.0](https://pypi.python.org/pypi/netCDF4/1.4.0) released. The netcdftime package is no longer
+08/10/2018: Version [1.4.1](https://pypi.python.org/pypi/netCDF4/1.4.1) released. The old slicing behavior
+(numpy array returned unless missing values are present, otherwise masked array returned) is renabled
+via `set_always_mask(False)`.
+
+05/11/2018: Version [1.4.0](https://pypi.python.org/pypi/netCDF4/1.4.0) released. The netcdftime package is no longer
 included, it is now a separate [package](https://pypi.python.org/pypi/cftime) dependency.  In addition to several
 bug fixes, there are a few important changes to the default behaviour to note:
  * Slicing a netCDF variable will now always return masked array by default, even if there are no 


=====================================
debian/changelog
=====================================
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,11 @@
-netcdf4-python (1.4.0-2) UNRELEASED; urgency=medium
+netcdf4-python (1.4.1-1) unstable; urgency=medium
 
+  * New upstream release.
   * Bump Standards-Version to 4.2.0, no changes.
   * Drop autopkgtests to test installability & module import.
   * Add lintian override for testsuite-autopkgtest-missing.
 
- -- Bas Couwenberg <sebastic at debian.org>  Thu, 05 Jul 2018 10:36:28 +0200
+ -- Bas Couwenberg <sebastic at debian.org>  Wed, 15 Aug 2018 07:02:39 +0200
 
 netcdf4-python (1.4.0-1) unstable; urgency=medium
 


=====================================
docs/netCDF4/index.html
=====================================
--- a/docs/netCDF4/index.html
+++ b/docs/netCDF4/index.html
@@ -4,7 +4,7 @@
   <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
 
     <title>netCDF4 API documentation</title>
-    <meta name="description" content="Version 1.4.0
+    <meta name="description" content="Version 1.4.1
 -------------
 - - - 
 
@@ -1090,6 +1090,7 @@ table {
     <li class="mono"><a href="#netCDF4.Dataset.renameDimension">renameDimension</a></li>
     <li class="mono"><a href="#netCDF4.Dataset.renameGroup">renameGroup</a></li>
     <li class="mono"><a href="#netCDF4.Dataset.renameVariable">renameVariable</a></li>
+    <li class="mono"><a href="#netCDF4.Dataset.set_always_mask">set_always_mask</a></li>
     <li class="mono"><a href="#netCDF4.Dataset.set_auto_chartostring">set_auto_chartostring</a></li>
     <li class="mono"><a href="#netCDF4.Dataset.set_auto_mask">set_auto_mask</a></li>
     <li class="mono"><a href="#netCDF4.Dataset.set_auto_maskandscale">set_auto_maskandscale</a></li>
@@ -1146,6 +1147,7 @@ table {
     <li class="mono"><a href="#netCDF4.Group.renameDimension">renameDimension</a></li>
     <li class="mono"><a href="#netCDF4.Group.renameGroup">renameGroup</a></li>
     <li class="mono"><a href="#netCDF4.Group.renameVariable">renameVariable</a></li>
+    <li class="mono"><a href="#netCDF4.Group.set_always_mask">set_always_mask</a></li>
     <li class="mono"><a href="#netCDF4.Group.set_auto_chartostring">set_auto_chartostring</a></li>
     <li class="mono"><a href="#netCDF4.Group.set_auto_mask">set_auto_mask</a></li>
     <li class="mono"><a href="#netCDF4.Group.set_auto_maskandscale">set_auto_maskandscale</a></li>
@@ -1182,6 +1184,7 @@ table {
     <li class="mono"><a href="#netCDF4.MFDataset.renameDimension">renameDimension</a></li>
     <li class="mono"><a href="#netCDF4.MFDataset.renameGroup">renameGroup</a></li>
     <li class="mono"><a href="#netCDF4.MFDataset.renameVariable">renameVariable</a></li>
+    <li class="mono"><a href="#netCDF4.MFDataset.set_always_mask">set_always_mask</a></li>
     <li class="mono"><a href="#netCDF4.MFDataset.set_auto_chartostring">set_auto_chartostring</a></li>
     <li class="mono"><a href="#netCDF4.MFDataset.set_auto_mask">set_auto_mask</a></li>
     <li class="mono"><a href="#netCDF4.MFDataset.set_auto_maskandscale">set_auto_maskandscale</a></li>
@@ -1236,6 +1239,7 @@ table {
     <li class="mono"><a href="#netCDF4.Variable.group">group</a></li>
     <li class="mono"><a href="#netCDF4.Variable.ncattrs">ncattrs</a></li>
     <li class="mono"><a href="#netCDF4.Variable.renameAttribute">renameAttribute</a></li>
+    <li class="mono"><a href="#netCDF4.Variable.set_always_mask">set_always_mask</a></li>
     <li class="mono"><a href="#netCDF4.Variable.set_auto_chartostring">set_auto_chartostring</a></li>
     <li class="mono"><a href="#netCDF4.Variable.set_auto_mask">set_auto_mask</a></li>
     <li class="mono"><a href="#netCDF4.Variable.set_auto_maskandscale">set_auto_maskandscale</a></li>
@@ -1264,7 +1268,7 @@ table {
 
   <header id="section-intro">
   <h1 class="title"><span class="name">netCDF4</span> module</h1>
-  <h2>Version 1.4.0</h2>
+  <h2>Version 1.4.1</h2>
 <hr />
 <h1>Introduction</h1>
 <p>netcdf4-python is a Python interface to the netCDF C library.  </p>
@@ -1772,6 +1776,17 @@ Hemisphere longitudes, resulting in a numpy array of shape  (3, 3, 36, 71).</p>
 <p><strong><em>Special note for scalar variables</em></strong>: To extract data from a scalar variable
 <code>v</code> with no associated dimensions, use <code>numpy.asarray(v)</code> or <code>v[...]</code>. The result
 will be a numpy scalar array.</p>
+<p>By default, netcdf4-python returns numpy masked arrays with values equal to the
+<code>missing_value</code> or <code>_FillValue</code> variable attributes masked.  The
+<a href="#netCDF4.Dataset.set_auto_mask"><code>set_auto_mask</code></a>  <a href="#netCDF4.Dataset"><code>Dataset</code></a> and <a href="#netCDF4.Variable"><code>Variable</code></a> methods
+can be used to disable this feature so that
+numpy arrays are always returned, with the missing values included. Prior to
+version 1.4.0 the default behavior was to only return masked arrays when the
+requested slice contained missing values.  This behavior can be recovered
+using the <a href="#netCDF4.Dataset.set_always_mask"><code>set_always_mask</code></a> method. If a masked array is
+written to a netCDF variable, the masked elements are filled with the
+value specified by the <code>missing_value</code> attribute.  If the variable has
+no <code>missing_value</code>, the <code>_FillValue</code> is used instead.</p>
 <h2><div id='section7'>7) Dealing with time coordinates.</h2>
 <p>Time coordinate values pose a special challenge to netCDF users.  Most
 metadata standards (such as CF) specify that time should be
@@ -3291,6 +3306,29 @@ character encoding of a string attribute (default is <code>utf-8</code>).</p></d
   
             
   <div class="item">
+    <div class="name def" id="netCDF4.Dataset.set_always_mask">
+    <p>def <span class="ident">set_always_mask</span>(</p><p>self, True_or_False)</p>
+    </div>
+    
+
+    
+  
+    <div class="desc"><p>Call <a href="#netCDF4.Variable.set_always_mask"><code>set_always_mask</code></a> for all variables contained in
+this <a href="#netCDF4.Dataset"><code>Dataset</code></a> or <a href="#netCDF4.Group"><code>Group</code></a>, as well as for all
+variables in all its subgroups.</p>
+<p><strong><code>True_or_False</code></strong>: Boolean determining if automatic conversion of
+masked arrays with no missing values to regular ararys shall be
+applied for all variables.</p>
+<p><strong><em>Note</em></strong>: Calling this function only affects existing
+variables. Variables created after calling this function will follow
+the default behaviour.</p></div>
+  <div class="source_cont">
+</div>
+
+  </div>
+  
+            
+  <div class="item">
     <div class="name def" id="netCDF4.Dataset.set_auto_chartostring">
     <p>def <span class="ident">set_auto_chartostring</span>(</p><p>self, True_or_False)</p>
     </div>
@@ -4264,6 +4302,29 @@ character encoding of a string attribute (default is <code>utf-8</code>).</p></d
   
             
   <div class="item">
+    <div class="name def" id="netCDF4.Group.set_always_mask">
+    <p>def <span class="ident">set_always_mask</span>(</p><p>self, True_or_False)</p>
+    </div>
+    
+
+    
+  
+    <div class="desc"><p>Call <a href="#netCDF4.Variable.set_always_mask"><code>set_always_mask</code></a> for all variables contained in
+this <a href="#netCDF4.Dataset"><code>Dataset</code></a> or <a href="#netCDF4.Group"><code>Group</code></a>, as well as for all
+variables in all its subgroups.</p>
+<p><strong><code>True_or_False</code></strong>: Boolean determining if automatic conversion of
+masked arrays with no missing values to regular ararys shall be
+applied for all variables.</p>
+<p><strong><em>Note</em></strong>: Calling this function only affects existing
+variables. Variables created after calling this function will follow
+the default behaviour.</p></div>
+  <div class="source_cont">
+</div>
+
+  </div>
+  
+            
+  <div class="item">
     <div class="name def" id="netCDF4.Group.set_auto_chartostring">
     <p>def <span class="ident">set_auto_chartostring</span>(</p><p>self, True_or_False)</p>
     </div>
@@ -5069,6 +5130,29 @@ character encoding of a string attribute (default is <code>utf-8</code>).</p></d
   
             
   <div class="item">
+    <div class="name def" id="netCDF4.MFDataset.set_always_mask">
+    <p>def <span class="ident">set_always_mask</span>(</p><p>self, True_or_False)</p>
+    </div>
+    
+
+    
+  
+    <div class="desc"><p>Call <a href="#netCDF4.Variable.set_always_mask"><code>set_always_mask</code></a> for all variables contained in
+this <a href="#netCDF4.Dataset"><code>Dataset</code></a> or <a href="#netCDF4.Group"><code>Group</code></a>, as well as for all
+variables in all its subgroups.</p>
+<p><strong><code>True_or_False</code></strong>: Boolean determining if automatic conversion of
+masked arrays with no missing values to regular ararys shall be
+applied for all variables.</p>
+<p><strong><em>Note</em></strong>: Calling this function only affects existing
+variables. Variables created after calling this function will follow
+the default behaviour.</p></div>
+  <div class="source_cont">
+</div>
+
+  </div>
+  
+            
+  <div class="item">
     <div class="name def" id="netCDF4.MFDataset.set_auto_chartostring">
     <p>def <span class="ident">set_auto_chartostring</span>(</p><p>self, True_or_False)</p>
     </div>
@@ -5542,6 +5626,16 @@ behavior is similar to Fortran or Matlab, but different than numpy.</p>
           </ul>
           <h3>Class variables</h3>
             <div class="item">
+            <p id="netCDF4.Variable.always_mask" class="name">var <span class="ident">always_mask</span></p>
+            
+
+            
+  
+  <div class="source_cont">
+</div>
+
+            </div>
+            <div class="item">
             <p id="netCDF4.Variable.chartostring" class="name">var <span class="ident">chartostring</span></p>
             
 
@@ -5928,6 +6022,26 @@ character encoding of a string attribute (default is <code>utf-8</code>).</p></d
   
             
   <div class="item">
+    <div class="name def" id="netCDF4.Variable.set_always_mask">
+    <p>def <span class="ident">set_always_mask</span>(</p><p>self,always_mask)</p>
+    </div>
+    
+
+    
+  
+    <div class="desc"><p>turn on or off conversion of data without missing values to regular
+numpy arrays.</p>
+<p>If <code>always_mask</code> is set to <code>True</code> then a masked array with no missing
+values is converted to a regular numpy array.</p>
+<p>The default value of <code>always_mask</code> is <code>True</code> (conversions to regular
+numpy arrays are not performed).</p></div>
+  <div class="source_cont">
+</div>
+
+  </div>
+  
+            
+  <div class="item">
     <div class="name def" id="netCDF4.Variable.set_auto_chartostring">
     <p>def <span class="ident">set_auto_chartostring</span>(</p><p>self,chartostring)</p>
     </div>
@@ -6184,8 +6298,9 @@ each attribute</p></div>
   
     <div class="desc"><p>enable the use of netcdf library routine <code>nc_get_vars</code>
 to retrieve strided variable slices.  By default,
-<code>nc_get_vars</code> not used since it slower than multiple calls
-to the unstrided read routine <code>nc_get_vara</code> in most cases.</p></div>
+<code>nc_get_vars</code> may not used by default (depending on the
+version of the netcdf-c library being used) since it may be
+slower than multiple calls to the unstrided read routine <code>nc_get_vara</code>.</p></div>
   <div class="source_cont">
 </div>
 


=====================================
netCDF4/_netCDF4.pyx
=====================================
--- a/netCDF4/_netCDF4.pyx
+++ b/netCDF4/_netCDF4.pyx
@@ -1,5 +1,5 @@
 """
-Version 1.4.0
+Version 1.4.1
 -------------
 - - - 
 
@@ -539,6 +539,18 @@ Hemisphere longitudes, resulting in a numpy array of shape  (3, 3, 36, 71).
 `v` with no associated dimensions, use `numpy.asarray(v)` or `v[...]`. The result
 will be a numpy scalar array.
 
+By default, netcdf4-python returns numpy masked arrays with values equal to the
+`missing_value` or `_FillValue` variable attributes masked.  The
+`netCDF4.Dataset.set_auto_mask`  `netCDF4.Dataset` and `netCDF4.Variable` methods
+can be used to disable this feature so that
+numpy arrays are always returned, with the missing values included. Prior to
+version 1.4.0 the default behavior was to only return masked arrays when the
+requested slice contained missing values.  This behavior can be recovered
+using the `netCDF4.Dataset.set_always_mask` method. If a masked array is
+written to a netCDF variable, the masked elements are filled with the
+value specified by the `missing_value` attribute.  If the variable has
+no `missing_value`, the `_FillValue` is used instead.
+
 ## <div id='section7'>7) Dealing with time coordinates.
 
 Time coordinate values pose a special challenge to netCDF users.  Most
@@ -1092,7 +1104,7 @@ except ImportError:
     # python3: zip is already python2's itertools.izip
     pass
 
-__version__ = "1.4.0"
+__version__ = "1.4.1"
 
 # Initialize numpy
 import posixpath
@@ -1470,7 +1482,7 @@ cdef _set_att(grp, int varid, name, value,\
         if value_arr.dtype.kind == 'V': # compound attribute.
             xtype = _find_cmptype(grp,value_arr.dtype)
         elif value_arr.dtype.str[1:] not in _supportedtypes:
-            raise TypeError, 'illegal data type for attribute, must be one of %s, got %s' % (_supportedtypes, value_arr.dtype.str[1:])
+            raise TypeError, 'illegal data type for attribute %r, must be one of %s, got %s' % (attname, _supportedtypes, value_arr.dtype.str[1:])
         elif xtype == -99: # if xtype is not passed in as kwarg.
             xtype = _nptonctype[value_arr.dtype.str[1:]]
         lenarr = PyArray_SIZE(value_arr)
@@ -2840,6 +2852,31 @@ after calling this function will follow the default behaviour.
                 for var in group.variables.values():
                     var.set_auto_scale(value)
 
+    def set_always_mask(self, value):
+        """
+**`set_always_mask(self, True_or_False)`**
+
+Call `netCDF4.Variable.set_always_mask` for all variables contained in
+this `netCDF4.Dataset` or `netCDF4.Group`, as well as for all
+variables in all its subgroups.
+
+**`True_or_False`**: Boolean determining if automatic conversion of
+masked arrays with no missing values to regular ararys shall be
+applied for all variables.
+
+***Note***: Calling this function only affects existing
+variables. Variables created after calling this function will follow
+the default behaviour.
+        """
+
+        for var in self.variables.values():
+            var.set_always_mask(value)
+
+        for groups in _walk_grps(self):
+            for group in groups:
+                for var in group.variables.values():
+                    var.set_always_mask(value)
+
     def get_variables_by_attributes(self, **kwargs):
         """
 **`get_variables_by_attribute(self, **kwargs)`**
@@ -3200,8 +3237,8 @@ behavior is similar to Fortran or Matlab, but different than numpy.
 **`size`**: The number of stored elements.
     """
     cdef public int _varid, _grpid, _nunlimdim
-    cdef public _name, ndim, dtype, mask, scale, chartostring,  _isprimitive, _iscompound,\
-    _isvlen, _isenum, _grp, _cmptype, _vltype, _enumtype,\
+    cdef public _name, ndim, dtype, mask, scale, always_mask, chartostring,  _isprimitive, \
+    _iscompound, _isvlen, _isenum, _grp, _cmptype, _vltype, _enumtype,\
     __orthogonal_indexing__, _has_lsd, _no_get_vars
     # Docstrings for class variables (used by pdoc).
     __pdoc__['Variable.dimensions'] = \
@@ -3600,13 +3637,21 @@ behavior is similar to Fortran or Matlab, but different than numpy.
         # add_offset, and converting to/from masked arrays is True.
         self.scale = True
         self.mask = True
+        # issue 809: default for converting arrays with no missing values to
+        # regular numpy arrays
+        self.always_mask = True
         # default is to automatically convert to/from character
         # to string arrays when _Encoding variable attribute is set.
         self.chartostring = True
         if 'least_significant_digit' in self.ncattrs():
             self._has_lsd = True
         # avoid calling nc_get_vars for strided slices by default.
-        self._no_get_vars = True
+        # a fix for strided slice access using HDF5 was added
+        # in 4.6.2.
+        if __netcdf4libversion__ >= "4.6.2":
+            self._no_get_vars = False
+        else:
+            self._no_get_vars = True
 
     def __array__(self):
         # numpy special method that returns a numpy array.
@@ -4290,12 +4335,12 @@ rename a `netCDF4.Variable` attribute named `oldname` to `newname`."""
         if fill_value is None:
             fill_value = default_fillvals[self.dtype.str[1:]]
         # create masked array with computed mask
-        if totalmask.any():
+        masked_values = bool(totalmask.any())
+        if masked_values:
             data = ma.masked_array(data,mask=totalmask,fill_value=fill_value)
         else:
             # issue #785: always return masked array, if no values masked
-            # set mask=False.
-            data = ma.masked_array(data,mask=False,fill_value=fill_value)
+            data = ma.masked_array(data)
         # issue 515 scalar array with mask=True should be converted
         # to numpy.ma.MaskedConstant to be consistent with slicing
         # behavior of masked arrays.
@@ -4303,6 +4348,11 @@ rename a `netCDF4.Variable` attribute named `oldname` to `newname`."""
             # return a scalar numpy masked constant not a 0-d masked array,
             # so that data == numpy.ma.masked.
             data = data[()] # changed from [...] (issue #662)
+        elif not self.always_mask and not masked_values:
+            # issue #809: return a regular numpy array if requested
+            # and there are no missing values
+            data = numpy.array(data, copy=False)
+            
         return data
 
     def _assign_vlen(self, elem, data):
@@ -4634,8 +4684,9 @@ The default value of `chartostring` is `True`
 
 enable the use of netcdf library routine `nc_get_vars`
 to retrieve strided variable slices.  By default,
-`nc_get_vars` not used since it slower than multiple calls
-to the unstrided read routine `nc_get_vara` in most cases.
+`nc_get_vars` may not used by default (depending on the
+version of the netcdf-c library being used) since it may be
+slower than multiple calls to the unstrided read routine `nc_get_vara`.
         """
         self._no_get_vars = not bool(use_nc_get_vars)
         
@@ -4757,6 +4808,21 @@ The default value of `mask` is `True`
         """
         self.mask = bool(mask)
         
+    def set_always_mask(self,always_mask):
+        """
+**`set_always_mask(self,always_mask)`**
+
+turn on or off conversion of data without missing values to regular
+numpy arrays.
+
+If `always_mask` is set to `True` then a masked array with no missing
+values is converted to a regular numpy array.
+
+The default value of `always_mask` is `True` (conversions to regular
+numpy arrays are not performed).
+
+        """
+        self.always_mask = bool(always_mask)
 
     def _put(self,ndarray data,start,count,stride):
         """Private method to put data into a netCDF variable"""


=====================================
setup.py
=====================================
--- a/setup.py
+++ b/setup.py
@@ -553,7 +553,7 @@ else:
 
 setup(name="netCDF4",
       cmdclass=cmdclass,
-      version="1.4.0",
+      version="1.4.1",
       long_description="netCDF version 4 has many features not found in earlier versions of the library, such as hierarchical groups, zlib compression, multiple unlimited dimensions, and new data types.  It is implemented on top of HDF5.  This module implements most of the new features, and can read and write netCDF files compatible with older versions of the library.  The API is modelled after Scientific.IO.NetCDF, and should be familiar to users of that module.\n\nThis project is hosted on a `GitHub repository <https://github.com/Unidata/netcdf4-python>`_ where you may access the most up-to-date source.",
       author="Jeff Whitaker",
       author_email="jeffrey.s.whitaker at noaa.gov",


=====================================
test/tst_cdf5.py
=====================================
--- a/test/tst_cdf5.py
+++ b/test/tst_cdf5.py
@@ -4,7 +4,7 @@ import sys, os, unittest, tempfile
 from numpy.testing import assert_array_equal
 
 FILE_NAME = tempfile.NamedTemporaryFile(suffix='.nc', delete=False).name
-dimsize = np.iinfo(np.int64).max # max unsigned 64 bit integer
+dimsize = np.iinfo(np.int32).max*2 # only allowed in CDF5
 ndim = 100
 arrdata = np.random.randint(np.iinfo(np.uint8).min,np.iinfo(np.uint8).max,size=ndim)
 


=====================================
test/tst_masked6.py
=====================================
--- /dev/null
+++ b/test/tst_masked6.py
@@ -0,0 +1,136 @@
+import unittest
+import os
+import tempfile
+
+import numpy as np
+from numpy import ma
+from numpy.testing import assert_array_almost_equal
+from netCDF4 import Dataset
+
+# Test automatic conversion of masked arrays (set_always_mask())
+
+class SetAlwaysMaskTestBase(unittest.TestCase):
+
+    """Base object for tests checking the functionality of set_always_mask()"""
+
+    def setUp(self):
+
+        self.testfile = tempfile.NamedTemporaryFile(suffix='.nc', delete=False).name
+
+        self.v = np.array([4, 3, 2, 1], dtype="i2")
+        self.w = np.ma.array([-1, -2, -3, -4], mask=[False, True, False, False], dtype="i2")
+                  
+        f = Dataset(self.testfile, 'w')
+        _ = f.createDimension('x', None)
+        v = f.createVariable('v', "i2", 'x')
+        w = f.createVariable('w', "i2", 'x')
+
+        v[...] = self.v
+        w[...] = self.w
+
+        f.close()
+        
+    def tearDown(self):
+
+        os.remove(self.testfile)
+
+
+class SetAlwaysMaskTrue(SetAlwaysMaskTestBase):
+
+    def test_always_mask(self):
+        
+        """Testing auto-conversion of masked arrays with no missing values to regular arrays."""
+        f = Dataset(self.testfile)
+
+        f.variables["v"].set_always_mask(True) # The default anyway...
+
+        v = f.variables['v'][:]
+
+        self.assertTrue(isinstance(v, np.ndarray))
+        self.assertTrue(isinstance(v, ma.core.MaskedArray))
+        assert_array_almost_equal(v, self.v)
+
+        w = f.variables['w'][:]
+
+        self.assertTrue(isinstance(w, np.ndarray))
+        self.assertTrue(isinstance(w, ma.core.MaskedArray))
+        assert_array_almost_equal(w, self.w)
+        
+        f.close()
+
+class SetAlwyasMaskFalse(SetAlwaysMaskTestBase):
+
+    def test_always_mask(self):
+        
+        """Testing auto-conversion of masked arrays with no missing values to regular arrays."""
+        f = Dataset(self.testfile)
+
+        f.variables["v"].set_always_mask(False)
+        v = f.variables['v'][:]
+
+        self.assertTrue(isinstance(v, np.ndarray))
+        self.assertFalse(isinstance(v, ma.core.MaskedArray))
+        assert_array_almost_equal(v, self.v)
+
+        w = f.variables['w'][:]
+
+        self.assertTrue(isinstance(w, np.ndarray))
+        self.assertTrue(isinstance(w, ma.core.MaskedArray))
+        assert_array_almost_equal(w, self.w)
+
+        f.close()
+
+class GlobalSetAlwaysMaskTest(unittest.TestCase):
+
+    def setUp(self):
+
+        self.testfile = tempfile.NamedTemporaryFile(suffix='.nc', delete=False).name
+
+        f = Dataset(self.testfile, 'w')
+
+        grp1 = f.createGroup('Group1')
+        grp2 = f.createGroup('Group2')
+        f.createGroup('Group3')         # empty group
+
+        f.createVariable('var0', "i2", ())
+        grp1.createVariable('var1', 'f8', ())
+        grp2.createVariable('var2', 'f4', ())
+
+        f.close()
+
+    def tearDown(self):
+
+        os.remove(self.testfile)
+
+    def runTest(self):
+
+        # Note: The default behaviour is to always return masked
+        #       arrays, which is already tested elsewhere.
+
+        f = Dataset(self.testfile, "r")
+
+        # Without regular numpy arrays
+
+        f.set_always_mask(True)
+
+        v0 = f.variables['var0']
+        v1 = f.groups['Group1'].variables['var1']
+        v2 = f.groups['Group2'].variables['var2']
+
+        self.assertTrue(v0.always_mask)
+        self.assertTrue(v1.always_mask)
+        self.assertTrue(v2.always_mask)
+
+        # With regular numpy arrays
+
+        f.set_always_mask(False)
+
+        self.assertFalse(v0.always_mask)
+        self.assertFalse(v1.always_mask)
+        self.assertFalse(v2.always_mask)
+
+        f.close()
+
+
+if __name__ == '__main__':
+    unittest.main()


=====================================
test/tst_multifile.py
=====================================
--- a/test/tst_multifile.py
+++ b/test/tst_multifile.py
@@ -4,6 +4,8 @@ from numpy.random import seed, randint
 from numpy.testing import assert_array_equal, assert_equal
 from numpy import ma
 import tempfile, unittest, os, datetime
+import cftime
+from pkg_resources import parse_version
 
 nx=100; ydim=5; zdim=10
 nfiles = 10
@@ -112,12 +114,15 @@ class NonuniformTimeTestCase(unittest.TestCase):
         calendar = 'standard'
 
         # Get the real dates
-        dates = []
-        for file in self.files:
-            f = Dataset(file)
-            t = f.variables['time']
-            dates.extend(num2date(t[:], t.units, calendar))
-            f.close()
+        # skip this until cftime pull request #55 is in a released
+        # version (1.0.1?). Otherwise, fix for issue #808 breaks this
+        if parse_version(cftime.__version__) >= parse_version('1.0.1'):
+            dates = []
+            for file in self.files:
+                f = Dataset(file)
+                t = f.variables['time']
+                dates.extend(num2date(t[:], t.units, calendar))
+                f.close()
 
         # Compare with the MF dates
         f = MFDataset(self.files,check=True)
@@ -129,7 +134,10 @@ class NonuniformTimeTestCase(unittest.TestCase):
         assert_equal(T.shape, t.shape)
         assert_equal(T.dimensions, t.dimensions)
         assert_equal(T.typecode(), t.typecode())
-        assert_array_equal(num2date(T[:], T.units, T.calendar), dates)
+        # skip this until cftime pull request #55 is in a released
+        # version (1.0.1?). Otherwise, fix for issue #808 breaks this
+        if parse_version(cftime.__version__) >= parse_version('1.0.1'):
+            assert_array_equal(num2date(T[:], T.units, T.calendar), dates)
         assert_equal(date2index(datetime.datetime(1980, 1, 2), T), 366)
         f.close()
 


=====================================
test/tst_multifile2.py
=====================================
--- a/test/tst_multifile2.py
+++ b/test/tst_multifile2.py
@@ -4,6 +4,8 @@ from numpy.random import seed, randint
 from numpy.testing import assert_array_equal, assert_equal
 from numpy import ma
 import tempfile, unittest, os, datetime
+import cftime
+from pkg_resources import parse_version
 
 nx=100; ydim=5; zdim=10
 nfiles = 10
@@ -102,12 +104,15 @@ class NonuniformTimeTestCase(unittest.TestCase):
 
     def runTest(self):
         # Get the real dates
-        dates = []
-        for file in self.files:
-            f = Dataset(file)
-            t = f.variables['time']
-            dates.extend(num2date(t[:], t.units, t.calendar))
-            f.close()
+        # skip this until cftime pull request #55 is in a released
+        # version (1.0.1?). Otherwise, fix for issue #808 breaks this
+        if parse_version(cftime.__version__) >= parse_version('1.0.1'):
+            dates = []
+            for file in self.files:
+                f = Dataset(file)
+                t = f.variables['time']
+                dates.extend(num2date(t[:], t.units, t.calendar))
+                f.close()
 
         # Compare with the MF dates
         f = MFDataset(self.files,check=True)
@@ -119,7 +124,10 @@ class NonuniformTimeTestCase(unittest.TestCase):
         assert_equal(T.shape, t.shape)
         assert_equal(T.dimensions, t.dimensions)
         assert_equal(T.typecode(), t.typecode())
-        assert_array_equal(num2date(T[:], T.units, T.calendar), dates)
+        # skip this until cftime pull request #55 is in a released
+        # version (1.0.1?). Otherwise, fix for issue #808 breaks this
+        if parse_version(cftime.__version__) >= parse_version('1.0.1'):
+            assert_array_equal(num2date(T[:], T.units, T.calendar), dates)
         assert_equal(date2index(datetime.datetime(1980, 1, 2), T), 366)
         f.close()
 



View it on GitLab: https://salsa.debian.org/debian-gis-team/netcdf4-python/compare/423b7c5957a5f71e2be9a88d32c9b6e2a4c810a5...3218ad8ff404bef50ac8c253f833a185ae63e1da

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/netcdf4-python/compare/423b7c5957a5f71e2be9a88d32c9b6e2a4c810a5...3218ad8ff404bef50ac8c253f833a185ae63e1da
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20180815/a28ca4d8/attachment-0001.html>


More information about the Pkg-grass-devel mailing list