codecov[bot]: # [Codecov](https://codecov.io/gh/pydata/sparse/pull/315?src=pr&el=h1) Report
> Merging [#315](https://codecov.io/gh/pydata/sparse/pull/315?src=pr&el=desc) into [master](https://codecov.io/gh/pydata/sparse/commit/6a0277959b1ae20d433ebab88334c28866a92a0e?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.


```diff
@@           Coverage Diff           @@
##           master     #315   +/-   ##
=======================================
  Coverage   93.93%   93.93%           
=======================================
  Files          19       19           
  Lines        2308     2308           
=======================================
  Hits         2168     2168           
  Misses        140      140
```



diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 607ba46..e3c2278 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -21,7 +21,7 @@ jobs:
   variables:
     python_version: '3.5'
   pool:
-    vmImage: 'macos-10.13'
+    vmImage: 'macos-10.14'
   steps:
     - template: ci/azure-steps.yml
 - job: Windows
diff --git a/setup.py b/setup.py
index 76f0430..5b02446 100755
--- a/setup.py
+++ b/setup.py
@@ -72,9 +72,7 @@ setup(
         "Tracker": "https://github.com/pydata/sparse/issues",
     },
     entry_points={
-        "numba_extensions": [
-            "init = sparse._numba_extension:_init_extension",
-        ],
+        "numba_extensions": ["init = sparse._numba_extension:_init_extension"]
     },
     python_requires=">=3.5, <4",
 )
diff --git a/sparse/_coo/core.py b/sparse/_coo/core.py
index 66080d3..ebd4766 100644
--- a/sparse/_coo/core.py
+++ b/sparse/_coo/core.py
@@ -445,7 +445,7 @@ class COO(SparseArray, NDArrayOperatorsMixin):  # lgtm [py/missing-equals]
         )
 
     @classmethod
-    def from_iter(cls, x, shape=None, fill_value=None):
+    def from_iter(cls, x, shape=None, fill_value=None, dtype=None):
         """
         Converts an iterable in certain formats to a :obj:`COO` array. See examples
         for details.
@@ -458,6 +458,8 @@ class COO(SparseArray, NDArrayOperatorsMixin):  # lgtm [py/missing-equals]
             The shape of the array.
         fill_value : scalar
             The fill value for this array.
+        dtype : numpy.dtype
+            The dtype of the input array. Inferred from the input if not given.
 
         Returns
         -------
@@ -511,15 +513,15 @@ class COO(SparseArray, NDArrayOperatorsMixin):  # lgtm [py/missing-equals]
         if not x:
             ndim = 0 if shape is None else len(shape)
             coords = np.empty((ndim, 0), dtype=np.uint8)
-            data = np.empty((0,))
+            data = np.empty((0,), dtype=dtype)
             shape = () if shape is None else shape
 
         elif not isinstance(x[0][0], Iterable):
             coords = np.stack(x[1], axis=0)
-            data = np.asarray(x[0])
+            data = np.asarray(x[0], dtype=dtype)
         else:
             coords = np.array([item[0] for item in x]).T
-            data = np.array([item[1] for item in x])
+            data = np.array([item[1] for item in x], dtype=dtype)
 
         if not (
             coords.ndim == 2
diff --git a/sparse/_dok.py b/sparse/_dok.py
index 2ddeeca..5e43df5 100644
--- a/sparse/_dok.py
+++ b/sparse/_dok.py
@@ -386,7 +386,10 @@ class DOK(SparseArray):
 
         if format == "coo" or format is COO:
             return COO.from_iter(
-                self.data, shape=self.shape, fill_value=self.fill_value
+                self.data,
+                shape=self.shape,
+                fill_value=self.fill_value,
+                dtype=self.dtype,
             )
 
         raise NotImplementedError("The given format is not supported.")

DOK to COO conversion: same dtype only when DOK array is not empty
I initialize a `DOK`-array with specific `dtype`,
don't set any value on it and convert it to a `COO`:

``` python
import numpy
import sparse

dok = sparse.DOK(1024, dtype=numpy.uint8)

coo = sparse.COO(dok)
```

The `dtype` of the `DOK` doesn't get applied to the `COO`.
```python
dok.dtype
>>> dtype('uint8')
coo.dtype
>>> dtype('float64')
```

This is only the case when I set a nonzero value on the `DOK` beforehand:

``` python
dok = sparse.DOK(1024, dtype=numpy.uint8)
dok[0] = 1
coo = sparse.COO(dok)

coo.dtype
>>> dtype('uint8')

coo.dtype == dok.dtype
>>> True
```

You might argue that instead I should use `sparse.zeros()` in the first place,
and while I generally agree, I think that the above behaviour is unexpected to me and should probably be changed.
diff --git a/sparse/tests/test_dok.py b/sparse/tests/test_dok.py
index f855f8f..e670684 100644
--- a/sparse/tests/test_dok.py
+++ b/sparse/tests/test_dok.py
@@ -152,3 +152,9 @@ def test_coo_fv_interface():
     assert_eq(s1, s2)
     s3 = sparse.COO(s2)
     assert_eq(s1, s3)
+
+
+def test_empty_dok_dtype():
+    d = sparse.DOK(5, dtype=np.uint8)
+    s = sparse.COO(d)
+    assert s.dtype == d.dtype

pip install -e .[tests]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-black
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
black==22.8.0
certifi==2021.5.30
click==8.0.4
coverage==6.2
dataclasses==0.8
importlib-metadata==4.8.3
iniconfig==1.1.1
llvmlite==0.36.0
mypy-extensions==1.0.0
numba==0.53.1
numpy==1.19.5
packaging==21.3
pathspec==0.9.0
platformdirs==2.4.0
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-black==0.6.0
pytest-cov==4.0.0
scipy==1.5.4
-e git+https://github.com/pydata/sparse.git@6a0277959b1ae20d433ebab88334c28866a92a0e#egg=sparse
toml==0.10.2
tomli==1.2.3
typed-ast==1.5.5
typing_extensions==4.1.1
zipp==3.6.0

name: sparse
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
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_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
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - 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
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - black==22.8.0
      - click==8.0.4
      - coverage==6.2
      - dataclasses==0.8
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - llvmlite==0.36.0
      - mypy-extensions==1.0.0
      - numba==0.53.1
      - numpy==1.19.5
      - packaging==21.3
      - pathspec==0.9.0
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-black==0.6.0
      - pytest-cov==4.0.0
      - scipy==1.5.4
      - toml==0.10.2
      - tomli==1.2.3
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/sparse

sparse/tests/test_dok.py::test_setitem[shape0-index0-0.842180772569558] sparse/tests/test_dok.py::test_setitem[shape1-index1-0.5429294071508498] sparse/tests/test_dok.py::test_setitem[shape3-1-0.7900911302517273] sparse/tests/test_dok.py::test_setitem[shape4-index4-0.21644640426794437] sparse/tests/test_dok.py::test_setitem[shape5-index5-0.08936495800484534] sparse/tests/test_dok.py::test_setitem[shape9-index9-0.14742276583072278] sparse/tests/test_dok.py::test_setitem[shape11-index11-0.5343439183903876] sparse/tests/test_dok.py::test_setitem[shape13-index13-0.7127569474311942] sparse/tests/test_dok.py::test_empty_dok_dtype
sparse/tests/test_dok.py::black sparse/tests/test_dok.py::test_random_shape_nnz[0.1-shape0] sparse/tests/test_dok.py::test_random_shape_nnz[0.1-shape1] sparse/tests/test_dok.py::test_random_shape_nnz[0.1-shape2] sparse/tests/test_dok.py::test_random_shape_nnz[0.3-shape0] sparse/tests/test_dok.py::test_random_shape_nnz[0.3-shape1] sparse/tests/test_dok.py::test_random_shape_nnz[0.3-shape2] sparse/tests/test_dok.py::test_random_shape_nnz[0.5-shape0] sparse/tests/test_dok.py::test_random_shape_nnz[0.5-shape1] sparse/tests/test_dok.py::test_random_shape_nnz[0.5-shape2] sparse/tests/test_dok.py::test_random_shape_nnz[0.7-shape0] sparse/tests/test_dok.py::test_random_shape_nnz[0.7-shape1] sparse/tests/test_dok.py::test_random_shape_nnz[0.7-shape2] sparse/tests/test_dok.py::test_convert_to_coo sparse/tests/test_dok.py::test_convert_from_coo sparse/tests/test_dok.py::test_convert_from_numpy sparse/tests/test_dok.py::test_convert_to_numpy sparse/tests/test_dok.py::test_construct[2-data0] sparse/tests/test_dok.py::test_construct[shape1-data1] sparse/tests/test_dok.py::test_construct[shape2-data2] sparse/tests/test_dok.py::test_getitem[0.1-shape0] sparse/tests/test_dok.py::test_getitem[0.1-shape1] sparse/tests/test_dok.py::test_getitem[0.1-shape2] sparse/tests/test_dok.py::test_getitem[0.3-shape0] sparse/tests/test_dok.py::test_getitem[0.3-shape1] sparse/tests/test_dok.py::test_getitem[0.3-shape2] sparse/tests/test_dok.py::test_getitem[0.5-shape0] sparse/tests/test_dok.py::test_getitem[0.5-shape1] sparse/tests/test_dok.py::test_getitem[0.5-shape2] sparse/tests/test_dok.py::test_getitem[0.7-shape0] sparse/tests/test_dok.py::test_getitem[0.7-shape1] sparse/tests/test_dok.py::test_getitem[0.7-shape2] sparse/tests/test_dok.py::test_setitem[shape2-index2-value2] sparse/tests/test_dok.py::test_setitem[shape6-index6-value6] sparse/tests/test_dok.py::test_setitem[shape7-index7-value7] sparse/tests/test_dok.py::test_setitem[shape8-index8-value8] sparse/tests/test_dok.py::test_setitem[shape10-index10-value10] sparse/tests/test_dok.py::test_setitem[shape12-index12-value12] sparse/tests/test_dok.py::test_default_dtype sparse/tests/test_dok.py::test_int_dtype sparse/tests/test_dok.py::test_float_dtype sparse/tests/test_dok.py::test_set_zero sparse/tests/test_dok.py::test_asformat[coo] sparse/tests/test_dok.py::test_asformat[dok] sparse/tests/test_dok.py::test_coo_fv_interface
setup.py sparse/_coo/core.py sparse/_dok.py azure-pipelines.yml
setup.py sparse/_coo/core.py sparse/_dok.py azure-pipelines.yml