Repository: pandas-dev/pandas

Issue:
Series.__setitem__ with datetime64[ns, tz] dtype raises ValueError when setting a tz-aware timestamps
I'm not able to construct a Series element by element if the elements are timezone localized datetimes. Any workarounds?
#### Code Sample, a copy-pastable example if possible

``` python
# This works
x = pd.Series()
x['foo'] = pd.to_datetime(42)
x['bar'] = pd.to_datetime(666)

# This doesn't
x = pd.Series()
x['foo'] = pd.to_datetime(42).tz_localize('UTC')
x['bar'] = pd.to_datetime(666).tz_localize('UTC')
```

```
ValueError                                Traceback (most recent call last)
<ipython-input-24-cc1ab78086e5> in <module>()
      1 x = pd.Series()
      2 x['foo'] = pd.to_datetime(42).tz_localize('UTC')
----> 3 x['bar'] = pd.to_datetime(666).tz_localize('UTC')

/usr/lib/python3.5/site-packages/pandas/core/series.py in __setitem__(self, key, value)
    726         # do the setitem
    727         cacher_needs_updating = self._check_is_chained_assignment_possible()
--> 728         setitem(key, value)
    729         if cacher_needs_updating:
    730             self._maybe_update_cacher()

/usr/lib/python3.5/site-packages/pandas/core/series.py in setitem(key, value)
    722                     pass
    723 
--> 724             self._set_with(key, value)
    725 
    726         # do the setitem

/usr/lib/python3.5/site-packages/pandas/core/series.py in _set_with(self, key, value)
    770                 self._set_values(key.astype(np.bool_), value)
    771             else:
--> 772                 self._set_labels(key, value)
    773 
    774     def _set_labels(self, key, value):

/usr/lib/python3.5/site-packages/pandas/core/series.py in _set_labels(self, key, value)
    780         mask = indexer == -1
    781         if mask.any():
--> 782             raise ValueError('%s not contained in the index' % str(key[mask]))
    783         self._set_values(indexer, value)
    784 

ValueError: ['b' 'a' 'r'] not contained in the index
```
#### Expected Output

Shouldn't raise errors.
#### output of `pd.show_versions()`

```
INSTALLED VERSIONS
------------------
commit: None
python: 3.5.1.final.0
python-bits: 64
OS: Linux
OS-release: 4.4.6-gnu-1
machine: x86_64
processor: 
byteorder: little
LC_ALL: None
LANG: en_DK.UTF-8

pandas: 0.18.0
nose: 1.3.7
pip: 8.1.1
setuptools: 18.2
Cython: 0.24
numpy: 1.11.0
scipy: 0.17.0
statsmodels: None
xarray: None
IPython: 4.1.2
sphinx: 1.4
patsy: None
dateutil: 2.5.2
pytz: 2016.3
blosc: None
bottleneck: None
tables: 3.2.2
numexpr: 2.5.2
matplotlib: 1.5.1
openpyxl: None
xlrd: 0.9.4
xlwt: None
xlsxwriter: None
lxml: None
bs4: 4.4.1
html5lib: None
httplib2: 0.9.2
apiclient: 1.5.0
sqlalchemy: 1.0.12
pymysql: None
psycopg2: 2.6.1 (dt dec pq3 ext lo64)
jinja2: 2.8
boto: None
```



Discussion:
you can do `x.loc['bar'] = ....`

bug on the getitem expansion though.

Pushing to 0.25.1.

Resolving patch:
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -1268,6 +1268,13 @@ def _set_with(self, key, value):
                 except Exception:
                     pass
 
+            if is_scalar(key) and not is_integer(key) and key not in self.index:
+                # GH#12862 adding an new key to the Series
+                # Note: have to exclude integers because that is ambiguously
+                #  position-based
+                self.loc[key] = value
+                return
+
             if is_scalar(key):
                 key = [key]
             elif not isinstance(key, (list, Series, np.ndarray)):


Test patch:
diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py
--- a/pandas/tests/indexing/test_loc.py
+++ b/pandas/tests/indexing/test_loc.py
@@ -802,7 +802,7 @@ def test_loc_setitem_with_scalar_index(self, indexer, value):
 
         assert is_scalar(result) and result == "Z"
 
-    def test_loc_coerceion(self):
+    def test_loc_coercion(self):
 
         # 12411
         df = DataFrame({"date": [Timestamp("20130101").tz_localize("UTC"), pd.NaT]})
@@ -838,6 +838,26 @@ def test_loc_coerceion(self):
         result = df.iloc[3:]
         tm.assert_series_equal(result.dtypes, expected)
 
+    def test_setitem_new_key_tz(self):
+        # GH#12862 should not raise on assigning the second value
+        vals = [
+            pd.to_datetime(42).tz_localize("UTC"),
+            pd.to_datetime(666).tz_localize("UTC"),
+        ]
+        expected = pd.Series(vals, index=["foo", "bar"])
+
+        ser = pd.Series()
+        ser["foo"] = vals[0]
+        ser["bar"] = vals[1]
+
+        tm.assert_series_equal(ser, expected)
+
+        ser = pd.Series()
+        ser.loc["foo"] = vals[0]
+        ser.loc["bar"] = vals[1]
+
+        tm.assert_series_equal(ser, expected)
+
     def test_loc_non_unique(self):
         # GH3659
         # non-unique indexer with loc slice
diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py
--- a/pandas/tests/series/indexing/test_indexing.py
+++ b/pandas/tests/series/indexing/test_indexing.py
@@ -523,7 +523,7 @@ def test_setitem_with_tz_dst():
     tm.assert_series_equal(s, exp)
 
 
-def test_categorial_assigning_ops():
+def test_categorical_assigning_ops():
     orig = Series(Categorical(["b", "b"], categories=["a", "b"]))
     s = orig.copy()
     s[:] = "a"