Repository: dask/dask

Issue:
dask.array.rechunk no longer works with an integer
This worked on dask 0.5, but now raises on master:

```
In [5]: da.from_array(np.arange(5), chunks=4).rechunk(3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-1383bbf6e4cd> in <module>()
----> 1 da.from_array(np.arange(5), chunks=4).rechunk(3)

/Users/shoyer/dev/dask/dask/array/core.pyc in rechunk(self, chunks)
   1069     def rechunk(self, chunks):
   1070         from .rechunk import rechunk
-> 1071         return rechunk(self, chunks)
   1072
   1073

/Users/shoyer/dev/dask/dask/array/rechunk.pyc in rechunk(x, chunks)
    198             chunks = blockdims_dict_to_tuple(x.chunks, chunks)
    199     chunks = tuple(lc if lc is not None else rc
--> 200                    for lc, rc in zip(chunks, x.chunks))
    201     chunks = normalize_chunks(chunks, x.shape)
    202     if not len(chunks) == x.ndim or tuple(map(sum, chunks)) != x.shape:

TypeError: zip argument #1 must support iteration
```

This causes a test failure for xray. On a related note, I'm now testing dask master on Travis with xray as (the last) optional test: https://travis-ci.org/xray/xray



Discussion:
On it.

The same [xray unit test](https://travis-ci.org/xray/xray/jobs/67867430) on dask master is still failing, unfortunately -- now with a different error message:

```
In [6]: da.from_array(np.zeros((4, 6)), chunks=2).rechunk(3)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-89ccc8d14449> in <module>()
----> 1 da.from_array(np.zeros((4, 6)), chunks=2).rechunk(3)

/Users/shoyer/dev/dask/dask/array/core.pyc in rechunk(self, chunks)
   1069     def rechunk(self, chunks):
   1070         from .rechunk import rechunk
-> 1071         return rechunk(self, chunks)
   1072
   1073

/Users/shoyer/dev/dask/dask/array/rechunk.pyc in rechunk(x, chunks)
    203     chunks = normalize_chunks(chunks, x.shape)
    204     if not len(chunks) == x.ndim or tuple(map(sum, chunks)) != x.shape:
--> 205         raise ValueError("Provided chunks are not consistent with shape")
    206
    207     crossed = intersect_chunks(x.chunks, chunks)

ValueError: Provided chunks are not consistent with shape
```


Resolving patch:
diff --git a/dask/array/rechunk.py b/dask/array/rechunk.py
--- a/dask/array/rechunk.py
+++ b/dask/array/rechunk.py
@@ -196,10 +196,9 @@ def rechunk(x, chunks):
             chunks = blockshape_dict_to_tuple(x.chunks, chunks)
         else:
             chunks = blockdims_dict_to_tuple(x.chunks, chunks)
-    if not isinstance(chunks, (tuple, list)):
-        chunks = (chunks,)
-    chunks = tuple(lc if lc is not None else rc
-                   for lc, rc in zip(chunks, x.chunks))
+    if isinstance(chunks, (tuple, list)):
+        chunks = tuple(lc if lc is not None else rc
+                       for lc, rc in zip(chunks, x.chunks))
     chunks = normalize_chunks(chunks, x.shape)
     if not len(chunks) == x.ndim or tuple(map(sum, chunks)) != x.shape:
         raise ValueError("Provided chunks are not consistent with shape")


Test patch:
diff --git a/dask/array/tests/test_array_core.py b/dask/array/tests/test_array_core.py
--- a/dask/array/tests/test_array_core.py
+++ b/dask/array/tests/test_array_core.py
@@ -1060,3 +1060,7 @@ def test_take_dask_from_numpy():
 
     assert z.chunks == y.chunks
     assert eq(z, np.array([2., 4., 6., 6., 4., 2.]))
+
+
+def test_normalize_chunks():
+    assert normalize_chunks(3, (4, 6)) == ((3, 1), (3, 3))
diff --git a/dask/array/tests/test_chunk.py b/dask/array/tests/test_chunk.py
--- a/dask/array/tests/test_chunk.py
+++ b/dask/array/tests/test_chunk.py
@@ -6,6 +6,7 @@
 import numpy as np
 
 from dask.array.chunk import coarsen, keepdims_wrapper, trim
+import dask.array as da
 
 
 def test_keepdims_wrapper_no_axis():
@@ -114,3 +115,7 @@ def test_coarsen_on_uneven_shape():
     assert y[0, 0] == np.sum(x[:2, :4])
     assert eq(y[11, :], x[23, :])
 """
+
+
+def test_integer_input():
+    assert da.zeros((4, 6), chunks=2).rechunk(3).chunks == ((3, 1), (3, 3))