diff --git a/.gitignore b/.gitignore
index 7fc3d3c76..f1f69b4c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.hypothesis
 *.py[cod]
 __pycache__/
 *.egg-info
diff --git a/dask/array/core.py b/dask/array/core.py
index 384bc1fdc..a8e11b807 100644
--- a/dask/array/core.py
+++ b/dask/array/core.py
@@ -1337,6 +1337,7 @@ class Array(DaskMethodsMixin):
             self.dtype = y.dtype
             self.dask = y.dask
             self.name = y.name
+            self._chunks = y.chunks
             return self
         else:
             raise NotImplementedError("Item assignment with %s not supported"
diff --git a/dask/array/random.py b/dask/array/random.py
index 5d5a6bb0b..8f299e7d0 100644
--- a/dask/array/random.py
+++ b/dask/array/random.py
@@ -217,6 +217,11 @@ class RandomState(object):
                 size = (size,)
 
             chunks = normalize_chunks(chunks, size, dtype=np.float64)
+            if not replace and len(chunks[0]) > 1:
+                    err_msg = ('replace=False is not currently supported for '
+                               'dask.array.choice with multi-chunk output '
+                               'arrays')
+                    raise NotImplementedError(err_msg)
             sizes = list(product(*chunks))
             state_data = random_state_data(len(sizes), self._numpy_state)
 
diff --git a/docs/README.rst b/docs/README.rst
index bb5afdb9d..932b24eb2 100644
--- a/docs/README.rst
+++ b/docs/README.rst
@@ -5,6 +5,6 @@ these commands suffice::
   git clone git@github.com:dask/dask.git
   cd dask/docs
   conda create -n daskdocs --file requirements-docs.txt
-  source activate daskdocs
+  conda activate daskdocs
   make html
   open build/html/index.html
diff --git a/docs/source/array-api.rst b/docs/source/array-api.rst
index 4abb29387..73e4da786 100644
--- a/docs/source/array-api.rst
+++ b/docs/source/array-api.rst
@@ -338,7 +338,7 @@ Create and Store Arrays
 Generalized Ufuncs
 ~~~~~~~~~~~~~~~~~~
 
-.. currentmodule:: dask.array
+.. currentmodule:: dask.array.gufunc
 
 .. autosummary::
    apply_gufunc

Dask array setitem with differently chunked data provides wrong shape
```python
>>> import dask.array as da
>>> x = da.zeros(5, chunks=2)
>>> m = da.zeros(5, chunks=3)
>>> x[m>0] = 1
>>> print x.shape, x.compute().shape
(5,) (4,)
```

This should probably unifiy chunks before slicing
diff --git a/dask/array/tests/test_random.py b/dask/array/tests/test_random.py
index 4624abf8e..5d270419c 100644
--- a/dask/array/tests/test_random.py
+++ b/dask/array/tests/test_random.py
@@ -268,6 +268,14 @@ def test_choice():
         with pytest.raises(ValueError):
             da.random.choice(a, size=size, chunks=chunks, p=p)
 
+    with pytest.raises(NotImplementedError):
+        da.random.choice(da_a, size=size, chunks=chunks, replace=False)
+
+    # Want to make sure replace=False works for a single-partition output array
+    x = da.random.choice(da_a, size=da_a.shape[0], chunks=-1, replace=False)
+    res = x.compute()
+    assert len(res) == len(np.unique(res))
+
 
 def test_create_with_auto_dimensions():
     with dask.config.set({'array.chunk-size': '128MiB'}):
diff --git a/dask/array/tests/test_slicing.py b/dask/array/tests/test_slicing.py
index 6ed1a3606..5fc3c79d2 100644
--- a/dask/array/tests/test_slicing.py
+++ b/dask/array/tests/test_slicing.py
@@ -798,3 +798,19 @@ def test_pathological_unsorted_slicing():
 
     assert '10' in str(info.list[0])
     assert 'out-of-order' in str(info.list[0])
+
+
+@pytest.mark.parametrize('params', [(2, 2, 1), (5, 3, 2)])
+def test_setitem_with_different_chunks_preserves_shape(params):
+    """ Reproducer for https://github.com/dask/dask/issues/3730.
+
+    Mutating based on an array with different chunks can cause new chunks to be
+    used.  We need to ensure those new chunk sizes are applied to the mutated
+    array, otherwise the array won't generate the correct keys.
+    """
+    array_size, chunk_size1, chunk_size2 = params
+    x = da.zeros(array_size, chunks=chunk_size1)
+    mask = da.zeros(array_size, chunks=chunk_size2)
+    x[mask] = 1
+    result = x.compute()
+    assert x.shape == result.shape
diff --git a/dask/dataframe/io/tests/test_hdf.py b/dask/dataframe/io/tests/test_hdf.py
index 7a316a6ce..9252ee399 100644
--- a/dask/dataframe/io/tests/test_hdf.py
+++ b/dask/dataframe/io/tests/test_hdf.py
@@ -535,6 +535,7 @@ def test_read_hdf_doesnt_segfault():
 
 
 def test_hdf_filenames():
+    pytest.importorskip('tables')
     df = pd.DataFrame({'x': ['a', 'b', 'c', 'd'],
                        'y': [1, 2, 3, 4]}, index=[1., 2., 3., 4.])
     ddf = dd.from_pandas(df, npartitions=2)

pip install -e .[complete]
parse_log_pytest
pytest
pytest
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
click==8.0.4
cloudpickle==2.2.1
-e git+https://github.com/dask/dask.git@06248f39d44d45ff375ee364a1cfa593c161c990#egg=dask
distributed==1.28.1
HeapDict==1.0.1
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1631916693255/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
locket==1.0.0
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
msgpack==1.0.5
numpy==1.19.5
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
pandas==1.1.5
partd==1.2.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
psutil==7.0.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.1
six==1.17.0
sortedcontainers==2.4.0
tblib==1.7.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
toolz==0.12.0
tornado==6.1
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
zict==2.1.0
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: dask
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib-metadata=4.8.1=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - click==8.0.4
      - cloudpickle==2.2.1
      - distributed==1.28.1
      - heapdict==1.0.1
      - locket==1.0.0
      - msgpack==1.0.5
      - numpy==1.19.5
      - pandas==1.1.5
      - partd==1.2.0
      - psutil==7.0.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.1
      - six==1.17.0
      - sortedcontainers==2.4.0
      - tblib==1.7.0
      - toolz==0.12.0
      - tornado==6.1
      - zict==2.1.0
prefix: /opt/conda/envs/dask

dask/array/tests/test_random.py::test_choice dask/array/tests/test_slicing.py::test_setitem_with_different_chunks_preserves_shape[params0] dask/array/tests/test_slicing.py::test_setitem_with_different_chunks_preserves_shape[params1]
dask/array/tests/test_random.py::test_RandomState dask/array/tests/test_random.py::test_concurrency dask/array/tests/test_random.py::test_doc_randomstate dask/array/tests/test_random.py::test_serializability dask/array/tests/test_random.py::test_determinisim_through_dask_values dask/array/tests/test_random.py::test_randomstate_consistent_names dask/array/tests/test_random.py::test_random dask/array/tests/test_random.py::test_parametrized_random_function dask/array/tests/test_random.py::test_kwargs dask/array/tests/test_random.py::test_unique_names dask/array/tests/test_random.py::test_docs dask/array/tests/test_random.py::test_can_make_really_big_random_array dask/array/tests/test_random.py::test_random_seed dask/array/tests/test_random.py::test_consistent_across_sizes dask/array/tests/test_random.py::test_random_all dask/array/tests/test_random.py::test_array_broadcasting dask/array/tests/test_random.py::test_multinomial dask/array/tests/test_random.py::test_create_with_auto_dimensions dask/array/tests/test_random.py::test_names dask/array/tests/test_slicing.py::test_slice_1d dask/array/tests/test_slicing.py::test_slice_singleton_value_on_boundary dask/array/tests/test_slicing.py::test_slice_array_1d dask/array/tests/test_slicing.py::test_slice_array_2d dask/array/tests/test_slicing.py::test_slice_optimizations dask/array/tests/test_slicing.py::test_slicing_with_singleton_indices dask/array/tests/test_slicing.py::test_slicing_with_newaxis dask/array/tests/test_slicing.py::test_take dask/array/tests/test_slicing.py::test_take_sorted dask/array/tests/test_slicing.py::test_slicing_chunks dask/array/tests/test_slicing.py::test_slicing_with_numpy_arrays dask/array/tests/test_slicing.py::test_slicing_and_chunks dask/array/tests/test_slicing.py::test_slicing_identities dask/array/tests/test_slicing.py::test_slice_stop_0 dask/array/tests/test_slicing.py::test_slice_list_then_None dask/array/tests/test_slicing.py::test_slicing_with_negative_step_flops_keys dask/array/tests/test_slicing.py::test_empty_slice dask/array/tests/test_slicing.py::test_multiple_list_slicing dask/array/tests/test_slicing.py::test_boolean_list_slicing dask/array/tests/test_slicing.py::test_boolean_numpy_array_slicing dask/array/tests/test_slicing.py::test_empty_list dask/array/tests/test_slicing.py::test_uneven_chunks dask/array/tests/test_slicing.py::test_new_blockdim dask/array/tests/test_slicing.py::test_slicing_consistent_names dask/array/tests/test_slicing.py::test_slicing_consistent_names_after_normalization dask/array/tests/test_slicing.py::test_sanitize_index_element dask/array/tests/test_slicing.py::test_sanitize_index dask/array/tests/test_slicing.py::test_uneven_blockdims dask/array/tests/test_slicing.py::test_oob_check dask/array/tests/test_slicing.py::test_index_with_int_dask_array[None-None] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[None-3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[None-2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[None-1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks1-None] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks1-3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks1-2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks1-1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks2-None] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks2-3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks2-2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks2-1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks3-None] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks3-3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks3-2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks3-1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks4-None] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks4-3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks4-2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array[x_chunks4-1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_0d[1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_0d[2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_0d[3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nanchunks[1] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nanchunks[2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nanchunks[3] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nanchunks[4] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nanchunks[5] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_negindex[2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_negindex[4] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_indexerror[2] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_indexerror[4] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[int8] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[int16] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[int32] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[int64] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[uint8] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[uint16] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[uint32] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_dtypes[uint64] dask/array/tests/test_slicing.py::test_index_with_int_dask_array_nocompute dask/array/tests/test_slicing.py::test_index_with_bool_dask_array dask/array/tests/test_slicing.py::test_index_with_bool_dask_array_2 dask/array/tests/test_slicing.py::test_slicing_with_Nones[index0-shape0] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index0-shape1] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index0-shape2] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index1-shape0] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index1-shape1] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index1-shape2] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index2-shape0] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index2-shape1] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index2-shape2] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index3-shape0] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index3-shape1] dask/array/tests/test_slicing.py::test_slicing_with_Nones[index3-shape2] dask/array/tests/test_slicing.py::test_slicing_integer_no_warnings dask/array/tests/test_slicing.py::test_None_overlap_int dask/array/tests/test_slicing.py::test_negative_n_slicing dask/array/tests/test_slicing.py::test_negative_list_slicing dask/array/tests/test_slicing.py::test_permit_oob_slices dask/array/tests/test_slicing.py::test_normalize_index dask/array/tests/test_slicing.py::test_take_semi_sorted dask/array/tests/test_slicing.py::test_slicing_plan[chunks0-index0-expected0] dask/array/tests/test_slicing.py::test_slicing_plan[chunks1-index1-expected1] dask/array/tests/test_slicing.py::test_slicing_plan[chunks2-index2-expected2] dask/array/tests/test_slicing.py::test_pathological_unsorted_slicing
docs/README.rst docs/source/array-api.rst dask/array/random.py .gitignore dask/array/core.py
docs/README.rst docs/source/array-api.rst dask/array/random.py .gitignore dask/array/core.py