Repository: dask/dask

Issue:
`Blockwise.clone` doesn't handle (iterable) literal arguments correctly
**What happened**:
Calling `dask.graph_manipulation.clone` on the result of a `dask.array.blockwise` operation with a (iterable) literal argument results in a `ValueError`.

**What you expected to happen**:
The `dask.graph_manipulation.clone` operation to succeed.

**Minimal Complete Verifiable Example**:
```python
import dask.array as da
from dask.graph_manipulation import clone

if __name__ == "__main__":

    x = da.ones(10)
    y = (1,)

    z = da.blockwise(lambda x, y: x + y[0], "r",
                     x, "r",
                     y, None)

    clone(z)
```

**Anything else we need to know?**:
The above produces:
```
TypeError: unhashable type: 'list'
```

I have traced the problem to:
https://github.com/dask/dask/blob/1ccd1a4f96afa1fe89ea93dcfe66517319b0664d/dask/blockwise.py#L812-L817

In the above, the conditional `if k in names` causes the `ValueError` when `k` is not hashable.

**Environment**:

- Dask version: 2022.4.1
- Python version: 3.8.10
- Operating System: Ubuntu 20.04
- Install method (conda, pip, source): pip
`Blockwise.clone` doesn't handle (iterable) literal arguments correctly
**What happened**:
Calling `dask.graph_manipulation.clone` on the result of a `dask.array.blockwise` operation with a (iterable) literal argument results in a `ValueError`.

**What you expected to happen**:
The `dask.graph_manipulation.clone` operation to succeed.

**Minimal Complete Verifiable Example**:
```python
import dask.array as da
from dask.graph_manipulation import clone

if __name__ == "__main__":

    x = da.ones(10)
    y = (1,)

    z = da.blockwise(lambda x, y: x + y[0], "r",
                     x, "r",
                     y, None)

    clone(z)
```

**Anything else we need to know?**:
The above produces:
```
TypeError: unhashable type: 'list'
```

I have traced the problem to:
https://github.com/dask/dask/blob/1ccd1a4f96afa1fe89ea93dcfe66517319b0664d/dask/blockwise.py#L812-L817

In the above, the conditional `if k in names` causes the `ValueError` when `k` is not hashable.

**Environment**:

- Dask version: 2022.4.1
- Python version: 3.8.10
- Operating System: Ubuntu 20.04
- Install method (conda, pip, source): pip


Discussion:

Resolving patch:
diff --git a/dask/blockwise.py b/dask/blockwise.py
--- a/dask/blockwise.py
+++ b/dask/blockwise.py
@@ -824,7 +824,7 @@ def clone(
 
         indices = []
         for k, idxv in self.indices:
-            if k in names:
+            if idxv is not None and k in names:
                 is_leaf = False
                 k = clone_key(k, seed)
             indices.append((k, idxv))


Test patch:
diff --git a/dask/tests/test_graph_manipulation.py b/dask/tests/test_graph_manipulation.py
--- a/dask/tests/test_graph_manipulation.py
+++ b/dask/tests/test_graph_manipulation.py
@@ -225,6 +225,30 @@ def test_clone(layers):
     assert_no_common_keys(c8, t3, layers=layers)
 
 
+@pytest.mark.skipif("not da or not dd")
+@pytest.mark.parametrize(
+    "literal",
+    [
+        1,
+        (1,),
+        [1],
+        {1: 1},
+        {1},
+    ],
+)
+def test_blockwise_clone_with_literals(literal):
+    arr = da.ones(10, chunks=1)
+
+    def noop(arr, lit):
+        return arr
+
+    blk = da.blockwise(noop, "x", arr, "x", literal, None)
+
+    cln = clone(blk)
+
+    assert_no_common_keys(blk, cln, layers=True)
+
+
 @pytest.mark.parametrize("layers", [False, True])
 def test_bind(layers):
     dsk1 = {("a-1", h1): 1, ("a-1", h2): 2}