# Buggy code
def _ensure_data(values, dtype=None):
    """
    routine to ensure that our data is of the correct
    input dtype for lower-level routines

    This will coerce:
    - ints -> int64
    - uint -> uint64
    - bool -> uint64 (TODO this should be uint8)
    - datetimelike -> i8
    - datetime64tz -> i8 (in local tz)
    - categorical -> codes

    Parameters
    ----------
    values : array-like
    dtype : pandas_dtype, optional
        coerce to this dtype

    Returns
    -------
    (ndarray, pandas_dtype, algo dtype as a string)

    """

    # we check some simple dtypes first
    try:
        if is_object_dtype(dtype):
            return ensure_object(np.asarray(values)), "object", "object"
        if is_bool_dtype(values) or is_bool_dtype(dtype):
            # we are actually coercing to uint64
            # until our algos support uint8 directly (see TODO)
            return np.asarray(values).astype("uint64"), "bool", "uint64"
        elif is_signed_integer_dtype(values) or is_signed_integer_dtype(dtype):
            return ensure_int64(values), "int64", "int64"
        elif is_unsigned_integer_dtype(values) or is_unsigned_integer_dtype(dtype):
            return ensure_uint64(values), "uint64", "uint64"
        elif is_float_dtype(values) or is_float_dtype(dtype):
            return ensure_float64(values), "float64", "float64"
        elif is_object_dtype(values) and dtype is None:
            return ensure_object(np.asarray(values)), "object", "object"
        elif is_complex_dtype(values) or is_complex_dtype(dtype):
            # ignore the fact that we are casting to float
            # which discards complex parts
            with catch_warnings(record=True):
                values = ensure_float64(values)
            return values, "float64", "float64"

    except (TypeError, ValueError):
        # if we are trying to coerce to a dtype
        # and it is incompat this will fall thru to here
        return ensure_object(values), "object", "object"

    # datetimelike
    if (
        needs_i8_conversion(values)
        or is_period_dtype(dtype)
        or is_datetime64_any_dtype(dtype)
        or is_timedelta64_dtype(dtype)
    ):
        if is_period_dtype(values) or is_period_dtype(dtype):
            from pandas import PeriodIndex

            values = PeriodIndex(values)
            dtype = values.dtype
        elif is_timedelta64_dtype(values) or is_timedelta64_dtype(dtype):
            from pandas import TimedeltaIndex

            values = TimedeltaIndex(values)
            dtype = values.dtype
        else:
            # Datetime
            from pandas import DatetimeIndex

            values = DatetimeIndex(values)
            dtype = values.dtype

        return values.asi8, dtype, "int64"

    elif is_categorical_dtype(values) and (
        is_categorical_dtype(dtype) or dtype is None
    ):
        values = getattr(values, "values", values)
        values = values.codes
        dtype = "category"

        # we are actually coercing to int64
        # until our algos support int* directly (not all do)
        values = ensure_int64(values)

        return values, dtype, "int64"

    # we have failed, return object
    values = np.asarray(values)
    return ensure_object(values), "object", "object"


# Traceback (OverflowError)
Traceback (most recent call last):
File "run.py", line 9, in <module>
df = pd.read_csv(data, na_values=na_values, index_col=index_col)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 660, in parser_f
return _read(filepath_or_buffer, kwds)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 416, in _read
data = parser.read(nrows)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 1010, in read
ret = self._engine.read(nrows)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 1837, in read
index, names = self._make_index(data, alldata, names)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 1347, in _make_index
index = self._agg_index(index)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 1440, in _agg_index
arr, _ = self._infer_types(arr, col_na_values | col_na_fvalues)
File "/home/liauys/Code/pandas/pandas/io/parsers.py", line 1524, in _infer_types
mask = algorithms.isin(values, list(na_values))
File "/home/liauys/Code/pandas/pandas/core/algorithms.py", line 408, in isin
values, _, _ = _ensure_data(values, dtype=dtype)
File "/home/liauys/Code/pandas/pandas/core/algorithms.py", line 74, in _ensure_data
return _ensure_int64(values), 'int64', 'int64'
File "pandas/_libs/algos_common_helper.pxi", line 3227, in pandas._libs.algos.ensure_int64
File "pandas/_libs/algos_common_helper.pxi", line 3232, in pandas._libs.algos.ensure_int64
OverflowError: cannot convert float infinity to integer

# Fixed code
def _ensure_data(values, dtype=None):
    """
    routine to ensure that our data is of the correct
    input dtype for lower-level routines

    This will coerce:
    - ints -> int64
    - uint -> uint64
    - bool -> uint64 (TODO this should be uint8)
    - datetimelike -> i8
    - datetime64tz -> i8 (in local tz)
    - categorical -> codes

    Parameters
    ----------
    values : array-like
    dtype : pandas_dtype, optional
        coerce to this dtype

    Returns
    -------
    (ndarray, pandas_dtype, algo dtype as a string)

    """

    # we check some simple dtypes first
    try:
        if is_object_dtype(dtype):
            return ensure_object(np.asarray(values)), "object", "object"
        if is_bool_dtype(values) or is_bool_dtype(dtype):
            # we are actually coercing to uint64
            # until our algos support uint8 directly (see TODO)
            return np.asarray(values).astype("uint64"), "bool", "uint64"
        elif is_signed_integer_dtype(values) or is_signed_integer_dtype(dtype):
            return ensure_int64(values), "int64", "int64"
        elif is_unsigned_integer_dtype(values) or is_unsigned_integer_dtype(dtype):
            return ensure_uint64(values), "uint64", "uint64"
        elif is_float_dtype(values) or is_float_dtype(dtype):
            return ensure_float64(values), "float64", "float64"
        elif is_object_dtype(values) and dtype is None:
            return ensure_object(np.asarray(values)), "object", "object"
        elif is_complex_dtype(values) or is_complex_dtype(dtype):
            # ignore the fact that we are casting to float
            # which discards complex parts
            with catch_warnings(record=True):
                values = ensure_float64(values)
            return values, "float64", "float64"

    except (TypeError, ValueError, OverflowError):
        # if we are trying to coerce to a dtype
        # and it is incompat this will fall thru to here
        return ensure_object(values), "object", "object"

    # datetimelike
    if (
        needs_i8_conversion(values)
        or is_period_dtype(dtype)
        or is_datetime64_any_dtype(dtype)
        or is_timedelta64_dtype(dtype)
    ):
        if is_period_dtype(values) or is_period_dtype(dtype):
            from pandas import PeriodIndex

            values = PeriodIndex(values)
            dtype = values.dtype
        elif is_timedelta64_dtype(values) or is_timedelta64_dtype(dtype):
            from pandas import TimedeltaIndex

            values = TimedeltaIndex(values)
            dtype = values.dtype
        else:
            # Datetime
            from pandas import DatetimeIndex

            values = DatetimeIndex(values)
            dtype = values.dtype

        return values.asi8, dtype, "int64"

    elif is_categorical_dtype(values) and (
        is_categorical_dtype(dtype) or dtype is None
    ):
        values = getattr(values, "values", values)
        values = values.codes
        dtype = "category"

        # we are actually coercing to int64
        # until our algos support int* directly (not all do)
        values = ensure_int64(values)

        return values, dtype, "int64"

    # we have failed, return object
    values = np.asarray(values)
    return ensure_object(values), "object", "object"