Skip to content

Commit de7a978

Browse files
authored
REF: dont alter self in _validate_specification (#48051)
* REF: dont alter self in _validate_specification * validate_specification->validate_left_right_on
1 parent 60b4400 commit de7a978

File tree

1 file changed

+48
-44
lines changed

1 file changed

+48
-44
lines changed

pandas/core/reshape/merge.py

+48-44
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,6 @@ def __init__(
640640
self.axis = 1 - axis if self.left.ndim == 2 else 0
641641

642642
self.on = com.maybe_make_list(on)
643-
self.left_on = com.maybe_make_list(left_on)
644-
self.right_on = com.maybe_make_list(right_on)
645643

646644
self.copy = copy
647645
self.suffixes = suffixes
@@ -674,7 +672,7 @@ def __init__(
674672
msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe())
675673
)
676674

677-
self._validate_specification()
675+
self.left_on, self.right_on = self._validate_left_right_on(left_on, right_on)
678676

679677
cross_col = None
680678
if self.how == "cross":
@@ -1077,7 +1075,7 @@ def _get_merge_keys(self):
10771075
# a pd.merge_asof(left_index=True, left_by=...) will result in a
10781076
# self.left_on array with a None in the middle of it. This requires
10791077
# a work-around as designated in the code below.
1080-
# See _validate_specification() for where this happens.
1078+
# See _validate_left_right_on() for where this happens.
10811079

10821080
# ugh, spaghetti re #733
10831081
if _any(self.left_on) and _any(self.right_on):
@@ -1325,25 +1323,27 @@ def _create_cross_configuration(
13251323
cross_col,
13261324
)
13271325

1328-
def _validate_specification(self) -> None:
1326+
def _validate_left_right_on(self, left_on, right_on):
1327+
left_on = com.maybe_make_list(left_on)
1328+
right_on = com.maybe_make_list(right_on)
1329+
13291330
if self.how == "cross":
13301331
if (
13311332
self.left_index
13321333
or self.right_index
1333-
or self.right_on is not None
1334-
or self.left_on is not None
1334+
or right_on is not None
1335+
or left_on is not None
13351336
or self.on is not None
13361337
):
13371338
raise MergeError(
13381339
"Can not pass on, right_on, left_on or set right_index=True or "
13391340
"left_index=True"
13401341
)
1341-
return
13421342
# Hm, any way to make this logic less complicated??
1343-
elif self.on is None and self.left_on is None and self.right_on is None:
1343+
elif self.on is None and left_on is None and right_on is None:
13441344

13451345
if self.left_index and self.right_index:
1346-
self.left_on, self.right_on = (), ()
1346+
left_on, right_on = (), ()
13471347
elif self.left_index:
13481348
raise MergeError("Must pass right_on or right_index=True")
13491349
elif self.right_index:
@@ -1356,8 +1356,8 @@ def _validate_specification(self) -> None:
13561356
if len(common_cols) == 0:
13571357
raise MergeError(
13581358
"No common columns to perform merge on. "
1359-
f"Merge options: left_on={self.left_on}, "
1360-
f"right_on={self.right_on}, "
1359+
f"Merge options: left_on={left_on}, "
1360+
f"right_on={right_on}, "
13611361
f"left_index={self.left_index}, "
13621362
f"right_index={self.right_index}"
13631363
)
@@ -1366,9 +1366,9 @@ def _validate_specification(self) -> None:
13661366
or not right_cols.join(common_cols, how="inner").is_unique
13671367
):
13681368
raise MergeError(f"Data columns not unique: {repr(common_cols)}")
1369-
self.left_on = self.right_on = common_cols
1369+
left_on = right_on = common_cols
13701370
elif self.on is not None:
1371-
if self.left_on is not None or self.right_on is not None:
1371+
if left_on is not None or right_on is not None:
13721372
raise MergeError(
13731373
'Can only pass argument "on" OR "left_on" '
13741374
'and "right_on", not a combination of both.'
@@ -1378,40 +1378,42 @@ def _validate_specification(self) -> None:
13781378
'Can only pass argument "on" OR "left_index" '
13791379
'and "right_index", not a combination of both.'
13801380
)
1381-
self.left_on = self.right_on = self.on
1382-
elif self.left_on is not None:
1381+
left_on = right_on = self.on
1382+
elif left_on is not None:
13831383
if self.left_index:
13841384
raise MergeError(
13851385
'Can only pass argument "left_on" OR "left_index" not both.'
13861386
)
1387-
if not self.right_index and self.right_on is None:
1387+
if not self.right_index and right_on is None:
13881388
raise MergeError('Must pass "right_on" OR "right_index".')
1389-
n = len(self.left_on)
1389+
n = len(left_on)
13901390
if self.right_index:
1391-
if len(self.left_on) != self.right.index.nlevels:
1391+
if len(left_on) != self.right.index.nlevels:
13921392
raise ValueError(
13931393
"len(left_on) must equal the number "
13941394
'of levels in the index of "right"'
13951395
)
1396-
self.right_on = [None] * n
1397-
elif self.right_on is not None:
1396+
right_on = [None] * n
1397+
elif right_on is not None:
13981398
if self.right_index:
13991399
raise MergeError(
14001400
'Can only pass argument "right_on" OR "right_index" not both.'
14011401
)
1402-
if not self.left_index and self.left_on is None:
1402+
if not self.left_index and left_on is None:
14031403
raise MergeError('Must pass "left_on" OR "left_index".')
1404-
n = len(self.right_on)
1404+
n = len(right_on)
14051405
if self.left_index:
1406-
if len(self.right_on) != self.left.index.nlevels:
1406+
if len(right_on) != self.left.index.nlevels:
14071407
raise ValueError(
14081408
"len(right_on) must equal the number "
14091409
'of levels in the index of "left"'
14101410
)
1411-
self.left_on = [None] * n
1412-
if self.how != "cross" and len(self.right_on) != len(self.left_on):
1411+
left_on = [None] * n
1412+
if self.how != "cross" and len(right_on) != len(left_on):
14131413
raise ValueError("len(right_on) must equal len(left_on)")
14141414

1415+
return left_on, right_on
1416+
14151417
def _validate(self, validate: str) -> None:
14161418

14171419
# Check uniqueness of each
@@ -1769,14 +1771,14 @@ def __init__(
17691771
fill_method=fill_method,
17701772
)
17711773

1772-
def _validate_specification(self) -> None:
1773-
super()._validate_specification()
1774+
def _validate_left_right_on(self, left_on, right_on):
1775+
left_on, right_on = super()._validate_left_right_on(left_on, right_on)
17741776

17751777
# we only allow on to be a single item for on
1776-
if len(self.left_on) != 1 and not self.left_index:
1778+
if len(left_on) != 1 and not self.left_index:
17771779
raise MergeError("can only asof on a key for left")
17781780

1779-
if len(self.right_on) != 1 and not self.right_index:
1781+
if len(right_on) != 1 and not self.right_index:
17801782
raise MergeError("can only asof on a key for right")
17811783

17821784
if self.left_index and isinstance(self.left.index, MultiIndex):
@@ -1797,27 +1799,27 @@ def _validate_specification(self) -> None:
17971799

17981800
# GH#29130 Check that merge keys do not have dtype object
17991801
if not self.left_index:
1800-
left_on = self.left_on[0]
1801-
if is_array_like(left_on):
1802-
lo_dtype = left_on.dtype
1802+
left_on_0 = left_on[0]
1803+
if is_array_like(left_on_0):
1804+
lo_dtype = left_on_0.dtype
18031805
else:
18041806
lo_dtype = (
1805-
self.left[left_on].dtype
1806-
if left_on in self.left.columns
1807-
else self.left.index.get_level_values(left_on)
1807+
self.left[left_on_0].dtype
1808+
if left_on_0 in self.left.columns
1809+
else self.left.index.get_level_values(left_on_0)
18081810
)
18091811
else:
18101812
lo_dtype = self.left.index.dtype
18111813

18121814
if not self.right_index:
1813-
right_on = self.right_on[0]
1814-
if is_array_like(right_on):
1815-
ro_dtype = right_on.dtype
1815+
right_on_0 = right_on[0]
1816+
if is_array_like(right_on_0):
1817+
ro_dtype = right_on_0.dtype
18161818
else:
18171819
ro_dtype = (
1818-
self.right[right_on].dtype
1819-
if right_on in self.right.columns
1820-
else self.right.index.get_level_values(right_on)
1820+
self.right[right_on_0].dtype
1821+
if right_on_0 in self.right.columns
1822+
else self.right.index.get_level_values(right_on_0)
18211823
)
18221824
else:
18231825
ro_dtype = self.right.index.dtype
@@ -1839,13 +1841,15 @@ def _validate_specification(self) -> None:
18391841
if len(self.left_by) != len(self.right_by):
18401842
raise MergeError("left_by and right_by must be same length")
18411843

1842-
self.left_on = self.left_by + list(self.left_on)
1843-
self.right_on = self.right_by + list(self.right_on)
1844+
left_on = self.left_by + list(left_on)
1845+
right_on = self.right_by + list(right_on)
18441846

18451847
# check 'direction' is valid
18461848
if self.direction not in ["backward", "forward", "nearest"]:
18471849
raise MergeError(f"direction invalid: {self.direction}")
18481850

1851+
return left_on, right_on
1852+
18491853
def _get_merge_keys(self):
18501854

18511855
# note this function has side effects

0 commit comments

Comments
 (0)