Repository: pandas-dev/pandas
Pull request: BUG GH23451 Allow setting date in string index for Series
- [X] closes #23451 
- [X] tests added / passed
- [X] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

Prevents string indices from turning into lists of characters when setting a date.


Problem statement:
Can't put date in Series if index is a string longer than 1 character
#### Code Sample

```
>>> import pandas
>>> x = pandas.Series([1,2,3],  index=['Date','b','other'])
>>> x
Date     1
b        2
other    3
dtype: int64
>>> from datetime import date
>>> x.Date = date.today()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python37\lib\site-packages\pandas\core\generic.py", line 4405, in __setattr__
    self[name] = value
  File "C:\Python37\lib\site-packages\pandas\core\series.py", line 939, in __setitem__
    setitem(key, value)
  File "C:\Python37\lib\site-packages\pandas\core\series.py", line 935, in setitem
    self._set_with(key, value)
  File "C:\Python37\lib\site-packages\pandas\core\series.py", line 983, in _set_with
    self._set_labels(key, value)
  File "C:\Python37\lib\site-packages\pandas\core\series.py", line 993, in _set_labels
    raise ValueError('%s not contained in the index' % str(key[mask]))
ValueError: ['D' 'a' 't' 'e'] not contained in the index
>>> x.b = date.today()
>>> x.b
datetime.date(2018, 11, 1)
>>> x
Date              1
b        2018-11-01
other             3
dtype: object
>>>
```
#### Problem description

I cannot put a date object in a Series if the index is a string with len > 1.
It works if it's only a single character.  Other types seem to work.  I've only seen the problem with dates.

Hints from issue discussion:
This looks similar to https://github.com/pandas-dev/pandas/issues/12862, and I can reproduce this in master as well.

Commit message: BUG-23451 Add whatsnew and other requested changes

Patch to review:
diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt
index 64cc098ccaa94..600def99ec3f2 100644
--- a/doc/source/whatsnew/v0.24.0.txt
+++ b/doc/source/whatsnew/v0.24.0.txt
@@ -1115,6 +1115,7 @@ Datetimelike
 - Bug in :func:`DataFrame.combine` with datetimelike values raising a TypeError (:issue:`23079`)
 - Bug in :func:`date_range` with frequency of ``Day`` or higher where dates sufficiently far in the future could wrap around to the past instead of raising ``OutOfBoundsDatetime`` (:issue:`14187`)
 - Bug in :class:`PeriodIndex` with attribute ``freq.n`` greater than 1 where adding a :class:`DateOffset` object would return incorrect results (:issue:`23215`)
+- Bug in :class:`Series` that interpreted string indices as lists of characters when setting datetimelike values
 
 Timedelta
 ^^^^^^^^^
diff --git a/pandas/core/series.py b/pandas/core/series.py
index 6cc5acc4a61d0..58cd0fc4cfc31 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -947,7 +947,9 @@ def _set_with(self, key, value):
                 except Exception:
                     pass
 
-            if not isinstance(key, (list, Series, np.ndarray, Series)):
+            if is_scalar(key):
+                key = [key]
+            elif not isinstance(key, (list, Series, np.ndarray)):
                 try:
                     key = list(key)
                 except Exception:
diff --git a/pandas/tests/series/test_datetime_values.py b/pandas/tests/series/test_datetime_values.py
index 2f6efc112819c..1a4d3c583dd94 100644
--- a/pandas/tests/series/test_datetime_values.py
+++ b/pandas/tests/series/test_datetime_values.py
@@ -548,3 +548,10 @@ def test_minmax_nat_series(self, nat):
     def test_minmax_nat_dataframe(self, nat):
         assert nat.min()[0] is pd.NaT
         assert nat.max()[0] is pd.NaT
+
+    def test_set_dt_with_string_index(self):
+        # GH 23451
+        x = pd.Series([1, 2, 3], index=['Date', 'b', 'other'])
+        x['Date'] = date.today()
+        assert x.Date == date.today()
+        assert x['Date'] == date.today()


Code review comments:
diff_hunk: @@ -548,3 +548,10 @@ def test_minmax_nat_series(self, nat):
     def test_minmax_nat_dataframe(self, nat):
         assert nat.min()[0] is pd.NaT
         assert nat.max()[0] is pd.NaT
+
+    def test_set_dt_with_string_index(self):
path: pandas/tests/series/test_datetime_values.py
text: @user1:
rename to test_setitem_with_string_index