Repository: pandas-dev/pandas

Issue:
DOC/BUG: error with .at indexer with datimeindex and enlargement
From docs: http://pandas-docs.github.io/pandas-docs-travis/indexing.html#fast-scalar-value-getting-and-setting

```
dates = date_range('1/1/2000', periods=8)
df = DataFrame(randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])
df.at[dates[-1]+1, 0] = 7
```

does now raise an error



Discussion:
that should be 'A' instead of the 0 (that was a previously fixed bug)

ah, but shouldn't it just interprete it as '0' ? (as mixed string / integer index is perfectly possible)

no, `.at` is `.loc` (but restricted to scalars), NOT like `.ix` (iow its strict)

yes, it is strict, so I would thing it should therefore just add a column named 0 (and indeed not add in column at place 0). As on object index can perfectly hold an integer column name.


Resolving patch:
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -1484,7 +1484,7 @@ class _ScalarAccessIndexer(_NDFrameIndexer):
 
     """ access scalars quickly """
 
-    def _convert_key(self, key):
+    def _convert_key(self, key, is_setter=False):
         return list(key)
 
     def __getitem__(self, key):
@@ -1505,7 +1505,7 @@ def __setitem__(self, key, value):
         if len(key) != self.obj.ndim:
             raise ValueError('Not enough indexers for scalar access '
                              '(setting)!')
-        key = list(self._convert_key(key))
+        key = list(self._convert_key(key, is_setter=True))
         key.append(value)
         self.obj.set_value(*key, takeable=self._takeable)
 
@@ -1515,8 +1515,13 @@ class _AtIndexer(_ScalarAccessIndexer):
     """ label based scalar accessor """
     _takeable = False
 
-    def _convert_key(self, key):
+    def _convert_key(self, key, is_setter=False):
         """ require they keys to be the same type as the index (so we don't fallback) """
+
+        # allow arbitrary setting
+        if is_setter:
+            return list(key)
+
         for ax, i in zip(self.obj.axes, key):
             if ax.is_integer():
                 if not com.is_integer(i):
@@ -1536,7 +1541,7 @@ class _iAtIndexer(_ScalarAccessIndexer):
     def _has_valid_setitem_indexer(self, indexer):
         self._has_valid_positional_setitem_indexer(indexer)
 
-    def _convert_key(self, key):
+    def _convert_key(self, key, is_setter=False):
         """ require  integer args (and convert to label arguments) """
         for a, i in zip(self.obj.axes, key):
             if not com.is_integer(i):


Test patch:
diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py
--- a/pandas/tests/test_indexing.py
+++ b/pandas/tests/test_indexing.py
@@ -2932,6 +2932,26 @@ def f():
         p.loc[:,:,'C'] = Series([30,32],index=p_orig.items)
         assert_panel_equal(p,expected)
 
+        # GH 8473
+        dates = date_range('1/1/2000', periods=8)
+        df_orig = DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])
+
+        expected = pd.concat([df_orig,DataFrame({'A' : 7},index=[dates[-1]+1])])
+        df = df_orig.copy()
+        df.loc[dates[-1]+1, 'A'] = 7
+        assert_frame_equal(df,expected)
+        df = df_orig.copy()
+        df.at[dates[-1]+1, 'A'] = 7
+        assert_frame_equal(df,expected)
+
+        expected = pd.concat([df_orig,DataFrame({0 : 7},index=[dates[-1]+1])],axis=1)
+        df = df_orig.copy()
+        df.loc[dates[-1]+1, 0] = 7
+        assert_frame_equal(df,expected)
+        df = df_orig.copy()
+        df.at[dates[-1]+1, 0] = 7
+        assert_frame_equal(df,expected)
+
     def test_partial_setting_mixed_dtype(self):
 
         # in a mixed dtype environment, try to preserve dtypes