Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/release.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,8 @@ Release notes
Bug fixes
~~~~~~~~~

* Coerce data to text for JSON parsing.
By :user:`John Kirkham <jakirkham>`; :issue:`429`
* Add and use utility functions to simplify reading and writing JSON.
By :user:`John Kirkham <jakirkham>`; :issue:`429`, :issue:`430`


.. _release_2.3.1:
Expand Down
6 changes: 2 additions & 4 deletions zarr/attrs.py
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
from collections import MutableMapping


from zarr.errors import PermissionError
from zarr.meta import parse_metadata
from zarr.util import json_dumps


class Attributes(MutableMapping):
Expand DownExpand Up@@ -113,9 +113,7 @@ def put(self, d):
self._write_op(self._put_nosync, d)

def _put_nosync(self, d):
s = json.dumps(d, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))
self.store[self.key] = s.encode('ascii')
self.store[self.key] = json_dumps(d)
if self.cache:
self._cached_asdict = d

Expand Down
2 changes: 1 addition & 1 deletion zarr/convenience.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1125,7 +1125,7 @@ def is_zarr_key(key):
for key in store if is_zarr_key(key)
}
}
store[metadata_key] = json_dumps(out).encode()
store[metadata_key] = json_dumps(out)
return open_consolidated(store, metadata_key=metadata_key)


Expand Down
32 changes: 4 additions & 28 deletions zarr/meta.py
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
import json
import base64
import codecs


import numpy as np
from numcodecs.compat import ensure_contiguous_ndarray


from zarr.compat import PY2, Mapping, text_type
from zarr.compat import PY2, Mapping
from zarr.errors import MetadataError
from zarr.util import json_dumps, json_loads


ZARR_FORMAT = 2


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': '))


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def parse_metadata(s):

# Here we allow that a store may return an already-parsed metadata object,
Expand DownExpand Up@@ -95,9 +75,7 @@ def encode_array_metadata(meta):
order=meta['order'],
filters=meta['filters'],
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


def encode_dtype(d):
Expand DownExpand Up@@ -142,9 +120,7 @@ def encode_group_metadata(meta=None):
meta = dict(
zarr_format=ZARR_FORMAT,
)
s = json_dumps(meta)
b = s.encode('ascii')
return b
return json_dumps(meta)


FLOAT_FILLS = {
Expand Down
12 changes: 6 additions & 6 deletions zarr/n5.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,14 +71,14 @@ def __getitem__(self, key):
key = key.replace(zarr_group_meta_key, n5_attrs_key)
value = group_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_array_meta_key):

key = key.replace(zarr_array_meta_key, n5_attrs_key)
value = array_metadata_to_zarr(self._load_n5_attrs(key))

return json_dumps(value).encode('ascii')
return json_dumps(value)

elif key.endswith(zarr_attrs_key):

Expand All@@ -88,7 +88,7 @@ def __getitem__(self, key):
if len(value) == 0:
raise KeyError(key)
else:
return json_dumps(value).encode('ascii')
return json_dumps(value)

elif is_chunk_key(key):

Expand All@@ -105,7 +105,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**group_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_array_meta_key):

Expand All@@ -114,7 +114,7 @@ def __setitem__(self, key, value):
n5_attrs = self._load_n5_attrs(key)
n5_attrs.update(**array_metadata_to_n5(json_loads(value)))

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif key.endswith(zarr_attrs_key):

Expand All@@ -135,7 +135,7 @@ def __setitem__(self, key, value):
# add new user attributes
n5_attrs.update(**zarr_attrs)

value = json_dumps(n5_attrs).encode('ascii')
value = json_dumps(n5_attrs)

elif is_chunk_key(key):

Expand Down
5 changes: 2 additions & 3 deletions zarr/storage.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,15 +26,14 @@
import errno
import re
import sys
import json
import multiprocessing
from pickle import PicklingError
from threading import Lock, RLock
import glob
import warnings


from zarr.util import (normalize_shape, normalize_chunks, normalize_order,
from zarr.util import (json_loads, normalize_shape, normalize_chunks, normalize_order,
normalize_storage_path, buffer_size,
normalize_fill_value, nolock, normalize_dtype)
from zarr.meta import encode_array_metadata, encode_group_metadata
Expand DownExpand Up@@ -2458,7 +2457,7 @@ def __init__(self, store, metadata_key='.zmetadata'):
d = store[metadata_key].decode() # pragma: no cover
else: # pragma: no cover
d = store[metadata_key]
meta = json.loads(d)
meta = json_loads(d)

# check format of consolidated metadata
consolidated_format = meta.get('zarr_consolidated_format', None)
Expand Down
22 changes: 21 additions & 1 deletion zarr/util.py
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
from textwrap import TextWrapper, dedent
import codecs
import json
import numbers
import uuid
import inspect
Expand All@@ -9,7 +11,7 @@
from asciitree import BoxStyle, LeftAligned
from asciitree.traversal import Traversal
import numpy as np
from numcodecs.compat import ensure_ndarray
from numcodecs.compat import ensure_ndarray, ensure_contiguous_ndarray
from numcodecs.registry import codec_registry


Expand All@@ -24,6 +26,24 @@
}


def ensure_text_type(s):
if not isinstance(s, text_type):
s = ensure_contiguous_ndarray(s)
s = codecs.decode(s, 'ascii')
return s


def json_dumps(o):
"""Write JSON in a consistent, human-readable way."""
return json.dumps(o, indent=4, sort_keys=True, ensure_ascii=True,
separators=(',', ': ')).encode('ascii')


def json_loads(s):
"""Read JSON in a consistent way."""
return json.loads(ensure_text_type(s))


def normalize_shape(shape):
"""Convenience function to normalize the `shape` argument."""

Expand Down