Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/pip/numpy-1.26.1
Browse files Browse the repository at this point in the history
  • Loading branch information
d-v-b authored Dec 21, 2023
2 parents a25fae5 + b5f79dd commit 9089490
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 59 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -56,7 +56,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
Expand All @@ -69,4 +69,4 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
2 changes: 1 addition & 1 deletion .github/workflows/releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
submodules: true
fetch-depth: 0

- uses: actions/setup-python@v4.7.1
- uses: actions/setup-python@v5.0.0
name: Install Python
with:
python-version: '3.8'
Expand Down
15 changes: 6 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,25 @@ default_stages: [commit, push]
default_language_version:
python: python3
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.0.224'
rev: 'v0.1.8'
hooks:
- id: ruff
# Respect `exclude` and `extend-exclude` settings.
args: ["--force-exclude"]
- repo: https://github.com/psf/black
rev: 23.10.1
rev: 23.12.0
hooks:
- id: black
- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
rev: v2.2.6
hooks:
- id: codespell
args: ["-L", "ba,ihs,kake,nd,noe,nwo,te,fo,zar", "-S", "fixture"]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-yaml
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
rev: v1.7.1
hooks:
- id: mypy
files: zarr
Expand Down
6 changes: 6 additions & 0 deletions docs/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Release notes
Unreleased
----------

Enhancements
~~~~~~~~~~~~

* Added type hints to ``zarr.creation.create()``.
By :user:`David Stansby <dstansby>` :issue:`1536`.

Docs
~~~~

Expand Down
11 changes: 9 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Homepage = "https://github.com/zarr-developers/zarr-python"
exclude_lines = [
"pragma: no cover",
"pragma: ${PY_MAJOR_VERSION} no cover",
'.*\.\.\.' # Ignore "..." lines
]

[tool.coverage.run]
Expand Down Expand Up @@ -119,9 +120,10 @@ exclude = '''
'''

[tool.mypy]
python_version = "3.8"
ignore_missing_imports = true
follow_imports = "silent"
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true

[tool.pytest.ini_options]
doctest_optionflags = [
Expand All @@ -137,3 +139,8 @@ filterwarnings = [
"ignore:PY_SSIZE_T_CLEAN will be required.*:DeprecationWarning",
"ignore:The loop argument is deprecated since Python 3.8.*:DeprecationWarning",
]


[tool.codespell]
ignore-words-list = "ba,ihs,kake,nd,noe,nwo,te,fo,zar"
skip = 'fixture,.git'
4 changes: 2 additions & 2 deletions requirements_dev_optional.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ pytest-cov==4.1.0
pytest-doctestplus==1.0.0
pytest-timeout==2.2.0
h5py==3.10.0
fsspec==2023.10.0
s3fs==2023.10.0
fsspec==2023.12.1
s3fs==2023.12.1
moto[server]>=4.0.8
7 changes: 4 additions & 3 deletions zarr/_storage/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from zarr.meta import Metadata2, Metadata3
from zarr.util import normalize_storage_path
from zarr.context import Context
from zarr.types import ZARR_VERSION

# v2 store keys
array_meta_key = ".zarray"
Expand All @@ -19,7 +20,7 @@
meta_root = "meta/root/"
data_root = "data/root/"

DEFAULT_ZARR_VERSION = 2
DEFAULT_ZARR_VERSION: ZARR_VERSION = 2

v3_api_available = os.environ.get("ZARR_V3_EXPERIMENTAL_API", "0").lower() not in ["0", "false"]

Expand Down Expand Up @@ -641,10 +642,10 @@ def _rmdir_from_keys_v3(store: StoreV3, path: str = "") -> None:
sfx = _get_metadata_suffix(store)
array_meta_file = meta_dir + ".array" + sfx
if array_meta_file in store:
store.erase(array_meta_file) # type: ignore
store.erase(array_meta_file)
group_meta_file = meta_dir + ".group" + sfx
if group_meta_file in store:
store.erase(group_meta_file) # type: ignore
store.erase(group_meta_file)


def _listdir_from_keys(store: BaseStore, path: Optional[str] = None) -> List[str]:
Expand Down
2 changes: 1 addition & 1 deletion zarr/_storage/v3_storage_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def erase_prefix(self, prefix):

def rmdir(self, path=None):
path = normalize_storage_path(path)
_rmdir_from_keys_v3(self, path) # type: ignore
_rmdir_from_keys_v3(self, path)

def __contains__(self, key):
if self._is_data_key(key):
Expand Down
2 changes: 1 addition & 1 deletion zarr/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2536,7 +2536,7 @@ def hexdigest(self, hashname="sha1"):
checksum = binascii.hexlify(self.digest(hashname=hashname))

# This is a bytes object on Python 3 and we want a str.
if type(checksum) is not str:
if not isinstance(checksum, str):
checksum = checksum.decode("utf8")

return checksum
Expand Down
46 changes: 26 additions & 20 deletions zarr/creation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from typing import Optional
from collections.abc import MutableMapping
from typing import Optional, Tuple, Union, Sequence
from warnings import warn

import numpy as np
import numpy.typing as npt
from numcodecs.abc import Codec
from numcodecs.registry import codec_registry

from zarr._storage.store import DEFAULT_ZARR_VERSION
Expand All @@ -19,32 +22,35 @@
normalize_storage_path,
normalize_store_arg,
)
from zarr._storage.store import StorageTransformer
from zarr.sync import Synchronizer
from zarr.types import ZARR_VERSION, DIMENSION_SEPARATOR, MEMORY_ORDER, MetaArray, PathLike
from zarr.util import normalize_dimension_separator


def create(
shape,
chunks=True,
dtype=None,
shape: Union[int, Tuple[int, ...]],
chunks: Union[int, Tuple[int, ...], bool] = True,
dtype: Optional[npt.DTypeLike] = None,
compressor="default",
fill_value: Optional[int] = 0,
order="C",
store=None,
synchronizer=None,
overwrite=False,
path=None,
chunk_store=None,
filters=None,
cache_metadata=True,
cache_attrs=True,
read_only=False,
object_codec=None,
dimension_separator=None,
write_empty_chunks=True,
order: MEMORY_ORDER = "C",
store: Optional[Union[str, MutableMapping]] = None,
synchronizer: Optional[Synchronizer] = None,
overwrite: bool = False,
path: Optional[PathLike] = None,
chunk_store: Optional[MutableMapping] = None,
filters: Optional[Sequence[Codec]] = None,
cache_metadata: bool = True,
cache_attrs: bool = True,
read_only: bool = False,
object_codec: Optional[Codec] = None,
dimension_separator: Optional[DIMENSION_SEPARATOR] = None,
write_empty_chunks: bool = True,
*,
zarr_version=None,
meta_array=None,
storage_transformers=(),
zarr_version: Optional[ZARR_VERSION] = None,
meta_array: Optional[MetaArray] = None,
storage_transformers: Sequence[StorageTransformer] = (),
**kwargs,
):
"""Create an array.
Expand Down
4 changes: 2 additions & 2 deletions zarr/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ def decode_fill_value(cls, v: Any, dtype: np.dtype, object_codec: Any = None) ->
return np.array(v, dtype=dtype)[()]
elif dtype.kind in "c":
v = (
cls.decode_fill_value(v[0], dtype.type().real.dtype), # type: ignore
cls.decode_fill_value(v[1], dtype.type().imag.dtype), # type: ignore
cls.decode_fill_value(v[0], dtype.type().real.dtype),
cls.decode_fill_value(v[1], dtype.type().imag.dtype),
)
v = v[0] + 1j * v[1]
return np.array(v, dtype=dtype)[()]
Expand Down
14 changes: 7 additions & 7 deletions zarr/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from numcodecs.compat import ensure_bytes, ensure_text, ensure_contiguous_ndarray_like
from numcodecs.registry import codec_registry
from zarr.context import Context
from zarr.types import PathLike as Path

from zarr.errors import (
MetadataError,
Expand Down Expand Up @@ -105,7 +106,6 @@
default_compressor = Zlib()


Path = Union[str, bytes, None]
# allow MutableMapping for backwards compatibility
StoreLike = Union[BaseStore, MutableMapping]

Expand Down Expand Up @@ -206,7 +206,7 @@ def rmdir(store: StoreLike, path: Path = None):
store_version = getattr(store, "_store_version", 2)
if hasattr(store, "rmdir") and store.is_erasable(): # type: ignore
# pass through
store.rmdir(path) # type: ignore
store.rmdir(path)
else:
# slow version, delete one key at a time
if store_version == 2:
Expand Down Expand Up @@ -236,7 +236,7 @@ def listdir(store: BaseStore, path: Path = None):
path = normalize_storage_path(path)
if hasattr(store, "listdir"):
# pass through
return store.listdir(path) # type: ignore
return store.listdir(path)
else:
# slow version, iterate through all keys
warnings.warn(
Expand Down Expand Up @@ -289,7 +289,7 @@ def getsize(store: BaseStore, path: Path = None) -> int:
if hasattr(store, "getsize"):
# pass through
path = normalize_storage_path(path)
return store.getsize(path) # type: ignore
return store.getsize(path)
elif isinstance(store, MutableMapping):
return _getsize(store, path)
else:
Expand Down Expand Up @@ -627,7 +627,7 @@ def _init_array_metadata(

key = _prefix_to_array_key(store, _path_to_prefix(path))
if hasattr(store, "_metadata_class"):
store[key] = store._metadata_class.encode_array_metadata(meta) # type: ignore
store[key] = store._metadata_class.encode_array_metadata(meta)
else:
store[key] = encode_array_metadata(meta)

Expand Down Expand Up @@ -730,10 +730,10 @@ def _init_group_metadata(
if store_version == 3:
meta = {"attributes": {}} # type: ignore
else:
meta = {} # type: ignore
meta = {}
key = _prefix_to_group_key(store, _path_to_prefix(path))
if hasattr(store, "_metadata_class"):
store[key] = store._metadata_class.encode_group_metadata(meta) # type: ignore
store[key] = store._metadata_class.encode_group_metadata(meta)
else:
store[key] = encode_group_metadata(meta)

Expand Down
12 changes: 10 additions & 2 deletions zarr/sync.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import os
from collections import defaultdict
from threading import Lock
from typing import Protocol

import fasteners


class ThreadSynchronizer:
class Synchronizer(Protocol):
"""Base class for synchronizers."""

def __getitem__(self, item):
...


class ThreadSynchronizer(Synchronizer):
"""Provides synchronization using thread locks."""

def __init__(self):
Expand All @@ -24,7 +32,7 @@ def __setstate__(self, *args):
self.__init__()


class ProcessSynchronizer:
class ProcessSynchronizer(Synchronizer):
"""Provides synchronization using file locks via the
`fasteners <https://fasteners.readthedocs.io/en/latest/api/inter_process/>`_
package.
Expand Down
8 changes: 5 additions & 3 deletions zarr/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
import pickle
import shutil
from typing import Any, Literal, Optional, Tuple, Union
from typing import Any, Literal, Optional, Tuple, Union, Sequence
import unittest
from itertools import zip_longest
from tempfile import mkdtemp
Expand All @@ -26,6 +26,7 @@
VLenUTF8,
Zlib,
)
from numcodecs.abc import Codec
from numcodecs.compat import ensure_bytes, ensure_ndarray
from numcodecs.tests.common import greetings
from numpy.testing import assert_array_almost_equal, assert_array_equal
Expand Down Expand Up @@ -73,6 +74,7 @@
from zarr.tests.test_storage_v3 import DummyStorageTransfomer
from zarr.util import buffer_size
from zarr.tests.util import abs_container, skip_test_env_var, have_fsspec, mktemp
from zarr.types import DIMENSION_SEPARATOR

# noinspection PyMethodMayBeStatic

Expand All @@ -82,8 +84,8 @@ class TestArray:
root = ""
path = ""
compressor = Zlib(level=1)
filters = None
dimension_separator: Literal["/", ".", None] = None
filters: Optional[Sequence[Codec]] = None
dimension_separator: Optional[DIMENSION_SEPARATOR] = None
cache_metadata = True
cache_attrs = True
partial_decompress: bool = False
Expand Down
13 changes: 13 additions & 0 deletions zarr/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Literal, Protocol, Union

ZARR_VERSION = Literal[2, 3]
DIMENSION_SEPARATOR = Literal[".", "/"]
MEMORY_ORDER = Literal["C", "F"]


PathLike = Union[str, bytes, None]


class MetaArray(Protocol):
def __array_function__(self, func, types, args, kwargs):
...
Loading

0 comments on commit 9089490

Please sign in to comment.