diff --git a/.pyup.yml b/.pyup.yml index 0c85ee8e03..04937ed0b0 100644 --- a/.pyup.yml +++ b/.pyup.yml @@ -4,21 +4,15 @@ schedule: every month requirements: - - requirements.txt: - pin: False - update: False - - requirements_test.txt: - pin: False - update: False - - requirements_rtfd.txt: - pin: False - update: False - - requirements_dev.txt: + - requirements_dev_minimal.txt: pin: True update: all - - requirements_dev_npy.txt: + - requirements_dev_numpy.txt: pin: True update: all - requirements_dev_optional.txt: pin: True update: all + - requirements_rtfd.txt: + pin: False + update: False diff --git a/.travis.yml b/.travis.yml index 2c73212d0e..13618a50f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,12 @@ addons: packages: - libdb-dev +env: + global: + - ZARR_TEST_ABS=1 + - ZARR_TEST_MONGO=1 + - ZARR_TEST_REDIS=1 + services: - docker - redis-server diff --git a/appveyor.yml b/appveyor.yml index d04417d671..45c5a8af7a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ environment: # See: http://stackoverflow.com/a/13751649/163740 CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\build.cmd" EMULATOR_LOC: C:\\Program Files (x86)\\Microsoft SDKs\\Azure\\Storage Emulator\\AzureStorageEmulator.exe + ZARR_TEST_ABS: 1 matrix: @@ -33,9 +34,7 @@ environment: install: - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - "%CMD_IN_ENV% python -m pip install -U pip setuptools wheel" - - "%CMD_IN_ENV% python -m pip install -rrequirements_test.txt" - - "%CMD_IN_ENV% python -m pip install -rrequirements_dev_npy.txt" - - "%CMD_IN_ENV% python -m pip install --no-binary=numcodecs -rrequirements_dev.txt" + - "%CMD_IN_ENV% python -m pip install -r requirements_dev_numpy.txt -r requirements_dev_minimal.txt -r requirements_dev_optional.txt" - "%CMD_IN_ENV% python setup.py install" - "%CMD_IN_ENV% python -m pip freeze" @@ -43,6 +42,7 @@ build: off before_test: - '"%EMULATOR_LOC%" start' + - '"%EMULATOR_LOC%" status' test_script: - "%CMD_IN_ENV% python -m pytest -v --pyargs zarr" diff --git a/docs/contributing.rst b/docs/contributing.rst index af897d1963..e0c2ca5d88 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -90,10 +90,9 @@ you have cloned the Zarr source code and your current working directory is the r the repository, you can do something like the following:: $ mkdir -p ~/pyenv/zarr-dev - $ virtualenv --no-site-packages --python=/usr/bin/python3.6 ~/pyenv/zarr-dev + $ virtualenv --no-site-packages --python=/usr/bin/python3.7 ~/pyenv/zarr-dev $ source ~/pyenv/zarr-dev/bin/activate - $ pip install -r requirements_dev.txt - $ pip install -r requirements_dev_optional.txt + $ pip install -r requirements_dev_minimal.txt -r requirements_dev_numpy.txt $ pip install -e . To verify that your development environment is working, you can run the unit tests:: @@ -139,34 +138,44 @@ Again, any conflicts need to be resolved before submitting a pull request. Running the test suite ~~~~~~~~~~~~~~~~~~~~~~ -Zarr includes a suite of unit tests, as well as doctests included in function and class -docstrings and in the tutorial and storage spec. The simplest way to run the unit tests -is to invoke:: +Zarr includes a suite of unit tests, as well as doctests included in +function and class docstrings and in the tutorial and storage +spec. The simplest way to run the unit tests is to activate your +development environment (see `creating a development environment`_ above) +and invoke:: $ pytest -v zarr -To also run the doctests within docstrings, run:: - - $ pytest -v --doctest-modules zarr +Some tests require optional dependencies to be installed, otherwise +the tests will be skipped. To install all optional dependencies, run:: -To run the doctests within the tutorial and storage spec, run:: + $ pip install -r requirements_dev_optional.txt - $ python -m doctest -o NORMALIZE_WHITESPACE -o ELLIPSIS docs/tutorial.rst docs/spec/v2.rst +To also run the doctests within docstrings (requires optional +depencies to be installed), run:: -Tests can be run under different Python versions using tox. E.g. (assuming you have the -corresponding Python interpreters installed on your system):: + $ pytest -v --doctest-plus zarr - $ tox -e py27,py34,py35,py36 +To run the doctests within the tutorial and storage spec (requires +optional dependencies to be installed), run:: -Zarr currently supports Python 2.7 and Python 3.4-3.6, so the above command must -succeed before code can be accepted into the main code base. Note that only the py36 -tox environment runs the doctests, i.e., doctests only need to succeed under Python 3.6. + $ python -m doctest -o NORMALIZE_WHITESPACE -o ELLIPSIS docs/tutorial.rst docs/spec/v2.rst -All tests are automatically run via Travis (Linux) and AppVeyor (Windows) continuous -integration services for every pull request. Tests must pass under both services before -code can be accepted. Test coverage is also collected automatically via the Coveralls -service, and total coverage over all builds must be 100% (although individual builds -may be lower due to Python 2/3 or other differences). +Note that some tests also require storage services to be running +locally. To run the Azure Blob Service storage tests, run an Azure +storage emulator (e.g., azurite) and set the environment variable +``ZARR_TEST_ABS=1``. To run the Mongo DB storage tests, run a Mongo +server locally and set the environment variable ``ZARR_TEST_MONGO=1``. +To run the Redis storage tests, run a Redis server locally on port +6379 and set the environment variable ``ZARR_TEST_REDIS=1``. + +All tests are automatically run via Travis (Linux) and AppVeyor +(Windows) continuous integration services for every pull +request. Tests must pass under both Travis and Appveyor before code +can be accepted. Test coverage is also collected automatically via the +Coveralls service, and total coverage over all builds must be 100% +(although individual builds may be lower due to Python 2/3 or other +differences). Code standards ~~~~~~~~~~~~~~ @@ -177,8 +186,6 @@ Conformance can be checked by running:: $ flake8 --max-line-length=100 zarr -This is automatically run when invoking ``tox -e py36``. - Test coverage ~~~~~~~~~~~~~ @@ -195,10 +202,15 @@ request. Coveralls coverage must also be 100% before code can be accepted. Documentation ~~~~~~~~~~~~~ -Docstrings for user-facing classes and functions should follow the `numpydoc -`_ standard, -including sections for Parameters and Examples. All examples should run and pass as doctests -under Python 3.6 only. +Docstrings for user-facing classes and functions should follow the +`numpydoc +`_ +standard, including sections for Parameters and Examples. All examples +should run and pass as doctests under Python 3.7. To run doctests, +activate your development environment, install optional requirements, +and run:: + + $ pytest -v --doctest-plus zarr Zarr uses Sphinx for documentation, hosted on readthedocs.org. Documentation is written in the RestructuredText markup language (.rst files) in the ``docs`` folder. @@ -208,7 +220,7 @@ folder. Any new features or important usage information should be included in th tutorial (``docs/tutorial.rst``). Any changes should also be included in the release notes (``docs/release.rst``). -The documentation can be built by running:: +The documentation can be built locally by running:: $ tox -e docs diff --git a/docs/release.rst b/docs/release.rst index 8626ace746..84a6e0853d 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -6,11 +6,14 @@ Upcoming Release * Use uniform chunking for all dimensions when specifying ``chunks`` as an integer. Also adds support for specifying ``-1`` to chunk across an entire dimension. - By :user:`James Bourbeau `; :issue:`456` + By :user:`James Bourbeau `; :issue:`456`. * Rename ``DictStore`` to ``MemoryStore``. - By :user:`James Bourbeau `; :issue:`455` + By :user:`James Bourbeau `; :issue:`455`. +* Upgrade dependencies in the test matrices and resolve a + compatibility issue with testing against the Azure Storage + Emulator. By :user:`alimanfoo`; :issue:`468`, :issue:`467`. .. _release_2.3.2: @@ -21,19 +24,19 @@ Enhancements ~~~~~~~~~~~~ * Use ``scandir`` in ``DirectoryStore``'s ``getsize`` method. - By :user:`John Kirkham `; :issue:`431` + By :user:`John Kirkham `; :issue:`431`. Bug fixes ~~~~~~~~~ * Add and use utility functions to simplify reading and writing JSON. - By :user:`John Kirkham `; :issue:`429`, :issue:`430` + By :user:`John Kirkham `; :issue:`429`, :issue:`430`. * Fix ``collections``'s ``DeprecationWarning``\ s. - By :user:`John Kirkham `; :issue:`432` + By :user:`John Kirkham `; :issue:`432`. * Fix tests on big endian machines. - By :user:`Elliott Sales de Andrade `; :issue:`427` + By :user:`Elliott Sales de Andrade `; :issue:`427`. .. _release_2.3.1: diff --git a/docs/tutorial.rst b/docs/tutorial.rst index 09f6e4ae2d..b6f239d71d 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -806,10 +806,10 @@ The class is :class:`zarr.storage.ABSStore` (requires `azure-storage-blob `_ to be installed):: - >>> store = zarr.ABSStore(container='test', prefix='zarr-testing', blob_service_kwargs={'is_emulated': True}) - >>> root = zarr.group(store=store, overwrite=True) - >>> z = root.zeros('foo/bar', shape=(1000, 1000), chunks=(100, 100), dtype='i4') - >>> z[:] = 42 + >>> store = zarr.ABSStore(container='test', prefix='zarr-testing', blob_service_kwargs={'is_emulated': True}) # doctest: +SKIP + >>> root = zarr.group(store=store, overwrite=True) # doctest: +SKIP + >>> z = root.zeros('foo/bar', shape=(1000, 1000), chunks=(100, 100), dtype='i4') # doctest: +SKIP + >>> z[:] = 42 # doctest: +SKIP When using an actual storage account, provide ``account_name`` and ``account_key`` arguments to :class:`zarr.storage.ABSStore`, the diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e035a2fc72..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -asciitree -fasteners -numcodecs -numpy -pytest -pyosreplace; python_version < '3.3' and sys.platform == 'win32' diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index 957edac387..0000000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,4 +0,0 @@ -asciitree==0.3.3 -fasteners==0.14.1 -numcodecs==0.6.2 -pyosreplace==0.1; python_version < '3.3' and sys.platform == 'win32' diff --git a/requirements_dev_minimal.txt b/requirements_dev_minimal.txt new file mode 100644 index 0000000000..7a89c04bd6 --- /dev/null +++ b/requirements_dev_minimal.txt @@ -0,0 +1,9 @@ +# library requirements +asciitree==0.3.3 +fasteners==0.15 +numcodecs==0.6.3 +msgpack-python==0.5.6 +setuptools-scm==3.3.3 +# test requirements +pytest==5.0.1; python_version > '3.0' +pytest==4.6.5; python_version < '3.0' diff --git a/requirements_dev_npy.txt b/requirements_dev_numpy.txt similarity index 65% rename from requirements_dev_npy.txt rename to requirements_dev_numpy.txt index 78b80223e2..1dd7939972 100644 --- a/requirements_dev_npy.txt +++ b/requirements_dev_numpy.txt @@ -1,4 +1,5 @@ # Break this out into a separate file to allow testing against # different versions of numpy. This file should pin to the latest # numpy version. -numpy==1.15.4 +numpy==1.17.0; python_version > '3.0' +numpy==1.16.4; python_version < '3.0' diff --git a/requirements_dev_optional.txt b/requirements_dev_optional.txt index 2e4feddce0..3df1f1e3c0 100644 --- a/requirements_dev_optional.txt +++ b/requirements_dev_optional.txt @@ -1,5 +1,17 @@ -# These packages are currently not available on Windows. -bsddb3==6.2.6 -lmdb==0.94 -redis==3.0.1 -pymongo==3.7.1 \ No newline at end of file +# optional library requirements +bsddb3==6.2.6; sys_platform != 'win32' +lmdb==0.97; sys_platform != 'win32' +# optional library requirements for services +azure-storage-blob==2.0.1 +redis==3.3.6 +pymongo==3.8.0 +# optional test requirements +tox==3.13.2 +coverage==4.5.4 +coveralls==1.8.2 +flake8==3.7.8 +pytest-cov==2.7.1 +pytest-doctestplus==0.3.0 +pytest-remotedata==0.3.2 +h5py==2.9.0 +s3fs==0.3.3; python_version > '3.0' diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100644 index 1492a673c1..0000000000 --- a/requirements_test.txt +++ /dev/null @@ -1,12 +0,0 @@ -coverage -coveralls -cython -flake8 -h5py -msgpack-python -pytest -pytest-cov -s3fs -setuptools-scm -tox -azure-storage-blob diff --git a/tox.ini b/tox.ini index 29303876a6..2a466b8731 100644 --- a/tox.ini +++ b/tox.ini @@ -4,9 +4,7 @@ # and then run "tox" from this directory. [tox] -# N.B., test different versions of numpy under py36 rather than py37 -# because wheels for npy113 not available for py37 -envlist = py27, py35, py36-npy{113,114,115}, py37, docs +envlist = py27, py35, py36, py37-npy{115,116,latest}, docs [testenv] install_command = pip install --no-binary=numcodecs {opts} {packages} @@ -15,35 +13,37 @@ setenv = # hooks for coverage exclusions based on Python major version py35,py36,py37: PY_MAJOR_VERSION = py3 py27: PY_MAJOR_VERSION = py2 +passenv = + ZARR_TEST_ABS + ZARR_TEST_MONGO + ZARR_TEST_REDIS commands = # clear out any data files generated during tests python -c 'import glob; import shutil; import os; [(shutil.rmtree(d) if os.path.isdir(d) else os.remove(d) if os.path.isfile(d) else None) for d in glob.glob("./example*")]' # main unit test runner - # N.B., don't run npy113 or npy114 with coverage because it is run together npy115 on travis - py27,py35,py36-npy115: pytest -v --cov=zarr --cov-config=.coveragerc zarr - py36-npy113: pytest -v zarr - py36-npy114: pytest -v zarr - py37: pytest -v --cov=zarr --cov-config=.coveragerc --doctest-modules zarr - # generate a coverate report - py27,py35,py36-npy115,py37: coverage report -m + py27,py35,py36: pytest -v --cov=zarr --cov-config=.coveragerc zarr + # don't collect coverage when running older numpy versions + py37-{npy115,npy116}: pytest -v zarr + # collect coverage and run doctests under py37 + py37-npylatest: pytest -v --cov=zarr --cov-config=.coveragerc --doctest-plus zarr --remote-data + # generate a coverage report + py27,py35,py36,py37-npylatest: coverage report -m # run doctests in the tutorial and spec - py37: python -m doctest -o NORMALIZE_WHITESPACE -o ELLIPSIS docs/tutorial.rst docs/spec/v2.rst + py37-npylatest: python -m doctest -o NORMALIZE_WHITESPACE -o ELLIPSIS docs/tutorial.rst docs/spec/v2.rst # pep8 checks - py37: flake8 zarr + py37-npylatest: flake8 zarr # print environment for debugging pip freeze deps = py27: backports.lzma - py36-npy113: numpy==1.13.3 - py36-npy114: numpy==1.14.6 - py27,py35,py36-npy115,py37: -rrequirements_dev_npy.txt - -rrequirements_test.txt - -rrequirements_dev.txt - # linux only + py37-npy115: numpy==1.15.4 + py37-npy116: numpy==1.16.4 + py27,py35,py36,py37-npylatest: -rrequirements_dev_numpy.txt + -rrequirements_dev_minimal.txt -rrequirements_dev_optional.txt [testenv:docs] -basepython = python2.7 +basepython = python3.6 changedir = docs deps = -rrequirements_rtfd.txt diff --git a/zarr/indexing.py b/zarr/indexing.py index 0cd116bc37..988489e0bb 100644 --- a/zarr/indexing.py +++ b/zarr/indexing.py @@ -693,7 +693,11 @@ def __init__(self, selection, array): self.chunk_rixs = np.nonzero(self.chunk_nitems)[0] # unravel chunk indices - self.chunk_mixs = np.unravel_index(self.chunk_rixs, dims=array._cdata_shape) + if tuple(map(int, np.__version__.split('.')[:2])) < (1, 16): + self.chunk_mixs = np.unravel_index(self.chunk_rixs, dims=array._cdata_shape) + else: + # deal with change dims->shape in arguments as of numpy 1.16 + self.chunk_mixs = np.unravel_index(self.chunk_rixs, shape=array._cdata_shape) def __iter__(self): diff --git a/zarr/storage.py b/zarr/storage.py index 9e608da0d2..03ebdefeac 100644 --- a/zarr/storage.py +++ b/zarr/storage.py @@ -44,6 +44,14 @@ err_fspath_exists_notdir, err_read_only, MetadataError) +__doctest_requires__ = { + ('RedisStore', 'RedisStore.*'): ['redis'], + ('MongoDBStore', 'MongoDBStore.*'): ['pymongo'], + ('ABSStore', 'ABSStore.*'): ['azure.storage.blob'], + ('LRUStoreCache', 'LRUStoreCache.*'): ['s3fs'], +} + + array_meta_key = '.zarray' group_meta_key = '.zgroup' attrs_key = '.zattrs' @@ -1099,8 +1107,10 @@ class also supports the context manager protocol, which ensures the ``close()`` >>> store = zarr.ZipStore('data/example.zip', mode='w') >>> z = zarr.zeros(100, chunks=10, store=store) - >>> z[...] = 42 # first write OK - >>> z[...] = 42 # second write generates warnings + >>> # first write OK + ... z[...] = 42 + >>> # second write generates warnings + ... z[...] = 42 # doctest: +SKIP >>> store.close() This can also happen in a more subtle situation, where data are written only @@ -1110,7 +1120,8 @@ class also supports the context manager protocol, which ensures the ``close()`` >>> store = zarr.ZipStore('data/example.zip', mode='w') >>> z = zarr.zeros(100, chunks=10, store=store) >>> z[5:15] = 42 - >>> z[15:25] = 42 # write overlaps chunk previously written, generates warnings + >>> # write overlaps chunk previously written, generates warnings + ... z[15:25] = 42 # doctest: +SKIP To avoid creating duplicate entries, only write data once, and align writes with chunk boundaries. This alignment is done automatically if you call @@ -1729,8 +1740,8 @@ class LRUStoreCache(MutableMapping): >>> s3 = s3fs.S3FileSystem(anon=True, client_kwargs=dict(region_name='eu-west-2')) >>> store = s3fs.S3Map(root='zarr-demo/store', s3=s3, check=False) >>> cache = zarr.LRUStoreCache(store, max_size=2**28) - >>> root = zarr.group(store=cache) - >>> z = root['foo/bar/baz'] + >>> root = zarr.group(store=cache) # doctest: +REMOTE_DATA + >>> z = root['foo/bar/baz'] # doctest: +REMOTE_DATA >>> from timeit import timeit >>> # first data access is relatively slow, retrieved from store ... timeit('print(z[:].tostring())', number=1, globals=globals()) # doctest: +SKIP @@ -2257,25 +2268,6 @@ class MongoDBStore(MutableMapping): **kwargs Keyword arguments passed through to the `pymongo.MongoClient` function. - Examples - -------- - Store a single array:: - - >>> import zarr - >>> store = zarr.MongoDBStore('localhost') - >>> z = zarr.zeros((10, 10), chunks=(5, 5), store=store, overwrite=True) - >>> z[...] = 42 - >>> store.close() - - Store a group:: - - >>> store = zarr.MongoDBStore('localhost') - >>> root = zarr.group(store=store, overwrite=True) - >>> foo = root.create_group('foo') - >>> bar = foo.zeros('bar', shape=(10, 10), chunks=(5, 5)) - >>> bar[...] = 42 - >>> store.close() - Notes ----- The maximum chunksize in MongoDB documents is 16 MB. @@ -2354,23 +2346,6 @@ class RedisStore(MutableMapping): **kwargs Keyword arguments passed through to the `redis.Redis` function. - Examples - -------- - Store a single array:: - - >>> import zarr - >>> store = zarr.RedisStore(port=6379) - >>> z = zarr.zeros((10, 10), chunks=(5, 5), store=store, overwrite=True) - >>> z[...] = 42 - - Store a group:: - - >>> store = zarr.RedisStore(port=6379) - >>> root = zarr.group(store=store, overwrite=True) - >>> foo = root.create_group('foo') - >>> bar = foo.zeros('bar', shape=(10, 10), chunks=(5, 5)) - >>> bar[...] = 42 - """ def __init__(self, prefix='zarr', **kwargs): import redis diff --git a/zarr/tests/test_core.py b/zarr/tests/test_core.py index 7fb905198f..43daca9f03 100644 --- a/zarr/tests/test_core.py +++ b/zarr/tests/test_core.py @@ -34,6 +34,11 @@ from numcodecs.tests.common import greetings +# also check for environment variables indicating whether tests requiring +# services should be run +ZARR_TEST_ABS = os.environ.get('ZARR_TEST_ABS', '0') + + # needed for PY2/PY3 consistent behaviour if PY2: # pragma: py3 no cover warnings.resetwarnings() @@ -1412,8 +1417,9 @@ def test_nbytes_stored(self): assert expect_nbytes_stored == z.nbytes_stored -@pytest.mark.skipif(asb is None, - reason="azure-blob-storage could not be imported") +@pytest.mark.skipif(asb is None or ZARR_TEST_ABS == '0', + reason="azure-blob-storage could not be imported or tests not" + "enabled via environment variable") class TestArrayWithABSStore(TestArray): @staticmethod diff --git a/zarr/tests/test_hierarchy.py b/zarr/tests/test_hierarchy.py index 30bcd484cf..546e2ab93f 100644 --- a/zarr/tests/test_hierarchy.py +++ b/zarr/tests/test_hierarchy.py @@ -34,6 +34,11 @@ from numcodecs import Zlib +# also check for environment variables indicating whether tests requiring +# services should be run +ZARR_TEST_ABS = os.environ.get('ZARR_TEST_ABS', '0') + + # needed for PY2/PY3 consistent behaviour if PY2: # pragma: py3 no cover warnings.resetwarnings() @@ -869,8 +874,9 @@ def create_store(): return store, None -@pytest.mark.skipif(asb is None, - reason="azure-blob-storage could not be imported") +@pytest.mark.skipif(asb is None or ZARR_TEST_ABS == '0', + reason="azure-blob-storage could not be imported or tests not enabled" + "via environment variable") class TestGroupWithABSStore(TestGroup): @staticmethod diff --git a/zarr/tests/test_storage.py b/zarr/tests/test_storage.py index b21341c464..a713acaf8a 100644 --- a/zarr/tests/test_storage.py +++ b/zarr/tests/test_storage.py @@ -16,11 +16,25 @@ from numpy.testing import assert_array_equal, assert_array_almost_equal import pytest +try: + import sqlite3 +except ImportError: # pragma: no cover + sqlite3 = None + try: import azure.storage.blob as asb except ImportError: # pragma: no cover asb = None +try: + import pymongo +except ImportError: # pragma: no cover + pymongo = None + +try: + import redis +except ImportError: # pragma: no cover + redis = None from zarr.storage import (init_array, array_meta_key, attrs_key, DictStore, MemoryStore, DirectoryStore, ZipStore, init_group, group_meta_key, @@ -43,6 +57,13 @@ LZMA = None +# also check for environment variables indicating whether tests requiring +# services should be run +ZARR_TEST_ABS = os.environ.get('ZARR_TEST_ABS', '0') +ZARR_TEST_MONGO = os.environ.get('ZARR_TEST_MONGO', '0') +ZARR_TEST_REDIS = os.environ.get('ZARR_TEST_REDIS', '0') + + @contextmanager def does_not_raise(): yield @@ -984,7 +1005,7 @@ def create_store(self): gdbm = None -@unittest.skipIf(gdbm is None, 'gdbm is not installed') +@unittest.skipIf(gdbm is None, reason='gdbm is not installed') class TestDBMStoreGnu(TestDBMStore): def create_store(self): @@ -1000,7 +1021,7 @@ def create_store(self): except ImportError: # pragma: no cover ndbm = None - @unittest.skipIf(ndbm is None, 'ndbm is not installed') + @unittest.skipIf(ndbm is None, reason='ndbm is not installed') class TestDBMStoreNDBM(TestDBMStore): def create_store(self): @@ -1016,7 +1037,7 @@ def create_store(self): bsddb3 = None -@unittest.skipIf(bsddb3 is None, 'bsddb3 is not installed') +@unittest.skipIf(bsddb3 is None, reason='bsddb3 is not installed') class TestDBMStoreBerkeleyDB(TestDBMStore): def create_store(self): @@ -1032,7 +1053,7 @@ def create_store(self): lmdb = None -@unittest.skipIf(lmdb is None, 'lmdb is not installed') +@unittest.skipIf(lmdb is None, reason='lmdb is not installed') class TestLMDBStore(StoreTests, unittest.TestCase): def create_store(self): @@ -1054,36 +1075,7 @@ def test_context_manager(self): assert 2 == len(store) -try: - import sqlite3 -except ImportError: # pragma: no cover - sqlite3 = None - -try: - import pymongo - from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError - try: - client = pymongo.MongoClient(host='127.0.0.1', - serverSelectionTimeoutMS=1e3) - client.server_info() - except (ConnectionFailure, ServerSelectionTimeoutError): # pragma: no cover - pymongo = None -except ImportError: # pragma: no cover - pymongo = None - -try: - import redis - from redis import ConnectionError - try: - rs = redis.Redis("localhost", port=6379) - rs.ping() - except ConnectionError: # pragma: no cover - redis = None -except ImportError: # pragma: no cover - redis = None - - -@unittest.skipIf(sqlite3 is None, 'python built without sqlite') +@unittest.skipIf(sqlite3 is None, reason='python built without sqlite') class TestSQLiteStore(StoreTests, unittest.TestCase): def create_store(self): @@ -1093,7 +1085,7 @@ def create_store(self): return store -@unittest.skipIf(sqlite3 is None, 'python built without sqlite') +@unittest.skipIf(sqlite3 is None, reason='python built without sqlite') class TestSQLiteStoreInMemory(TestSQLiteStore, unittest.TestCase): def create_store(self): @@ -1112,7 +1104,9 @@ def test_pickle(self): pickle.dumps(store) -@unittest.skipIf(pymongo is None, 'test requires pymongo') +@unittest.skipIf(pymongo is None or ZARR_TEST_MONGO == '0', + reason='pymongo client library not installed or tests not enabled' + 'via environment variable') class TestMongoDBStore(StoreTests, unittest.TestCase): def create_store(self): @@ -1123,7 +1117,9 @@ def create_store(self): return store -@unittest.skipIf(redis is None, 'test requires redis') +@unittest.skipIf(redis is None or ZARR_TEST_REDIS == '0', + reason='redis client library not installed or tests not enabled' + 'via environment variable') class TestRedisStore(StoreTests, unittest.TestCase): def create_store(self): @@ -1529,8 +1525,9 @@ def test_format_compatibility(): assert compressor.get_config() == z.compressor.get_config() -@pytest.mark.skipif(asb is None, - reason="azure-blob-storage could not be imported") +@pytest.mark.skipif(asb is None or ZARR_TEST_ABS == '0', + reason='azure blob storage client library not available or tests ' + 'not enabled via environment variable') class TestABSStore(StoreTests, unittest.TestCase): def create_store(self):