diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index f9e05e3f8..5b5f302e5 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -1,4 +1,16 @@ from collections import Iterable +from numbers import Integral + +import numpy as np + +def _isinstance(value, expected_type): + """A Numpy-aware replacement for isinstance""" + np_ints = [np.intc, np.intp, np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64] + if expected_type is Integral: + types = np_ints + [Integral] + return any(isinstance(value, t) for t in types) + return isinstance(value, expected_type) def check_type(name, value, expected_type, expected_iter_type=None): """Ensure that an object is of an expected type. Optionally, if the object is @@ -18,14 +30,14 @@ def check_type(name, value, expected_type, expected_iter_type=None): """ - if not isinstance(value, expected_type): + if not _isinstance(value, expected_type): msg = 'Unable to set {0} to {1} which is not of type {2}'.format( name, value, expected_type.__name__) raise ValueError(msg) if expected_iter_type: for item in value: - if not isinstance(item, expected_iter_type): + if not _isinstance(item, expected_iter_type): msg = 'Unable to set {0} to {1} since each item must be ' \ 'of type {2}'.format(name, value, expected_iter_type.__name__) @@ -74,7 +86,7 @@ def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): # If this item is of the expected type, then we've reached the bottom # level of this branch. - if isinstance(current_item, expected_type): + if _isinstance(current_item, expected_type): # Is this deep enough? if len(tree) < min_depth: msg = 'Error setting {0}: The item at {1} does not meet the ' \ diff --git a/openmc/filter.py b/openmc/filter.py index 09928e235..ca5d430a9 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -6,7 +6,8 @@ import numpy as np from openmc import Mesh from openmc.constants import * -from openmc.checkvalue import check_type +from openmc.checkvalue import check_type, check_iterable_type, \ + check_greater_than class Filter(object): """A filter used to constrain a tally to a specific criterion, e.g. only tally @@ -134,15 +135,9 @@ class Filter(object): if self._type in ['cell', 'cellborn', 'surface', 'material', 'universe', 'distribcell']: + check_iterable_type('filter bins', bins, Integral) for edge in bins: - if not isinstance(edge, Integral): - msg = 'Unable to add bin "{0}" to a {1} Filter since ' \ - 'it is not an integer'.format(edge, self._type) - raise ValueError(msg) - elif edge < 0: - msg = 'Unable to add bin "{0}" to a {1} Filter since ' \ - 'it is negative'.format(edge, self._type) - raise ValueError(msg) + check_greater_than('filter bin', edge, 0, equality=True) elif self._type in ['energy', 'energyout']: for edge in bins: @@ -185,12 +180,8 @@ class Filter(object): # FIXME @num_bins.setter def num_bins(self, num_bins): - if not isinstance(num_bins, Integral) or num_bins < 0: - msg = 'Unable to set the number of bins "{0}" for a {1} Filter ' \ - 'since it is not a positive ' \ - 'integer'.format(num_bins, self._type) - raise ValueError(msg) - + check_type('filter num_bins', num_bins, Integral) + check_greater_than('filter num_bins', num_bins, 0, equality=True) self._num_bins = num_bins @mesh.setter