Skip to content

Commit 8507170

Browse files
jbrockmendelTomAugspurger
authored andcommitted
CLN: separate raising from non-raising parts of method (pandas-dev#27151)
* separate coerce_values from coerce_args
1 parent a99c463 commit 8507170

File tree

2 files changed

+63
-50
lines changed

2 files changed

+63
-50
lines changed

pandas/core/internals/blocks.py

+61-48
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,15 @@ def array_dtype(self):
208208
"""
209209
return self.dtype
210210

211-
def make_block(self, values, placement=None, ndim=None):
211+
def make_block(self, values, placement=None):
212212
"""
213213
Create a new block, with type inference propagate any values that are
214214
not specified
215215
"""
216216
if placement is None:
217217
placement = self.mgr_locs
218-
if ndim is None:
219-
ndim = self.ndim
220218

221-
return make_block(values, placement=placement, ndim=ndim)
219+
return make_block(values, placement=placement, ndim=self.ndim)
222220

223221
def make_block_same_class(self, values, placement=None, ndim=None,
224222
dtype=None):
@@ -369,7 +367,9 @@ def fillna(self, value, limit=None, inplace=False, downcast=None):
369367

370368
# fillna, but if we cannot coerce, then try again as an ObjectBlock
371369
try:
372-
values, _ = self._try_coerce_args(self.values, value)
370+
# Note: we only call try_coerce_args to let it raise
371+
self._try_coerce_args(value)
372+
373373
blocks = self.putmask(mask, value, inplace=inplace)
374374
blocks = [b.make_block(values=self._try_coerce_result(b.values))
375375
for b in blocks]
@@ -659,7 +659,21 @@ def _try_cast_result(self, result, dtype=None):
659659
# may need to change the dtype here
660660
return maybe_downcast_to_dtype(result, dtype)
661661

662-
def _try_coerce_args(self, values, other):
662+
def _coerce_values(self, values):
663+
"""
664+
Coerce values (usually derived from self.values) for an operation.
665+
666+
Parameters
667+
----------
668+
values : ndarray or ExtensionArray
669+
670+
Returns
671+
-------
672+
ndarray or ExtensionArray
673+
"""
674+
return values
675+
676+
def _try_coerce_args(self, other):
663677
""" provide coercion to our input arguments """
664678

665679
if np.any(notna(other)) and not self._can_hold_element(other):
@@ -669,7 +683,7 @@ def _try_coerce_args(self, values, other):
669683
type(other).__name__,
670684
type(self).__name__.lower().replace('Block', '')))
671685

672-
return values, other
686+
return other
673687

674688
def _try_coerce_result(self, result):
675689
""" reverse of try_coerce_args """
@@ -718,9 +732,9 @@ def replace(self, to_replace, value, inplace=False, filter=None,
718732

719733
# try to replace, if we raise an error, convert to ObjectBlock and
720734
# retry
735+
values = self._coerce_values(self.values)
721736
try:
722-
values, to_replace = self._try_coerce_args(self.values,
723-
to_replace)
737+
to_replace = self._try_coerce_args(to_replace)
724738
except (TypeError, ValueError):
725739
# GH 22083, TypeError or ValueError occurred within error handling
726740
# causes infinite loop. Cast and retry only if not objectblock.
@@ -793,7 +807,8 @@ def setitem(self, indexer, value):
793807
# coerce if block dtype can store value
794808
values = self.values
795809
try:
796-
values, value = self._try_coerce_args(values, value)
810+
value = self._try_coerce_args(value)
811+
values = self._coerce_values(values)
797812
# can keep its own dtype
798813
if hasattr(value, 'dtype') and is_dtype_equal(values.dtype,
799814
value.dtype):
@@ -925,7 +940,7 @@ def putmask(self, mask, new, align=True, inplace=False, axis=0,
925940
new = self.fill_value
926941

927942
if self._can_hold_element(new):
928-
_, new = self._try_coerce_args(new_values, new)
943+
new = self._try_coerce_args(new)
929944

930945
if transpose:
931946
new_values = new_values.T
@@ -1127,7 +1142,8 @@ def _interpolate_with_fill(self, method='pad', axis=0, inplace=False,
11271142
return [self.copy()]
11281143

11291144
values = self.values if inplace else self.values.copy()
1130-
values, fill_value = self._try_coerce_args(values, fill_value)
1145+
values = self._coerce_values(values)
1146+
fill_value = self._try_coerce_args(fill_value)
11311147
values = missing.interpolate_2d(values, method=method, axis=axis,
11321148
limit=limit, fill_value=fill_value,
11331149
dtype=self.dtype)
@@ -1298,11 +1314,12 @@ def func(cond, values, other):
12981314
if cond.ravel().all():
12991315
return values
13001316

1301-
values, other = self._try_coerce_args(values, other)
1317+
values = self._coerce_values(values)
1318+
other = self._try_coerce_args(other)
13021319

13031320
try:
1304-
return self._try_coerce_result(expressions.where(
1305-
cond, values, other))
1321+
fastres = expressions.where(cond, values, other)
1322+
return self._try_coerce_result(fastres)
13061323
except Exception as detail:
13071324
if errors == 'raise':
13081325
raise TypeError(
@@ -1349,10 +1366,10 @@ def func(cond, values, other):
13491366
result_blocks = []
13501367
for m in [mask, ~mask]:
13511368
if m.any():
1352-
r = self._try_cast_result(result.take(m.nonzero()[0],
1353-
axis=axis))
1354-
result_blocks.append(
1355-
self.make_block(r.T, placement=self.mgr_locs[m]))
1369+
taken = result.take(m.nonzero()[0], axis=axis)
1370+
r = self._try_cast_result(taken)
1371+
nb = self.make_block(r.T, placement=self.mgr_locs[m])
1372+
result_blocks.append(nb)
13561373

13571374
return result_blocks
13581375

@@ -1423,7 +1440,7 @@ def quantile(self, qs, interpolation='linear', axis=0):
14231440
values = values[None, :]
14241441
else:
14251442
values = self.get_values()
1426-
values, _ = self._try_coerce_args(values, values)
1443+
values = self._coerce_values(values)
14271444

14281445
is_empty = values.shape[axis] == 0
14291446
orig_scalar = not is_list_like(qs)
@@ -1579,7 +1596,8 @@ def putmask(self, mask, new, align=True, inplace=False, axis=0,
15791596
# use block's copy logic.
15801597
# .values may be an Index which does shallow copy by default
15811598
new_values = self.values if inplace else self.copy().values
1582-
new_values, new = self._try_coerce_args(new_values, new)
1599+
new_values = self._coerce_values(new_values)
1600+
new = self._try_coerce_args(new)
15831601

15841602
if isinstance(new, np.ndarray) and len(new) == len(mask):
15851603
new = new[mask]
@@ -2120,25 +2138,25 @@ def _can_hold_element(self, element):
21202138
return (is_integer(element) or isinstance(element, datetime) or
21212139
isna(element))
21222140

2123-
def _try_coerce_args(self, values, other):
2141+
def _coerce_values(self, values):
2142+
return values.view('i8')
2143+
2144+
def _try_coerce_args(self, other):
21242145
"""
2125-
Coerce values and other to dtype 'i8'. NaN and NaT convert to
2146+
Coerce other to dtype 'i8'. NaN and NaT convert to
21262147
the smallest i8, and will correctly round-trip to NaT if converted
21272148
back in _try_coerce_result. values is always ndarray-like, other
21282149
may not be
21292150
21302151
Parameters
21312152
----------
2132-
values : ndarray-like
21332153
other : ndarray-like or scalar
21342154
21352155
Returns
21362156
-------
2137-
base-type values, base-type other
2157+
base-type other
21382158
"""
21392159

2140-
values = values.view('i8')
2141-
21422160
if isinstance(other, bool):
21432161
raise TypeError
21442162
elif is_null_datetimelike(other):
@@ -2156,7 +2174,7 @@ def _try_coerce_args(self, values, other):
21562174
# let higher levels handle
21572175
raise TypeError(other)
21582176

2159-
return values, other
2177+
return other
21602178

21612179
def _try_coerce_result(self, result):
21622180
""" reverse of try_coerce_args """
@@ -2249,13 +2267,6 @@ def is_view(self):
22492267
# check the ndarray values of the DatetimeIndex values
22502268
return self.values._data.base is not None
22512269

2252-
def copy(self, deep=True):
2253-
""" copy constructor """
2254-
values = self.values
2255-
if deep:
2256-
values = values.copy()
2257-
return self.make_block_same_class(values)
2258-
22592270
def get_values(self, dtype=None):
22602271
"""
22612272
Returns an ndarray of values.
@@ -2305,21 +2316,22 @@ def _slice(self, slicer):
23052316
return self.values[loc]
23062317
return self.values[slicer]
23072318

2308-
def _try_coerce_args(self, values, other):
2319+
def _coerce_values(self, values):
2320+
# asi8 is a view, needs copy
2321+
return _block_shape(values.view("i8"), ndim=self.ndim)
2322+
2323+
def _try_coerce_args(self, other):
23092324
"""
23102325
localize and return i8 for the values
23112326
23122327
Parameters
23132328
----------
2314-
values : ndarray-like
23152329
other : ndarray-like or scalar
23162330
23172331
Returns
23182332
-------
2319-
base-type values, base-type other
2333+
base-type other
23202334
"""
2321-
# asi8 is a view, needs copy
2322-
values = _block_shape(values.view("i8"), ndim=self.ndim)
23232335

23242336
if isinstance(other, ABCSeries):
23252337
other = self._holder(other)
@@ -2347,7 +2359,7 @@ def _try_coerce_args(self, values, other):
23472359
else:
23482360
raise TypeError(other)
23492361

2350-
return values, other
2362+
return other
23512363

23522364
def _try_coerce_result(self, result):
23532365
""" reverse of try_coerce_args """
@@ -2488,21 +2500,22 @@ def fillna(self, value, **kwargs):
24882500
value = Timedelta(value, unit='s')
24892501
return super().fillna(value, **kwargs)
24902502

2491-
def _try_coerce_args(self, values, other):
2503+
def _coerce_values(self, values):
2504+
return values.view('i8')
2505+
2506+
def _try_coerce_args(self, other):
24922507
"""
24932508
Coerce values and other to int64, with null values converted to
24942509
iNaT. values is always ndarray-like, other may not be
24952510
24962511
Parameters
24972512
----------
2498-
values : ndarray-like
24992513
other : ndarray-like or scalar
25002514
25012515
Returns
25022516
-------
2503-
base-type values, base-type other
2517+
base-type other
25042518
"""
2505-
values = values.view('i8')
25062519

25072520
if isinstance(other, bool):
25082521
raise TypeError
@@ -2517,7 +2530,7 @@ def _try_coerce_args(self, values, other):
25172530
# let higher levels handle
25182531
raise TypeError(other)
25192532

2520-
return values, other
2533+
return other
25212534

25222535
def _try_coerce_result(self, result):
25232536
""" reverse of try_coerce_args / try_operate """
@@ -2688,7 +2701,7 @@ def _maybe_downcast(self, blocks, downcast=None):
26882701
def _can_hold_element(self, element):
26892702
return True
26902703

2691-
def _try_coerce_args(self, values, other):
2704+
def _try_coerce_args(self, other):
26922705
""" provide coercion to our input arguments """
26932706

26942707
if isinstance(other, ABCDatetimeIndex):
@@ -2701,7 +2714,7 @@ def _try_coerce_args(self, values, other):
27012714
# when falling back to ObjectBlock.where
27022715
other = other.astype(object)
27032716

2704-
return values, other
2717+
return other
27052718

27062719
def should_store(self, value):
27072720
return not (issubclass(value.dtype.type,

pandas/tests/internals/test_internals.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,14 @@ def test_try_coerce_arg(self):
299299
block = create_block('datetime', [0])
300300

301301
# coerce None
302-
none_coerced = block._try_coerce_args(block.values, None)[1]
302+
none_coerced = block._try_coerce_args(None)
303303
assert pd.Timestamp(none_coerced) is pd.NaT
304304

305305
# coerce different types of date bojects
306306
vals = (np.datetime64('2010-10-10'), datetime(2010, 10, 10),
307307
date(2010, 10, 10))
308308
for val in vals:
309-
coerced = block._try_coerce_args(block.values, val)[1]
309+
coerced = block._try_coerce_args(val)
310310
assert np.int64 == type(coerced)
311311
assert pd.Timestamp('2010-10-10') == pd.Timestamp(coerced)
312312

0 commit comments

Comments
 (0)