Skip to content

Commit b47f1eb

Browse files
authored
REF: catch more specific exceptions in Series.__setitem__ (#45194)
1 parent b5c6e47 commit b47f1eb

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

pandas/core/series.py

+21-11
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,9 @@ def __setitem__(self, key, value) -> None:
10811081

10821082
try:
10831083
self._set_with_engine(key, value)
1084-
except (KeyError, ValueError):
1084+
except KeyError:
1085+
# We have a scalar (or for MultiIndex or object-dtype, scalar-like)
1086+
# key that is not present in self.index.
10851087
if is_integer(key) and self.index.inferred_type != "integer":
10861088
# positional setter
10871089
if not self.index._should_fallback_to_positional:
@@ -1102,9 +1104,15 @@ def __setitem__(self, key, value) -> None:
11021104
# GH#12862 adding a new key to the Series
11031105
self.loc[key] = value
11041106

1105-
except (InvalidIndexError, TypeError) as err:
1107+
except (TypeError, ValueError):
1108+
# The key was OK, but we cannot set the value losslessly
1109+
indexer = self.index.get_loc(key)
1110+
self._set_values(indexer, value)
1111+
1112+
except InvalidIndexError as err:
11061113
if isinstance(key, tuple) and not isinstance(self.index, MultiIndex):
11071114
# cases with MultiIndex don't get here bc they raise KeyError
1115+
# e.g. test_basic_getitem_setitem_corner
11081116
raise KeyError(
11091117
"key of type tuple not found and not a MultiIndex"
11101118
) from err
@@ -1163,17 +1171,19 @@ def _set_with(self, key, value):
11631171
# Without this, the call to infer_dtype will consume the generator
11641172
key = list(key)
11651173

1166-
key_type = lib.infer_dtype(key, skipna=False)
1174+
if not self.index._should_fallback_to_positional:
1175+
# Regardless of the key type, we're treating it as labels
1176+
self._set_labels(key, value)
11671177

1168-
# Note: key_type == "boolean" should not occur because that
1169-
# should be caught by the is_bool_indexer check in __setitem__
1170-
if key_type == "integer":
1171-
if not self.index._should_fallback_to_positional:
1172-
self._set_labels(key, value)
1173-
else:
1174-
self._set_values(key, value)
11751178
else:
1176-
self.loc[key] = value
1179+
# Note: key_type == "boolean" should not occur because that
1180+
# should be caught by the is_bool_indexer check in __setitem__
1181+
key_type = lib.infer_dtype(key, skipna=False)
1182+
1183+
if key_type == "integer":
1184+
self._set_values(key, value)
1185+
else:
1186+
self._set_labels(key, value)
11771187

11781188
def _set_labels(self, key, value) -> None:
11791189
key = com.asarray_tuplesafe(key)

0 commit comments

Comments
 (0)