Repository: blaze/blaze

Issue:
`Data([('aa', 1)])` doesn't repr
``` python
In [7]: bz.__version__
Out[7]: '0.8.3'

In [8]: d = bz.Data([('aa', 2)])

In [9]: d
Out[9]: ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/IPython/core/formatters.pyc in __call__(self, obj)
    695                 type_pprinters=self.type_printers,
    696                 deferred_pprinters=self.deferred_printers)
--> 697             printer.pretty(obj)
    698             printer.flush()
    699             return stream.getvalue()

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/IPython/lib/pretty.pyc in pretty(self, obj)
    381                             if callable(meth):
    382                                 return meth(obj, self, cycle)
--> 383             return _default_pprint(obj, self, cycle)
    384         finally:
    385             self.end_group()

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/IPython/lib/pretty.pyc in _default_pprint(obj, p, cycle)
    501     if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
    502         # A user-provided repr. Find newlines and replace them with p.break_()
--> 503         _repr_pprint(obj, p, cycle)
    504         return
    505     p.begin_group(1, '<')

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/IPython/lib/pretty.pyc in _repr_pprint(obj, p, cycle)
    683     """A pprint that just redirects to the normal repr function."""
    684     # Find newlines and replace them with p.break_()
--> 685     output = repr(obj)
    686     for idx,output_line in enumerate(output.splitlines()):
    687         if idx:

/Users/ksmith/work/blaze/blaze-repo/blaze/interactive.pyc in expr_repr(expr, n)
    259     if (ndim(expr) == 1 and (istabular(expr.dshape) or
    260                              isscalar(expr.dshape.measure))):
--> 261         return repr_tables(expr, 10)
    262
    263     # Smallish arrays

/Users/ksmith/work/blaze/blaze-repo/blaze/interactive.pyc in repr_tables(expr, n)
    198
    199 def repr_tables(expr, n=10):
--> 200     result = concrete_head(expr, n).rename(columns={None: ''})
    201
    202     if isinstance(result, (DataFrame, Series)):

/Users/ksmith/work/blaze/blaze-repo/blaze/interactive.pyc in concrete_head(expr, n)
    183     else:
    184         df = odo(head, DataFrame)
--> 185         df.columns = [expr._name]
    186         return df
    187     result = compute(head)

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/pandas/core/generic.pyc in __setattr__(self, name, value)
   2159         try:
   2160             object.__getattribute__(self, name)
-> 2161             return object.__setattr__(self, name, value)
   2162         except AttributeError:
   2163             pass

pandas/src/properties.pyx in pandas.lib.AxisProperty.__set__ (pandas/lib.c:42548)()

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/pandas/core/generic.pyc in _set_axis(self, axis, labels)
    411
    412     def _set_axis(self, axis, labels):
--> 413         self._data.set_axis(axis, labels)
    414         self._clear_item_cache()
    415

/Users/ksmith/anaconda/envs/dataportal/lib/python2.7/site-packages/pandas/core/internals.pyc in set_axis(self, axis, new_labels)
   2217         if new_len != old_len:
   2218             raise ValueError('Length mismatch: Expected axis has %d elements, '
-> 2219                              'new values have %d elements' % (old_len, new_len))
   2220
   2221         self.axes[axis] = new_labels

ValueError: Length mismatch: Expected axis has 2 elements, new values have 1 elements
```



Discussion:
@kwmsmith what would you expect this to repr as? Since there are no column names we can't _really_ convert it to a sensible `DataFrame`.

I guess we could do this:

``` python
In [7]: from odo import odo

In [8]: odo([('a', 2)], pd.DataFrame)
Out[8]:
  f0  f1
0  a   2
```

but I _really_ don't like that numpy does this in the first place. I think we should raise an error here.


Resolving patch:
diff --git a/blaze/interactive.py b/blaze/interactive.py
--- a/blaze/interactive.py
+++ b/blaze/interactive.py
@@ -97,20 +97,16 @@ def _hashargs(self):
 
 
 @copydoc(InteractiveSymbol)
-def Data(data, dshape=None, name=None, fields=None, columns=None, schema=None,
-         **kwargs):
-    if columns:
-        raise ValueError("columns argument deprecated, use fields instead")
+def Data(data, dshape=None, name=None, fields=None, schema=None, **kwargs):
     if schema and dshape:
         raise ValueError("Please specify one of schema= or dshape= keyword"
                          " arguments")
 
     if isinstance(data, InteractiveSymbol):
-        return Data(data.data, dshape, name, fields, columns, schema, **kwargs)
+        return Data(data.data, dshape, name, fields, schema, **kwargs)
 
     if isinstance(data, _strtypes):
-        data = resource(data, schema=schema, dshape=dshape, columns=columns,
-                        **kwargs)
+        data = resource(data, schema=schema, dshape=dshape, **kwargs)
     if (isinstance(data, Iterator) and
             not isinstance(data, tuple(not_an_iterator))):
         data = tuple(data)


Test patch:
diff --git a/blaze/tests/test_interactive.py b/blaze/tests/test_interactive.py
--- a/blaze/tests/test_interactive.py
+++ b/blaze/tests/test_interactive.py
@@ -394,11 +394,6 @@ def test_asarray_fails_on_different_column_names():
         Data(df, fields=list('abc'))
 
 
-def test_data_does_not_accept_columns_kwarg():
-    with pytest.raises(ValueError):
-        Data([(1, 2), (3, 4)], columns=list('ab'))
-
-
 def test_functions_as_bound_methods():
     """
     Test that all functions on an InteractiveSymbol are instance methods
@@ -459,3 +454,8 @@ def test_pickle_roundtrip():
     es = Data(np.array([1, 2, 3]))
     assert es.isidentical(pickle.loads(pickle.dumps(es)))
     assert (es + 1).isidentical(pickle.loads(pickle.dumps(es + 1)))
+
+
+def test_nameless_data():
+    data = [('a', 1)]
+    assert repr(data) in repr(Data(data))