From 762a2346a9d7cfc9e9a51f3f0b113eff759a117e Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 10:27:15 -0700 Subject: [PATCH 1/6] troubleshoot CI --- pandas/tests/series/indexing/test_indexing.py | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 3083b655821f8..33f4aadecdbae 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -690,13 +690,7 @@ def test_dt64_series_assign_nat(nat_val, should_cast, tz): "nat_val,should_cast", [ (pd.NaT, True), - pytest.param( - np.timedelta64("NaT", "ns"), - True, - marks=pytest.mark.xfail( - reason="Platform-specific failures, unknown cause", strict=False - ), - ), + (np.timedelta64("NaT", "ns"), True), (np.datetime64("NaT", "ns"), False), ], ) @@ -709,6 +703,33 @@ def test_td64_series_assign_nat(nat_val, should_cast): if not should_cast: expected = expected.astype(object) + if should_cast: + # Debugging CI failures + + # Walk through the engine.set_value call that _should_ work + ser = base.copy(deep=True) + values = ser._values + engine = ser.index._engine + assert type(engine).__name__ == "Int64Engine" + loc = engine.get_loc(0) + assert loc == 0 + value = pd._libs.index.convert_scalar(values, nat_val) + assert value == pd._libs.iNaT + values[loc] = value + tm.assert_series_equal(ser, expected) + + # the _set_with_engine call should successfully go + # through index._engine.set_value + ser = base.copy(deep=True) + values = ser._values + ser.index._engine.set_value(values, 0, nat_val) + tm.assert_series_equal(ser, expected) + + # the __setitem__ call should successfully go through _set_with_engine + ser = base.copy(deep=True) + ser._set_with_engine(0, nat_val) + tm.assert_series_equal(ser, expected) + ser = base.copy(deep=True) ser[0] = nat_val tm.assert_series_equal(ser, expected) From 33383bba3c4a95c28b604f5a7f253decd27bda30 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 12:24:15 -0700 Subject: [PATCH 2/6] get more info in traceback --- pandas/_libs/index.pyx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 13812663dd907..6c53706ee981f 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -555,7 +555,11 @@ cpdef convert_scalar(ndarray arr, object value): return NPY_NAT elif isinstance(value, str): return Timedelta(value).value - raise ValueError("cannot set a Timedelta with a non-timedelta") + raise ValueError("cannot set a Timedelta with a non-timedelta {typ}; " + "is_array={check1}, is_dt64={check2}" + .format(typ=type(value).__name__), + check1=util.is_array(value), + check2=util.is_datetime64_object(value)) if (issubclass(arr.dtype.type, (np.integer, np.floating, np.complex)) and not issubclass(arr.dtype.type, np.bool_)): From 1b62652f6fe6818272f2de18e375d5a9a0aeb41a Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 12:51:12 -0700 Subject: [PATCH 3/6] typo fixup --- pandas/_libs/index.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 6c53706ee981f..adf1eddeb2614 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -557,9 +557,9 @@ cpdef convert_scalar(ndarray arr, object value): return Timedelta(value).value raise ValueError("cannot set a Timedelta with a non-timedelta {typ}; " "is_array={check1}, is_dt64={check2}" - .format(typ=type(value).__name__), + .format(typ=type(value).__name__, check1=util.is_array(value), - check2=util.is_datetime64_object(value)) + check2=util.is_datetime64_object(value))) if (issubclass(arr.dtype.type, (np.integer, np.floating, np.complex)) and not issubclass(arr.dtype.type, np.bool_)): From a0bd95f93d6fec85ff730a48d6f44ecbb324657d Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 13:47:08 -0700 Subject: [PATCH 4/6] troubleshoot more --- pandas/_libs/index.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index adf1eddeb2614..609e478d72b70 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -551,6 +551,8 @@ cpdef convert_scalar(ndarray arr, object value): # exclude np.datetime64("NaT") which would otherwise be picked up # by the `value != value check below pass + elif util.is_timedelta64_object(value): + return value elif value is None or value != value: return NPY_NAT elif isinstance(value, str): From b7513ed6955d3b9d1e3168ef66355083ab94a68a Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 13:47:49 -0700 Subject: [PATCH 5/6] earlier --- pandas/_libs/index.pyx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 609e478d72b70..505230659552b 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -545,14 +545,12 @@ cpdef convert_scalar(ndarray arr, object value): elif arr.descr.type_num == NPY_TIMEDELTA: if util.is_array(value): pass - elif isinstance(value, timedelta): + elif isinstance(value, timedelta) or util.is_timedelta64_object(value): return Timedelta(value).value elif util.is_datetime64_object(value): # exclude np.datetime64("NaT") which would otherwise be picked up # by the `value != value check below pass - elif util.is_timedelta64_object(value): - return value elif value is None or value != value: return NPY_NAT elif isinstance(value, str): From cacacf3b8aa184a95420f1336c46585ce58f8bcb Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 23 Jul 2019 14:42:27 -0700 Subject: [PATCH 6/6] remove debug code --- pandas/_libs/index.pyx | 6 +---- pandas/tests/series/indexing/test_indexing.py | 27 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 505230659552b..f704ceffa662e 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -555,11 +555,7 @@ cpdef convert_scalar(ndarray arr, object value): return NPY_NAT elif isinstance(value, str): return Timedelta(value).value - raise ValueError("cannot set a Timedelta with a non-timedelta {typ}; " - "is_array={check1}, is_dt64={check2}" - .format(typ=type(value).__name__, - check1=util.is_array(value), - check2=util.is_datetime64_object(value))) + raise ValueError("cannot set a Timedelta with a non-timedelta") if (issubclass(arr.dtype.type, (np.integer, np.floating, np.complex)) and not issubclass(arr.dtype.type, np.bool_)): diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 33f4aadecdbae..2d36bfdb93a17 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -703,33 +703,6 @@ def test_td64_series_assign_nat(nat_val, should_cast): if not should_cast: expected = expected.astype(object) - if should_cast: - # Debugging CI failures - - # Walk through the engine.set_value call that _should_ work - ser = base.copy(deep=True) - values = ser._values - engine = ser.index._engine - assert type(engine).__name__ == "Int64Engine" - loc = engine.get_loc(0) - assert loc == 0 - value = pd._libs.index.convert_scalar(values, nat_val) - assert value == pd._libs.iNaT - values[loc] = value - tm.assert_series_equal(ser, expected) - - # the _set_with_engine call should successfully go - # through index._engine.set_value - ser = base.copy(deep=True) - values = ser._values - ser.index._engine.set_value(values, 0, nat_val) - tm.assert_series_equal(ser, expected) - - # the __setitem__ call should successfully go through _set_with_engine - ser = base.copy(deep=True) - ser._set_with_engine(0, nat_val) - tm.assert_series_equal(ser, expected) - ser = base.copy(deep=True) ser[0] = nat_val tm.assert_series_equal(ser, expected)