diff --git a/pandas/_libs/parsers.pyx b/pandas/_libs/parsers.pyx index 25028b06f7bad..4d87dcefa856d 100644 --- a/pandas/_libs/parsers.pyx +++ b/pandas/_libs/parsers.pyx @@ -1090,7 +1090,20 @@ cdef class TextReader: # we had a fallback parse on the dtype, so now try to cast # only allow safe casts, eg. with a nan you cannot safely cast to int + #floating casts are handled in this section if col_res is not None and col_dtype is not None: + if is_float_dtype(col_dtype) and col_res.dtype == np.bool_ : + mask = col_res.view(np.uint8) == na_values[np.uint8] + col_res = col_res.astype(col_dtype) + np.putmask(col_res, mask, np.nan) + return col_res, na_count + if is_integer_dtype(col_dtype) and col_res.dtype == np.bool_ : + if na_count > 0: + raise ValueError( + f"cannot safely convert passed user dtype of " + f"{col_dtype} for {np.bool_} dtyped data in " + f"column {i} as it is applicable only in the case of float values and not NA values") + pass try: col_res = col_res.astype(col_dtype, casting='safe') except TypeError: diff --git a/pandas/tests/io/parser/test_na_values.py b/pandas/tests/io/parser/test_na_values.py index 2880bf8690b46..b02ea5d9f4396 100644 --- a/pandas/tests/io/parser/test_na_values.py +++ b/pandas/tests/io/parser/test_na_values.py @@ -590,3 +590,22 @@ def test_nan_multi_index(all_parsers): ) tm.assert_frame_equal(result, expected) + +def test_bool_and_nan_to_int(all_parsers): + p = all_parsers + test_data_val = """0 NaN True False""" + with pytest.raises(ValueError, match = "convert"): + print(p.read_csv(StringIO(test_data_val), dtype = "int")) + +def test_bool_and_nan_to_float(all_parsers): + p = all_parsers + test_data_val = """0 NaN True False""" + result = p.read_csv(StringIO(test_data_val), dtype = "float") + expected = DataFrame.from_dict({"0": [np.nan, 1.0, 0.0]}) + tm.assert_frame_equal(result, expected) + +def test_bool_and_nan_to_bool(all_parsers): + p = all_parsers + test_data_val = """0 NaN True False """ + with pytest.raises(ValueError, match = "NA values"): + p.read_csv(StringIO(test_data_val), dtype = "bool")