//  [python]
def make_new_dset(
    parent,
    shape=None,
    dtype=None,
    data=None,
    chunks=None,
    compression=None,
    shuffle=None,
    fletcher32=None,
    maxshape=None,
    compression_opts=None,
    fillvalue=None,
    scaleoffset=None,
    track_times=None,
    initializer=None,
    initializer_opts=None
):
    """Return a new low-level dataset identifier

    Only creates anonymous datasets.
    """

    # fill in fields for the body of the POST request as we got
    body = {}

    # Convert data to a C-contiguous ndarray
    if data is not None and not isinstance(data, Empty):
        from . import base

        data = base.array_for_new_object(data, specified_dtype=dtype)

    # Validate shape
    if shape is None:
        if data is None:
            if dtype is None:
                raise TypeError("One of data, shape or dtype must be specified")
            data = Empty(dtype)
        shape = data.shape
    else:
        shape = (shape,) if isinstance(shape, int) else tuple(shape)
        if data is not None and (
            numpy.prod(shape, dtype=numpy.ulonglong) != numpy.prod(data.shape, dtype=numpy.ulonglong)
        ):
            raise ValueError("Shape tuple is incompatible with data")

    if shape is None:
        body["shape"] = "H5S_NULL"
    else:
        body["shape"] = shape

    if track_times is not None:
        if track_times not in (True, False):
            raise TypeError("invalid track_times")

    if isinstance(maxshape, int):
        maxshape = (maxshape,)
    tmp_shape = maxshape if maxshape is not None else shape

    # Validate chunk shape
    if isinstance(chunks, int) and not isinstance(chunks, bool):
        chunks = (chunks,)
    if isinstance(chunks, tuple) and any(
        chunk > dim for dim, chunk in zip(tmp_shape, chunks) if dim is not None
    ):
        errmsg = (
            "Chunk shape must not be greater than data shape in any dimension. "
            f"{chunks} is not compatible with {shape}"
        )
        raise ValueError(errmsg)

    # validate chunks is not False if maxshape or compression is set
    if chunks is False:
        if maxshape is not None:
            raise ValueError("chunks must not be False with extendible datasets")
        if compression is not None:
            raise ValueError("chunks must not be False with compression")

    if chunks and shape is None and (data is None or isinstance(data, Empty)):
        raise TypeError("Chunk layout may not be specified with empty dataset")

    if isinstance(dtype, Datatype):
        # Named types are used as-is
        type_json = dtype.id.type_json
    else:
        # Validate dtype
        if dtype is None and data is None:
            dtype = numpy.dtype("=f4")
        elif data is not None:
            if dtype is None:
                if hasattr(data, "dtype"):
                    dtype = data.dtype
                else:
                    dtype = guess_dtype(data)
            else:
                dtype = numpy.dtype(dtype)
                if dtype.kind == "O" and data.dtype.kind == "O" and not dtype.metadata:
                    # use metadata fields from data.dtype if not set in dtype
                    dtype = data.dtype
                else:
                    pass  # just use given dtype
        else:
            dtype = numpy.dtype(dtype)

        if dtype.kind == "O" and dtype.metadata and "ref" in dtype.metadata:
            type_json = {}
            type_json["class"] = "H5T_REFERENCE"
            meta_type = dtype.metadata["ref"]
            if meta_type is Reference:
                type_json["base"] = "H5T_STD_REF_OBJ"
            elif meta_type is RegionReference:
                type_json["base"] = "H5T_STD_REF_DSETREG"
            else:
                errmsg = "Unexpected metadata type"
                raise ValueError(errmsg)
        else:
            type_json = getTypeItem(dtype)
    body["type"] = type_json

    layout = None
    if chunks is not None and isinstance(chunks, dict):
        # use the given chunk layout
        layout = chunks
        chunks = None

    compressors = parent.id.http_conn.compressors

    # Legacy
    if compression is True:
        if compression_opts is None:
            compression_opts = 4
        compression = "gzip"

    # Legacy
    if compression in _LEGACY_GZIP_COMPRESSION_VALS:
        if compression_opts is not None:
            raise TypeError("Conflict in compression options")
        compression_opts = compression
        compression = "gzip"

    if compression:
        if isinstance(compression, int):
            if compression < 0:
                raise ValueError(f"Invalid filter: {compression}")
            if compression not in range(0, 10):
                raise ValueError(f"Unknown compression: {compression}")
            compression_opts = compression
            compression = "gzip"
        elif compression not in compressors:
            msg = "Unknown compression, expect one of the following "
            msg += f"values: {compressors}"
            raise ValueError(msg)

    dcpl = filters.generate_dcpl(
        shape,
        dtype,
        chunks=chunks,
        compression=compression,
        compression_opts=compression_opts,
        shuffle=shuffle,
        fletcher32=fletcher32,
        maxshape=maxshape,
        scaleoffset=scaleoffset,
        layout=layout,
        initializer=initializer,
        initializer_opts=initializer_opts
    )

    if fillvalue is not None:
        # is it compatible with the array type?
        if fillvalue:
            if hasattr(fillvalue, "tolist"):
                # convert numpy object to list
                fillvalue = fillvalue.tolist()
            fillvalue = _decode(fillvalue)
            if not isinstance(fillvalue, str) and hasattr(fillvalue, "__iter__"):
                # fill value is a list, or similar: check that dtype is compound
                if len(fillvalue) != len(dtype):
                    raise ValueError("Invalid fill value for non-compound type dataset")
                fillvalue = list(fillvalue)
            else:
                if len(dtype) > 1:
                    raise ValueError("Invalid fill value for compound type dataset")

            dcpl["fillValue"] = fillvalue

    if chunks and isinstance(chunks, dict):
        dcpl["layout"] = chunks

    body["creationProperties"] = dcpl

    """
    if track_times in (True, False):
        dcpl.set_obj_track_times(track_times)
    elif track_times is not None:
        raise TypeError("track_times must be either True or False")
    """
    if maxshape is not None and len(maxshape) > 0:
        if shape is not None:
            maxshape = tuple(m if m is not None else 0 for m in maxshape)
            body["maxdims"] = maxshape
        else:
            print("Warning: maxshape provided but no shape")

    req = "/datasets"

    rsp = parent.POST(req, body=body)

    json_rep = {}
    json_rep["id"] = rsp["id"]

    req = "/datasets/" + rsp["id"]
    rsp = parent.GET(req)

    json_rep["shape"] = rsp["shape"]
    json_rep["type"] = rsp["type"]
    json_rep["lastModified"] = rsp["lastModified"]
    if "creationProperties" in rsp:
        json_rep["creationProperties"] = rsp["creationProperties"]
    else:
        json_rep["creationProperties"] = {}
    if "layout" in rsp:
        json_rep["layout"] = rsp["layout"]

    dset_id = DatasetID(parent, json_rep)

    if data is not None:
        # init data
        dset = Dataset(dset_id)
        dset[...] = data

    return dset_id