test_indexing.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import re
  2. import numpy as np
  3. import pytest
  4. import pandas as pd
  5. class TestSetitemValidation:
  6. def _check_setitem_invalid(self, arr, invalid):
  7. msg = f"Invalid value '{str(invalid)}' for dtype {arr.dtype}"
  8. msg = re.escape(msg)
  9. with pytest.raises(TypeError, match=msg):
  10. arr[0] = invalid
  11. with pytest.raises(TypeError, match=msg):
  12. arr[:] = invalid
  13. with pytest.raises(TypeError, match=msg):
  14. arr[[0]] = invalid
  15. # FIXME: don't leave commented-out
  16. # with pytest.raises(TypeError):
  17. # arr[[0]] = [invalid]
  18. # with pytest.raises(TypeError):
  19. # arr[[0]] = np.array([invalid], dtype=object)
  20. # Series non-coercion, behavior subject to change
  21. ser = pd.Series(arr)
  22. with pytest.raises(TypeError, match=msg):
  23. ser[0] = invalid
  24. # TODO: so, so many other variants of this...
  25. _invalid_scalars = [
  26. 1 + 2j,
  27. "True",
  28. "1",
  29. "1.0",
  30. pd.NaT,
  31. np.datetime64("NaT"),
  32. np.timedelta64("NaT"),
  33. ]
  34. @pytest.mark.parametrize(
  35. "invalid", _invalid_scalars + [1, 1.0, np.int64(1), np.float64(1)]
  36. )
  37. def test_setitem_validation_scalar_bool(self, invalid):
  38. arr = pd.array([True, False, None], dtype="boolean")
  39. self._check_setitem_invalid(arr, invalid)
  40. @pytest.mark.parametrize("invalid", _invalid_scalars + [True, 1.5, np.float64(1.5)])
  41. def test_setitem_validation_scalar_int(self, invalid, any_int_ea_dtype):
  42. arr = pd.array([1, 2, None], dtype=any_int_ea_dtype)
  43. self._check_setitem_invalid(arr, invalid)
  44. @pytest.mark.parametrize("invalid", _invalid_scalars + [True])
  45. def test_setitem_validation_scalar_float(self, invalid, float_ea_dtype):
  46. arr = pd.array([1, 2, None], dtype=float_ea_dtype)
  47. self._check_setitem_invalid(arr, invalid)