Skip to content

Commit

Permalink
py3k: Handle strings from netCDF consistently.
Browse files Browse the repository at this point in the history
  • Loading branch information
QuLogic committed Sep 16, 2015
1 parent 6682bce commit a02e863
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions lib/iris/fileformats/cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@
ocean_s_coordinate_g2=['eta', 'depth'])


# NetCDF returns a different type for strings depending on Python version.
def _is_str_dtype(var):
return ((six.PY2 and np.issubdtype(var.dtype, np.str)) or
(six.PY3 and np.issubdtype(var.dtype, np.bytes_)))


################################################################################
class CFVariable(six.with_metaclass(ABCMeta, object)):
"""Abstract base class wrapper for a CF-netCDF variable."""
Expand Down Expand Up @@ -313,7 +319,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
warnings.warn(message % (name, nc_var_name))
else:
# Restrict to non-string type i.e. not a CFLabelVariable.
if not np.issubdtype(variables[name].dtype, np.str):
if not _is_str_dtype(variables[name]):
result[name] = CFAuxiliaryCoordinateVariable(name, variables[name])

return result
Expand Down Expand Up @@ -478,7 +484,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True, monotonic=Fals
if nc_var_name in ignore:
continue
# String variables can't be coordinates
if np.issubdtype(nc_var.dtype, np.str):
if _is_str_dtype(nc_var):
continue
# Restrict to one-dimensional with name as dimension OR zero-dimensional scalar
if not ((nc_var.ndim == 1 and nc_var_name in nc_var.dimensions) or (nc_var.ndim == 0)):
Expand Down Expand Up @@ -638,8 +644,9 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
warnings.warn(message % (name, nc_var_name))
else:
# Restrict to only string type.
if np.issubdtype(variables[name].dtype, np.str):
result[name] = CFLabelVariable(name, variables[name])
if _is_str_dtype(variables[name]):
var = variables[name]
result[name] = CFLabelVariable(name, var)

return result

Expand Down Expand Up @@ -683,7 +690,7 @@ def cf_label_data(self, cf_data_var):

# Calculate new label data shape (without string dimension) and create payload array.
new_shape = tuple(dim_len for i, dim_len in enumerate(self.shape) if i != str_dim)
data = np.empty(new_shape, dtype='|S%d' % self.shape[str_dim])
data = np.empty(new_shape, dtype='|U%d' % self.shape[str_dim])

for index in np.ndindex(new_shape):
# Create the slice for the label data.
Expand All @@ -692,7 +699,8 @@ def cf_label_data(self, cf_data_var):
else:
label_index = index + (slice(None, None),)

data[index] = ''.join(label_data[label_index]).strip()
data[index] = b''.join(label_data[label_index]).strip().decode(
'utf8')

return data

Expand Down

0 comments on commit a02e863

Please sign in to comment.