Skip to content

Commit bec736f

Browse files
authored
TST/REF: de-duplicate SetitemCastingEquivalents (#39575)
1 parent f79468b commit bec736f

File tree

1 file changed

+46
-109
lines changed

1 file changed

+46
-109
lines changed

pandas/tests/series/indexing/test_setitem.py

+46-109
Original file line numberDiff line numberDiff line change
@@ -307,57 +307,71 @@ class SetitemCastingEquivalents:
307307
- the setitem does not expand the obj
308308
"""
309309

310-
@pytest.fixture(params=[np.nan, np.float64("NaN")])
311-
def val(self, request):
310+
@pytest.fixture
311+
def is_inplace(self):
312312
"""
313-
One python float NaN, one np.float64. Only np.float64 has a `dtype`
314-
attribute.
313+
Indicate that we are not (yet) checking whether or not setting is inplace.
315314
"""
316-
return request.param
315+
return None
317316

318-
def check_indexer(self, obj, key, expected, val, indexer):
317+
def check_indexer(self, obj, key, expected, val, indexer, is_inplace):
318+
orig = obj
319319
obj = obj.copy()
320+
arr = obj._values
321+
320322
indexer(obj)[key] = val
321323
tm.assert_series_equal(obj, expected)
322324

323-
def test_int_key(self, obj, key, expected, val, indexer_sli):
325+
self._check_inplace(is_inplace, orig, arr, obj)
326+
327+
def _check_inplace(self, is_inplace, orig, arr, obj):
328+
if is_inplace is None:
329+
# We are not (yet) checking whether setting is inplace or not
330+
pass
331+
elif is_inplace:
332+
assert obj._values is arr
333+
else:
334+
# otherwise original array should be unchanged
335+
tm.assert_equal(arr, orig._values)
336+
337+
def test_int_key(self, obj, key, expected, val, indexer_sli, is_inplace):
324338
if not isinstance(key, int):
325339
return
326340

327-
self.check_indexer(obj, key, expected, val, indexer_sli)
341+
self.check_indexer(obj, key, expected, val, indexer_sli, is_inplace)
328342

329343
if indexer_sli is tm.loc:
330-
self.check_indexer(obj, key, expected, val, tm.at)
344+
self.check_indexer(obj, key, expected, val, tm.at, is_inplace)
331345
elif indexer_sli is tm.iloc:
332-
self.check_indexer(obj, key, expected, val, tm.iat)
346+
self.check_indexer(obj, key, expected, val, tm.iat, is_inplace)
333347

334348
rng = range(key, key + 1)
335-
self.check_indexer(obj, rng, expected, val, indexer_sli)
349+
self.check_indexer(obj, rng, expected, val, indexer_sli, is_inplace)
336350

337351
if indexer_sli is not tm.loc:
338352
# Note: no .loc because that handles slice edges differently
339353
slc = slice(key, key + 1)
340-
self.check_indexer(obj, slc, expected, val, indexer_sli)
354+
self.check_indexer(obj, slc, expected, val, indexer_sli, is_inplace)
341355

342356
ilkey = [key]
343-
self.check_indexer(obj, ilkey, expected, val, indexer_sli)
357+
self.check_indexer(obj, ilkey, expected, val, indexer_sli, is_inplace)
344358

345359
indkey = np.array(ilkey)
346-
self.check_indexer(obj, indkey, expected, val, indexer_sli)
360+
self.check_indexer(obj, indkey, expected, val, indexer_sli, is_inplace)
347361

348-
def test_slice_key(self, obj, key, expected, val, indexer_sli):
362+
def test_slice_key(self, obj, key, expected, val, indexer_sli, is_inplace):
349363
if not isinstance(key, slice):
350364
return
351365

352366
if indexer_sli is not tm.loc:
353367
# Note: no .loc because that handles slice edges differently
354-
self.check_indexer(obj, key, expected, val, indexer_sli)
368+
self.check_indexer(obj, key, expected, val, indexer_sli, is_inplace)
355369

356370
ilkey = list(range(len(obj)))[key]
357-
self.check_indexer(obj, ilkey, expected, val, indexer_sli)
371+
self.check_indexer(obj, ilkey, expected, val, indexer_sli, is_inplace)
358372

359373
indkey = np.array(ilkey)
360-
self.check_indexer(obj, indkey, expected, val, indexer_sli)
374+
self.check_indexer(obj, indkey, expected, val, indexer_sli, is_inplace)
361375

362376
def test_mask_key(self, obj, key, expected, val, indexer_sli):
363377
# setitem with boolean mask
@@ -368,14 +382,19 @@ def test_mask_key(self, obj, key, expected, val, indexer_sli):
368382
indexer_sli(obj)[mask] = val
369383
tm.assert_series_equal(obj, expected)
370384

371-
def test_series_where(self, obj, key, expected, val):
385+
def test_series_where(self, obj, key, expected, val, is_inplace):
372386
mask = np.zeros(obj.shape, dtype=bool)
373387
mask[key] = True
374388

389+
orig = obj
375390
obj = obj.copy()
391+
arr = obj._values
392+
376393
res = obj.where(~mask, val)
377394
tm.assert_series_equal(res, expected)
378395

396+
self._check_inplace(is_inplace, orig, arr, obj)
397+
379398
def test_index_where(self, obj, key, expected, val, request):
380399
if Index(obj).dtype != obj.dtype:
381400
pytest.skip("test not applicable for this dtype")
@@ -519,15 +538,15 @@ def test_setitem_slice_into_readonly_backing_data():
519538
assert not array.any()
520539

521540

522-
class TestSetitemCastingEquivalentsTimedelta64IntoNumeric:
541+
class TestSetitemTimedelta64IntoNumeric(SetitemCastingEquivalents):
523542
# timedelta64 should not be treated as integers when setting into
524543
# numeric Series
525544

526545
@pytest.fixture
527546
def val(self):
528547
td = np.timedelta64(4, "ns")
529548
return td
530-
return np.full((1,), td)
549+
# TODO: could also try np.full((1,), td)
531550

532551
@pytest.fixture(params=[complex, int, float])
533552
def dtype(self, request):
@@ -551,91 +570,9 @@ def expected(self, dtype):
551570
def key(self):
552571
return 0
553572

554-
def check_indexer(self, obj, key, expected, val, indexer):
555-
orig = obj
556-
obj = obj.copy()
557-
arr = obj._values
558-
559-
indexer(obj)[key] = val
560-
tm.assert_series_equal(obj, expected)
561-
562-
tm.assert_equal(arr, orig._values) # original array is unchanged
563-
564-
def test_int_key(self, obj, key, expected, val, indexer_sli):
565-
if not isinstance(key, int):
566-
return
567-
568-
self.check_indexer(obj, key, expected, val, indexer_sli)
569-
570-
rng = range(key, key + 1)
571-
self.check_indexer(obj, rng, expected, val, indexer_sli)
572-
573-
if indexer_sli is not tm.loc:
574-
# Note: no .loc because that handles slice edges differently
575-
slc = slice(key, key + 1)
576-
self.check_indexer(obj, slc, expected, val, indexer_sli)
577-
578-
ilkey = [key]
579-
self.check_indexer(obj, ilkey, expected, val, indexer_sli)
580-
581-
indkey = np.array(ilkey)
582-
self.check_indexer(obj, indkey, expected, val, indexer_sli)
583-
584-
def test_slice_key(self, obj, key, expected, val, indexer_sli):
585-
if not isinstance(key, slice):
586-
return
587-
588-
if indexer_sli is not tm.loc:
589-
# Note: no .loc because that handles slice edges differently
590-
self.check_indexer(obj, key, expected, val, indexer_sli)
591-
592-
ilkey = list(range(len(obj)))[key]
593-
self.check_indexer(obj, ilkey, expected, val, indexer_sli)
594-
595-
indkey = np.array(ilkey)
596-
self.check_indexer(obj, indkey, expected, val, indexer_sli)
597-
598-
def test_mask_key(self, obj, key, expected, val, indexer_sli):
599-
# setitem with boolean mask
600-
mask = np.zeros(obj.shape, dtype=bool)
601-
mask[key] = True
602-
603-
self.check_indexer(obj, mask, expected, val, indexer_sli)
604-
605-
def test_series_where(self, obj, key, expected, val):
606-
mask = np.zeros(obj.shape, dtype=bool)
607-
mask[key] = True
608-
609-
orig = obj
610-
obj = obj.copy()
611-
arr = obj._values
612-
res = obj.where(~mask, val)
613-
tm.assert_series_equal(res, expected)
614-
615-
tm.assert_equal(arr, orig._values) # original array is unchanged
616-
617-
def test_index_where(self, obj, key, expected, val, request):
618-
if Index(obj).dtype != obj.dtype:
619-
pytest.skip("test not applicable for this dtype")
620-
621-
mask = np.zeros(obj.shape, dtype=bool)
622-
mask[key] = True
623-
624-
if obj.dtype == bool and not mask.all():
625-
# When mask is all True, casting behavior does not apply
626-
msg = "Index/Series casting behavior inconsistent GH#38692"
627-
mark = pytest.mark.xfail(reason=msg)
628-
request.node.add_marker(mark)
629-
630-
res = Index(obj).where(~mask, val)
631-
tm.assert_index_equal(res, Index(expected))
632-
633-
def test_index_putmask(self, obj, key, expected, val):
634-
if Index(obj).dtype != obj.dtype:
635-
pytest.skip("test not applicable for this dtype")
636-
637-
mask = np.zeros(obj.shape, dtype=bool)
638-
mask[key] = True
639-
640-
res = Index(obj).putmask(mask, val)
641-
tm.assert_index_equal(res, Index(expected))
573+
@pytest.fixture
574+
def is_inplace(self):
575+
"""
576+
Indicate we do _not_ expect the setting to be done inplace.
577+
"""
578+
return False

0 commit comments

Comments
 (0)