Repository: blaze/blaze

Issue:
Individual columns should be able to repr if not passed in CSV
This issue title is possibly the worst ever, so here's an example:

``` python
import tempfile
import pandas as pd
from blaze import *
```

This works:

``` python
with tempfile.NamedTemporaryFile(delete=False) as f:
    df = pd.DataFrame(np.random.randn(10, 2))
    df.to_csv(f.name, index=False, header=False)
    csv = CSV(f.name, columns=list('ab'))  # passing columns to CSV
    t = Table(csv)
    assert t.a.isidentical(t['a'])
```

But this:

``` python
with tempfile.NamedTemporaryFile(delete=False) as f:
    df = pd.DataFrame(np.random.randn(10, 2))
    df.to_csv(f.name, index=False, header=False)
    csv = CSV(f.name)
    t = Table(csv, columns=list('ab'))  # passing columns to Table
    assert t.a.isidentical(t['a'])
```

yield a `t` where `t.a` throws an error in the interpreter when I try to `repr` it.

The difference is that the first propagates the columns to the `Table` (or maybe it doesn't propagate, but it uses the correct names), while in the second the columns are still represented by their "anonymous" names `_0`, `_1`, etc.



Discussion:
On messing around with this I think it should raise a `TypeError`, I'll put up a PR to discuss.

Longer term, I wonder if having something like a surrogate column name where the underlying data representation can have columns called whatever (certain properties, e.g., `len` have to be the same), but the operations are all driven by whatever is in the `Table` instance.


Resolving patch:
diff --git a/blaze/api/table.py b/blaze/api/table.py
--- a/blaze/api/table.py
+++ b/blaze/api/table.py
@@ -4,9 +4,7 @@
 
 from ..expr.core import Expr
 from ..expr.table import TableSymbol, TableExpr
-from ..data.python import Python
 from ..dispatch import dispatch
-from ..data.core import DataDescriptor, discover
 from ..data.pandas import into, DataFrame
 from .into import into
 
@@ -58,6 +56,12 @@ def __init__(self, data, name=None, columns=None, schema=None,
         self.schema = dshape(schema)
 
         self.data = data
+
+        if hasattr(data, 'schema') and self.schema != data.schema:
+            raise TypeError('%s schema %s does not match %s schema %s' %
+                            (type(data).__name__, data.schema,
+                             type(self).__name__, self.schema))
+
         self._name = name or next(names)
         self.iscolumn = iscolumn
 


Test patch:
diff --git a/blaze/expr/tests/test_table.py b/blaze/expr/tests/test_table.py
--- a/blaze/expr/tests/test_table.py
+++ b/blaze/expr/tests/test_table.py
@@ -1,5 +1,10 @@
 from __future__ import absolute_import, division, print_function
 
+import pytest
+import tempfile
+import pandas as pd
+
+from blaze import CSV, Table
 from blaze.expr.table import *
 from blaze.expr.core import discover
 from blaze.utils import raises
@@ -96,6 +101,14 @@ def test_selection_by_getattr():
     assert 'Alice' in str(result)
 
 
+def test_different_schema_raises():
+    with tempfile.NamedTemporaryFile(delete=False) as f:
+        df = pd.DataFrame(np.random.randn(10, 2))
+        df.to_csv(f.name, index=False, header=False)
+        with pytest.raises(TypeError):
+            Table(CSV(f.name), columns=list('ab'))
+
+
 def test_getattr_doesnt_override_properties():
     t = TableSymbol('t', '{iscolumn: string, schema: string}')
     assert isinstance(t.iscolumn, bool)