Repository: dask/dask
File: dask/array/core.py (Python)

Code before:
            "Passing an object to dask.array.from_array which is already a "
            "Dask collection. This can lead to unexpected behavior."
        )

    if isinstance(x, (list, tuple, memoryview) + np.ScalarType):
        x = np.array(x)

    if is_arraylike(x) and hasattr(x, "copy"):
        x = x.copy()

    if asarray is None:
        asarray = not hasattr(x, "__array_function__")

    previous_chunks = getattr(x, "chunks", None)

    # As of Zarr 3.x, arrays can have a shards attribute. If present,
    # this defines the smallest array region that is safe to write, and
    # thus this is a better default than the chunks attribute.
    # We check for chunks AND shards to be somewhat specific to Zarr 3.x arrays
    if (
        hasattr(x, "chunks")
        and hasattr(x, "shards")
        and (x.shards is not None)
        and chunks == "auto"
    ):
        chunks = x.shards

    chunks = normalize_chunks(
        chunks, x.shape, dtype=x.dtype, previous_chunks=previous_chunks
    )

    if name in (None, True):
        token = tokenize(x, chunks, lock, asarray, fancy, getitem, inline_array)
        name = name or "array-" + token
    elif name is False:
        name = "array-" + str(uuid.uuid1())

    if lock is True:
        lock = SerializableLock()

    is_ndarray = type(x) in (np.ndarray, np.ma.core.MaskedArray)
    is_single_block = all(len(c) == 1 for c in chunks)
    # Always use the getter for h5py etc. Not using isinstance(x, np.ndarray)
    # because np.matrix is a subclass of np.ndarray.
    if is_ndarray and not is_single_block and not lock:
        # eagerly slice numpy arrays to prevent memory blowup
        # GH5367, GH5601
        slices = slices_from_chunks(chunks)
        keys = product([name], *(range(len(bds)) for bds in chunks))
        values = [x[slc] for slc in slices]
        dsk = dict(zip(keys, values))

Review comment (suggestion):
@d-v-b There is an equivalent change to Xarray that would be good to make: https://github.com/pydata/xarray/blob/19f2973528df7e423aae85184f7c65bf7de9cb2e/xarray/backends/zarr.py#L858

Code after:
            "Passing an object to dask.array.from_array which is already a "
            "Dask collection. This can lead to unexpected behavior."
        )

    if isinstance(x, (list, tuple, memoryview) + np.ScalarType):
        x = np.array(x)

    if is_arraylike(x) and hasattr(x, "copy"):
        x = x.copy()

    if asarray is None:
        asarray = not hasattr(x, "__array_function__")

    previous_chunks = getattr(x, "chunks", None)

    # As of Zarr 3.x, arrays can have a shards attribute. If present,
    # this defines the smallest array region that is safe to write, and
    # thus this is a better starting point than the chunks attribute.
    # We check for chunks AND shards to be somewhat specific to Zarr 3.x arrays
    if (
        hasattr(x, "chunks")
        and hasattr(x, "shards")
        and (x.shards is not None)
        and chunks == "auto"
    ):
        previous_chunks = x.shards

    chunks = normalize_chunks(
        chunks, x.shape, dtype=x.dtype, previous_chunks=previous_chunks
    )

    if name in (None, True):
        token = tokenize(x, chunks, lock, asarray, fancy, getitem, inline_array)
        name = name or "array-" + token
    elif name is False:
        name = "array-" + str(uuid.uuid1())

    if lock is True:
        lock = SerializableLock()

    is_ndarray = type(x) in (np.ndarray, np.ma.core.MaskedArray)
    is_single_block = all(len(c) == 1 for c in chunks)
    # Always use the getter for h5py etc. Not using isinstance(x, np.ndarray)
    # because np.matrix is a subclass of np.ndarray.
    if is_ndarray and not is_single_block and not lock:
        # eagerly slice numpy arrays to prevent memory blowup
        # GH5367, GH5601
        slices = slices_from_chunks(chunks)
        keys = product([name], *(range(len(bds)) for bds in chunks))
        values = [x[slc] for slc in slices]
        dsk = dict(zip(keys, values))