Repository: zarr-developers/zarr-python

Issue:
Modify fill_value on existing arrays
There is currently no way to chance the fill_value on an existing array (without hacking the metadata). We allow existing arrays to be resized. Why not allow to change the fill_value?

Discussion:
pep8speaks: Hello @Carreau! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:



* In the file [`zarr/tests/test_storage.py`](https://github.com/zarr-developers/zarr-python/blob/7dbc924b63d579defed553ba8312185caa60c041/zarr/tests/test_storage.py):

> [Line 1885:1](https://github.com/zarr-developers/zarr-python/blob/7dbc924b63d579defed553ba8312185caa60c041/zarr/tests/test_storage.py#L1885): [E266](https://duckduckgo.com/?q=pep8%20E266) too many leading '#' for block comment


joshmoore: Closing and re-opening to move from travis to GHA.
rabernat: Thanks for keeping this alive! It's a small but valuable feature request.
joshmoore: Fixed a minor issue in the test. Let's see if it goes green.
codecov[bot]: # [Codecov](https://codecov.io/gh/zarr-developers/zarr-python/pull/665?src=pr&el=h1) Report
> Merging [#665](https://codecov.io/gh/zarr-developers/zarr-python/pull/665?src=pr&el=desc) (120ef18) into [master](https://codecov.io/gh/zarr-developers/zarr-python/commit/23422fc463722023e4d6e9594fee9ec274c2879d?el=desc) (23422fc) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##           master     #665   +/-   ##
=======================================
  Coverage   99.94%   99.94%           
=======================================
  Files          28       28           
  Lines       10263    10274   +11     
=======================================
+ Hits        10257    10268   +11     
  Misses          6        6           
```

| [Impacted Files](https://codecov.io/gh/zarr-developers/zarr-python/pull/665?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [zarr/core.py](https://codecov.io/gh/zarr-developers/zarr-python/pull/665/diff?src=pr&el=tree#diff-emFyci9jb3JlLnB5) | `100.00% <100.00%> (ø)` | |
| [zarr/tests/test\_storage.py](https://codecov.io/gh/zarr-developers/zarr-python/pull/665/diff?src=pr&el=tree#diff-emFyci90ZXN0cy90ZXN0X3N0b3JhZ2UucHk=) | `100.00% <100.00%> (ø)` | |

joshmoore: @rabernat : Green. You want to do the review honors then?
joshmoore: Rebased and solved merge conflicts.

Patch:
diff --git a/docs/release.rst b/docs/release.rst
index d0aed556..801dcbe8 100644
--- a/docs/release.rst
+++ b/docs/release.rst
@@ -9,6 +9,8 @@ Unreleased
 Enhancements
 ~~~~~~~~~~~~
 
+* Allow to assign array ``fill_values`` and update metadata accordingly. :issue:`662`
+
 * array indexing with [] (getitem and setitem) now supports fancy indexing.
   By :user:`Juan Nunez-Iglesias <jni>`; :issue:`725`.
 
diff --git a/zarr/core.py b/zarr/core.py
index d3661394..029b3c1a 100644
--- a/zarr/core.py
+++ b/zarr/core.py
@@ -347,6 +347,11 @@ class Array:
         """A value used for uninitialized portions of the array."""
         return self._fill_value
 
+    @fill_value.setter
+    def fill_value(self, new):
+        self._fill_value = new
+        self._flush_metadata_nosync()
+
     @property
     def order(self):
         """A string indicating the order in which bytes are arranged within


Test patch:
diff --git a/zarr/tests/test_storage.py b/zarr/tests/test_storage.py
index 3438e606..0b1b00eb 100644
--- a/zarr/tests/test_storage.py
+++ b/zarr/tests/test_storage.py
@@ -17,6 +17,7 @@ from numpy.testing import assert_array_almost_equal, assert_array_equal
 
 from numcodecs.compat import ensure_bytes
 
+import zarr
 from zarr.codecs import BZ2, AsType, Blosc, Zlib
 from zarr.errors import MetadataError
 from zarr.hierarchy import group
@@ -2187,4 +2188,19 @@ class TestConsolidatedMetadataStore:
         with pytest.raises(PermissionError):
             cs['bar'] = 0
         with pytest.raises(PermissionError):
-            cs['spam'] = 'eggs'
+            cs["spam"] = "eggs"
+
+
+# standalone test we do not want to run on each store.
+
+
+def test_fill_value_change():
+    a = zarr.create((10, 10), dtype=int)
+
+    assert a[0, 0] == 0
+
+    a.fill_value = 1
+
+    assert a[0, 0] == 1
+
+    assert json.loads(a.store[".zarray"])["fill_value"] == 1