Repository: dask/dask

Issue:
Dask array `eye` key error 
The following `da.eye` snippet 

```python
import dask.array as da
da.eye(10, chunks=-1).compute()
```

raises `KeyError: ('eye-c26fa66cf1d752e6525f23ca3762f597', 0, 0)`. I've not looked into this too deeply yet, but suspect we're not handling the `chunks=-1` case gracefully. 

<details>
<summary>Full traceback:</summary>

```
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-55dafe761500> in <module>
----> 1 da.eye(10, chunks=-1).compute()

~/projects/dask/dask/dask/base.py in compute(self, **kwargs)
    284         dask.base.compute
    285         """
--> 286         (result,) = compute(self, traverse=False, **kwargs)
    287         return result
    288

~/projects/dask/dask/dask/base.py in compute(*args, **kwargs)
    566         postcomputes.append(x.__dask_postcompute__())
    567
--> 568     results = schedule(dsk, keys, **kwargs)
    569     return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])
    570

~/projects/dask/dask/dask/threaded.py in get(dsk, result, cache, num_workers, pool, **kwargs)
     77             pool = MultiprocessingPoolExecutor(pool)
     78
---> 79     results = get_async(
     80         pool.submit,
     81         pool._max_workers,

~/projects/dask/dask/dask/local.py in get_async(submit, num_workers, dsk, result, cache, get_id, rerun_exceptions_locally, pack_exception, raise_exception, callbacks, dumps, loads, chunksize, **kwargs)
    526                     finish(dsk, state, not succeeded)
    527
--> 528     return nested_get(result, state["cache"])
    529
    530

~/projects/dask/dask/dask/local.py in nested_get(ind, coll)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in <listcomp>(.0)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in nested_get(ind, coll)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in <listcomp>(.0)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in nested_get(ind, coll)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in <listcomp>(.0)
    306     """
    307     if isinstance(ind, list):
--> 308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
    310         return coll[ind]

~/projects/dask/dask/dask/local.py in nested_get(ind, coll)
    308         return tuple([nested_get(i, coll) for i in ind])
    309     else:
--> 310         return coll[ind]
    311
    312

KeyError: ('eye-c26fa66cf1d752e6525f23ca3762f597', 0, 0)
```

</details>


Discussion:
cc @ncclementi as you may find this issue interesting 

Resolving patch:
diff --git a/dask/array/creation.py b/dask/array/creation.py
--- a/dask/array/creation.py
+++ b/dask/array/creation.py
@@ -543,19 +543,13 @@ def eye(N, chunks="auto", M=None, k=0, dtype=float):
 
     if not isinstance(chunks, (int, str)):
         raise ValueError("chunks must be an int or string")
-    elif isinstance(chunks, str):
-        chunks = normalize_chunks(chunks, shape=(N, M), dtype=dtype)
-        chunks = chunks[0][0]
+
+    vchunks, hchunks = normalize_chunks(chunks, shape=(N, M), dtype=dtype)
+    chunks = vchunks[0]
+
     token = tokenize(N, chunks, M, k, dtype)
     name_eye = "eye-" + token
 
-    vchunks = [chunks] * (N // chunks)
-    if N % chunks != 0:
-        vchunks.append(N % chunks)
-    hchunks = [chunks] * (M // chunks)
-    if M % chunks != 0:
-        hchunks.append(M % chunks)
-
     for i, vchunk in enumerate(vchunks):
         for j, hchunk in enumerate(hchunks):
             if (j - i - 1) * chunks <= k <= (j - i + 1) * chunks:


Test patch:
diff --git a/dask/array/tests/test_creation.py b/dask/array/tests/test_creation.py
--- a/dask/array/tests/test_creation.py
+++ b/dask/array/tests/test_creation.py
@@ -404,6 +404,7 @@ def test_eye():
 
     assert_eq(da.eye(9, chunks=3, dtype=int), np.eye(9, dtype=int))
     assert_eq(da.eye(10, chunks=3, dtype=int), np.eye(10, dtype=int))
+    assert_eq(da.eye(10, chunks=-1, dtype=int), np.eye(10, dtype=int))
 
     with dask.config.set({"array.chunk-size": "50 MiB"}):
         x = da.eye(10000, "auto")