<commit_before>from collections import Iterable
import copy
from numbers import Real, Integral

import numpy as np

from openmc import Mesh
from openmc.constants import *
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
    events when the particle is in a certain cell and energy range.

    Parameters
    ----------
    type : str
        The type of the tally filter. Acceptable values are "universe",
        "material", "cell", "cellborn", "surface", "mesh", "energy",
        "energyout", and "distribcell".
    bins : int or Iterable of int or Iterable of float
        The bins for the filter. This takes on different meaning for different
        filters.

    Attributes
    ----------
    type : str
        The type of the tally filter.
    bins : int or Iterable of int or Iterable of float
        The bins for the filter

    """

    # Initialize Filter class attributes
    def __init__(self, type=None, bins=None):
        self.type = type
        self._num_bins = 0
        self.bins = bins
        self._mesh = None
        self._offset = -1
        self._stride = None

    def __eq__(self, filter2):
        # Check type
        if self.type != filter2.type:
            return False

        # Check number of bins
        elif len(self.bins) != len(filter2.bins):
            return False

        # Check bin edges
        elif not np.allclose(self.bins, filter2.bins):
            return False

        else:
            return True

    def __hash__(self):
        return hash((self._type, self._bins))

    def __deepcopy__(self, memo):
        existing = memo.get(id(self))

        # If this is the first time we have tried to copy this object, create a copy
        if existing is None:
            clone = type(self).__new__(type(self))
            clone._type = self.type
            clone._bins = copy.deepcopy(self.bins, memo)
            clone._num_bins = self.num_bins
            clone._mesh = copy.deepcopy(self.mesh, memo)
            clone._offset = self.offset
            clone._stride = self.stride

            memo[id(self)] = clone

            return clone

        # If this object has been copied before, return the first copy made
        else:
            return existing

    @property
    def type(self):
        return self._type

    @property
    def bins(self):
        return self._bins

    @property
    def num_bins(self):
        return self._num_bins

    @property
    def mesh(self):
        return self._mesh

    @property
    def offset(self):
        return self._offset

    @property
    def stride(self):
        return self._stride

    @type.setter
    def type(self, type):
        if type is None:
            self._type = type
        elif type not in FILTER_TYPES.values():
            msg = 'Unable to set Filter type to "{0}" since it is not one ' \
                  'of the supported types'.format(type)
            raise ValueError(msg)

        self._type = type

    @bins.setter
    def bins(self, bins):
        if bins is None:
            self.num_bins = 0
        elif self._type is None:
            msg = 'Unable to set bins for Filter to "{0}" since ' \
                  'the Filter type has not yet been set'.format(bins)
            raise ValueError(msg)

        # If the bin edge is a single value, it is a Cell, Material, etc. ID
        if not isinstance(bins, Iterable):
            bins = [bins]

        # If the bins are in a collection, convert it to a list
        else:
            bins = list(bins)

        if self.type in ['cell', 'cellborn', 'surface', 'material',
                          'universe', 'distribcell']:
            check_iterable_type('filter bins', bins, Integral)
            for edge in bins:
                check_greater_than('filter bin', edge, 0, equality=True)

        elif self._type in ['energy', 'energyout']:
            for edge in bins:
                if not isinstance(edge, Real):
                    msg = 'Unable to add bin edge "{0}" to a "{1}" Filter ' \
                          'since it is a non-integer or floating point ' \
                          'value'.format(edge, self.type)
                    raise ValueError(msg)
                elif edge < 0.:
                    msg = 'Unable to add bin edge "{0}" to a "{1}" Filter ' \
                          'since it is a negative value'.format(edge, self.type)
                    raise ValueError(msg)

            # Check that bin edges are monotonically increasing
            for index in range(len(bins)):
                if index > 0 and bins[index] < bins[index-1]:
                    msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \
                          'since they are not monotonically ' \
                          'increasing'.format(bins, self.type)
                    raise ValueError(msg)

        # mesh filters
        elif self._type == 'mesh':
            if not len(bins) == 1:
                msg = 'Unable to add bins "{0}" to a mesh Filter since ' \
                      'only a single mesh can be used per tally'.format(bins)
                raise ValueError(msg)
            elif not isinstance(bins[0], Integral):
                msg = 'Unable to add bin "{0}" to mesh Filter since it ' \
                       'is a non-integer'.format(bins[0])
                raise ValueError(msg)
            elif bins[0] < 0:
                msg = 'Unable to add bin "{0}" to mesh Filter since it ' \
                       'is a negative integer'.format(bins[0])
                raise ValueError(msg)

        # If all error checks passed, add bin edges
        self._bins = np.array(bins)

    # FIXME
    @num_bins.setter
    def num_bins(self, num_bins):
        check_type('filter num_bins', num_bins, Integral)
        check_greater_than('filter num_bins', num_bins, 0, equality=True)<commit_msg>Fix PyAPI filter for numpy isinstance bug<commit_after>from collections import Iterable
import copy
from numbers import Real, Integral

import numpy as np

from openmc import Mesh
from openmc.constants import *
from openmc.checkvalue import check_type, check_iterable_type, \
                              check_greater_than, _isinstance

class Filter(object):
    """A filter used to constrain a tally to a specific criterion, e.g. only tally
    events when the particle is in a certain cell and energy range.

    Parameters
    ----------
    type : str
        The type of the tally filter. Acceptable values are "universe",
        "material", "cell", "cellborn", "surface", "mesh", "energy",
        "energyout", and "distribcell".
    bins : int or Iterable of int or Iterable of float
        The bins for the filter. This takes on different meaning for different
        filters.

    Attributes
    ----------
    type : str
        The type of the tally filter.
    bins : int or Iterable of int or Iterable of float
        The bins for the filter

    """

    # Initialize Filter class attributes
    def __init__(self, type=None, bins=None):
        self.type = type
        self._num_bins = 0
        self.bins = bins
        self._mesh = None
        self._offset = -1
        self._stride = None

    def __eq__(self, filter2):
        # Check type
        if self.type != filter2.type:
            return False

        # Check number of bins
        elif len(self.bins) != len(filter2.bins):
            return False

        # Check bin edges
        elif not np.allclose(self.bins, filter2.bins):
            return False

        else:
            return True

    def __hash__(self):
        return hash((self._type, self._bins))

    def __deepcopy__(self, memo):
        existing = memo.get(id(self))

        # If this is the first time we have tried to copy this object, create a copy
        if existing is None:
            clone = type(self).__new__(type(self))
            clone._type = self.type
            clone._bins = copy.deepcopy(self.bins, memo)
            clone._num_bins = self.num_bins
            clone._mesh = copy.deepcopy(self.mesh, memo)
            clone._offset = self.offset
            clone._stride = self.stride

            memo[id(self)] = clone

            return clone

        # If this object has been copied before, return the first copy made
        else:
            return existing

    @property
    def type(self):
        return self._type

    @property
    def bins(self):
        return self._bins

    @property
    def num_bins(self):
        return self._num_bins

    @property
    def mesh(self):
        return self._mesh

    @property
    def offset(self):
        return self._offset

    @property
    def stride(self):
        return self._stride

    @type.setter
    def type(self, type):
        if type is None:
            self._type = type
        elif type not in FILTER_TYPES.values():
            msg = 'Unable to set Filter type to "{0}" since it is not one ' \
                  'of the supported types'.format(type)
            raise ValueError(msg)

        self._type = type

    @bins.setter
    def bins(self, bins):
        if bins is None:
            self.num_bins = 0
        elif self._type is None:
            msg = 'Unable to set bins for Filter to "{0}" since ' \
                  'the Filter type has not yet been set'.format(bins)
            raise ValueError(msg)

        # If the bin edge is a single value, it is a Cell, Material, etc. ID
        if not _isinstance(bins, Iterable):
            bins = [bins]

        # If the bins are in a collection, convert it to a list
        else:
            bins = list(bins)

        if self.type in ['cell', 'cellborn', 'surface', 'material',
                          'universe', 'distribcell']:
            check_iterable_type('filter bins', bins, Integral)
            for edge in bins:
                check_greater_than('filter bin', edge, 0, equality=True)

        elif self._type in ['energy', 'energyout']:
            for edge in bins:
                if not _isinstance(edge, Real):
                    msg = 'Unable to add bin edge "{0}" to a "{1}" Filter ' \
                          'since it is a non-integer or floating point ' \
                          'value'.format(edge, self.type)
                    raise ValueError(msg)
                elif edge < 0.:
                    msg = 'Unable to add bin edge "{0}" to a "{1}" Filter ' \
                          'since it is a negative value'.format(edge, self.type)
                    raise ValueError(msg)

            # Check that bin edges are monotonically increasing
            for index in range(len(bins)):
                if index > 0 and bins[index] < bins[index-1]:
                    msg = 'Unable to add bin edges "{0}" to a "{1}" Filter ' \
                          'since they are not monotonically ' \
                          'increasing'.format(bins, self.type)
                    raise ValueError(msg)

        # mesh filters
        elif self._type == 'mesh':
            if not len(bins) == 1:
                msg = 'Unable to add bins "{0}" to a mesh Filter since ' \
                      'only a single mesh can be used per tally'.format(bins)
                raise ValueError(msg)
            elif not _isinstance(bins[0], Integral):
                msg = 'Unable to add bin "{0}" to mesh Filter since it ' \
                       'is a non-integer'.format(bins[0])
                raise ValueError(msg)
            elif bins[0] < 0:
                msg = 'Unable to add bin "{0}" to mesh Filter since it ' \
                       'is a negative integer'.format(bins[0])
                raise ValueError(msg)

        # If all error checks passed, add bin edges
        self._bins = np.array(bins)

    # FIXME
    @num_bins.setter
    def num_bins(self, num_bins):
        check_type('filter num_bins', num_bins, Integral)
        check_greater_than('filter num_bins', num_bins, 0, equality=True)
{'fraction_non_alphanumeric': 0.08850803113098195, 'fraction_numerical': 0.004802119556217917, 'mean_word_length': 1.6547252747252748, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '459209', 'n_tokens_mistral': 3378, 'n_tokens_neox': 3128, 'n_words': 1186}