diff --git a/.circleci/config.yml b/.circleci/config.yml index 96a6a06fa..aae6c58f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,13 +38,6 @@ references: username: hdmf password: $DOCKERHUB_PASSWORD - py36: &py36 - docker: - - image: circleci/python:3.6.13-buster - auth: - username: hdmf - password: $DOCKERHUB_PASSWORD - conda-image: &conda-image docker: - image: continuumio/miniconda3:4.9.2 @@ -161,14 +154,6 @@ jobs: - run: <<: *run-style-check - python36: - <<: *py36 - environment: - - TEST_TOX_ENV: "py36" - - BUILD_TOX_ENV: "build-py36" - - TEST_WHEELINSTALL_ENV: "wheelinstall" - <<: *ci-steps - python37: <<: *py37 environment: @@ -183,7 +168,6 @@ jobs: - TEST_TOX_ENV: "py38" - BUILD_TOX_ENV: "build-py38" - TEST_WHEELINSTALL_ENV: "wheelinstall" - - UPLOAD_WHEELS: "true" <<: *ci-steps python39: @@ -192,41 +176,33 @@ jobs: - TEST_TOX_ENV: "py39" - BUILD_TOX_ENV: "build-py39" - TEST_WHEELINSTALL_ENV: "wheelinstall" + - UPLOAD_WHEELS: "true" # upload distributions from only this job to pypi <<: *ci-steps - python38-upgrade-dev: - <<: *py38 + python39-upgrade-dev: + <<: *py39 environment: - - TEST_TOX_ENV: "py38-upgrade-dev" - - BUILD_TOX_ENV: "build-py38-upgrade-dev" + - TEST_TOX_ENV: "py39-upgrade-dev" + - BUILD_TOX_ENV: "build-py39-upgrade-dev" - TEST_WHEELINSTALL_ENV: "wheelinstall" <<: *ci-steps - python38-upgrade-dev-pre: - <<: *py38 + python39-upgrade-dev-pre: + <<: *py39 environment: - - TEST_TOX_ENV: "py38-upgrade-dev-pre" - - BUILD_TOX_ENV: "build-py38-upgrade-dev-pre" + - TEST_TOX_ENV: "py39-upgrade-dev-pre" + - BUILD_TOX_ENV: "build-py39-upgrade-dev-pre" - TEST_WHEELINSTALL_ENV: "wheelinstall" <<: *ci-steps - python36-min-req: - <<: *py36 + python37-min-req: + <<: *py37 environment: - - TEST_TOX_ENV: "py36-min-req" - - BUILD_TOX_ENV: "build-py36-min-req" + - TEST_TOX_ENV: "py37-min-req" + - BUILD_TOX_ENV: "build-py37-min-req" - TEST_WHEELINSTALL_ENV: "wheelinstall" <<: *ci-steps - miniconda36: - <<: *conda-image - environment: - - CONDA_PYTHON_VER: "3.6.*=*_cpython" # avoid using pypy compiler - - TEST_TOX_ENV: "py36" - - BUILD_TOX_ENV: "build-py36" - - TEST_WHEELINSTALL_ENV: "wheelinstall" - <<: *conda-steps - miniconda37: <<: *conda-image environment: @@ -254,12 +230,6 @@ jobs: - TEST_WHEELINSTALL_ENV: "wheelinstall" <<: *conda-steps - gallery36: - <<: *py36 - environment: - - TEST_TOX_ENV: "gallery-py36" - <<: *gallery-steps - gallery37: <<: *py37 environment: @@ -278,26 +248,26 @@ jobs: - TEST_TOX_ENV: "gallery-py39" <<: *gallery-steps - gallery38-upgrade-dev: - <<: *py38 + gallery39-upgrade-dev: + <<: *py39 environment: - - TEST_TOX_ENV: "gallery-py38-upgrade-dev" + - TEST_TOX_ENV: "gallery-py39-upgrade-dev" <<: *gallery-steps - gallery38-upgrade-dev-pre: - <<: *py38 + gallery39-upgrade-dev-pre: + <<: *py39 environment: - - TEST_TOX_ENV: "gallery-py38-upgrade-dev-pre" + - TEST_TOX_ENV: "gallery-py39-upgrade-dev-pre" <<: *gallery-steps - gallery36-min-req: - <<: *py36 + gallery37-min-req: + <<: *py37 environment: - - TEST_TOX_ENV: "gallery-py36-min-req" + - TEST_TOX_ENV: "gallery-py37-min-req" <<: *gallery-steps test-validation: - <<: *py38 + <<: *py39 steps: - checkout - run: git submodule sync @@ -309,13 +279,13 @@ jobs: command: | . ../venv/bin/activate pip install tox - tox -e validation-py38 + tox -e validation-py39 # Install is expected to be quick. Increase timeout in case there are some network issues. # While pip installing tox does not output by default. Circle thinks task is dead after 10 min. no_output_timeout: 30m deploy-dev: - <<: *py38 + <<: *py39 steps: - checkout - attach_workspace: @@ -336,7 +306,7 @@ jobs: --exit-success-if-missing-token deploy-release: - <<: *py38 + <<: *py39 steps: - attach_workspace: at: ./ @@ -366,27 +336,27 @@ workflows: jobs: - flake8: <<: *no_filters - - python38: + - python37-min-req: <<: *no_filters - - python36-min-req: + - python39: <<: *no_filters - - miniconda36: + - miniconda37: <<: *no_filters - - miniconda38: + - miniconda39: <<: *no_filters - - gallery38: + - gallery37-min-req: <<: *no_filters - - gallery36-min-req: + - gallery38: # TODO replace with gallery39 after allensdk support py39 <<: *no_filters - deploy-dev: requires: - flake8 - - python38 - - python36-min-req - - miniconda36 - - miniconda38 - - gallery38 - - gallery36-min-req + - python37-min-req + - python39 + - miniconda37 + - miniconda39 + - gallery37-min-req + - gallery38 # gallery39 filters: tags: ignore: @@ -400,12 +370,12 @@ workflows: - deploy-release: requires: - flake8 - - python38 - - python36-min-req - - miniconda36 - - miniconda38 - - gallery38 - - gallery36-min-req + - python37-min-req + - python39 + - miniconda37 + - miniconda39 + - gallery37-min-req + - gallery38 # gallery39 filters: tags: only: /^[0-9]+(\.[0-9]+)*(\.post[0-9]+)?$/ @@ -424,19 +394,17 @@ workflows: jobs: - flake8: <<: *no_filters - - python36: - <<: *no_filters - python37: <<: *no_filters + - python37-min-req: + <<: *no_filters - python38: <<: *no_filters - python39: <<: *no_filters - - python38-upgrade-dev: - <<: *no_filters - - python36-min-req: + - python39-upgrade-dev: <<: *no_filters - - miniconda36: + - python39-upgrade-dev-pre: <<: *no_filters - miniconda37: <<: *no_filters @@ -444,21 +412,15 @@ workflows: <<: *no_filters - miniconda39: <<: *no_filters - - gallery36: - <<: *no_filters - gallery37: <<: *no_filters + - gallery37-min-req: + <<: *no_filters - gallery38: <<: *no_filters - gallery39: <<: *no_filters - - gallery38-upgrade-dev: - <<: *no_filters - - gallery36-min-req: - <<: *no_filters - - python38-upgrade-dev-pre: - <<: *no_filters - - gallery38-upgrade-dev-pre: + - gallery39-upgrade-dev: <<: *no_filters - - test-validation: + - gallery39-upgrade-dev-pre: <<: *no_filters diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ba3fdb027..14f7796b1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -20,7 +20,7 @@ assignees: '' Python Executable: Conda or Python - Python Version: Python 3.6, 3.7, or 3.8 + Python Version: Python 3.7, 3.8, or 3.9 Operating System: Windows, macOS or Linux HDMF Version: PyNWB Version: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index c0cfcc234..70eb5695c 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -15,7 +15,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] env: OS: ${{ matrix.os }} - PYTHON: '3.8' + PYTHON: '3.9' steps: - name: Cancel Workflow Action uses: styfle/cancel-workflow-action@0.6.0 @@ -27,7 +27,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/CHANGELOG.md b/CHANGELOG.md index bc3f46aa9..edd9984ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,12 @@ - - - -- +- Drop Python 3.6 support, add Python 3.9 support. @rly (#1377) +- Update requirements to allow compatibility with HDMF 3 and h5py 3. @rly (#1377) ### Minor new features: - Add RRID for citing PyNWB to the docs. @oruebel (#1372) +- Update CI and tests to handle deprecations in libraries. @rly (#1377) ### Bug fixes: - Enforce electrode ID uniqueness during insertion into table. @CodyCBakerPhD (#1344) diff --git a/azure-pipelines-nightly.yml b/azure-pipelines-nightly.yml index 552d1bcd3..c0a79b9d2 100644 --- a/azure-pipelines-nightly.yml +++ b/azure-pipelines-nightly.yml @@ -19,23 +19,21 @@ jobs: imageName: 'macos-10.15' pythonVersion: '3.9' testToxEnv: 'py39' - coverageToxEnv: '' buildToxEnv: 'build-py39' testWheelInstallEnv: 'wheelinstall' - macOS-py3.8-upgrade-dev-pre: + macOS-py3.9-upgrade-dev-pre: imageName: 'macos-10.15' - pythonVersion: '3.8' - testToxEnv: 'py38-upgrade-dev-pre' - coverageToxEnv: '' - buildToxEnv: 'build-py38-upgrade-dev-pre' + pythonVersion: '3.9' + testToxEnv: 'py39-upgrade-dev-pre' + buildToxEnv: 'build-py39-upgrade-dev-pre' testWheelInstallEnv: 'wheelinstall' - macOS-py3.8-upgrade-dev: + macOS-py3.9-upgrade-dev: imageName: 'macos-10.15' - pythonVersion: '3.8' - testToxEnv: 'py38-upgrade-dev' - buildToxEnv: 'build-py38-upgrade-dev' + pythonVersion: '3.9' + testToxEnv: 'py39-upgrade-dev' + buildToxEnv: 'build-py39-upgrade-dev' testWheelInstallEnv: 'wheelinstall' macOS-py3.8: @@ -52,41 +50,32 @@ jobs: buildToxEnv: 'build-py37' testWheelInstallEnv: 'wheelinstall' - macOS-py3.6: + macOS-py3.7-min-req: imageName: 'macos-10.15' - pythonVersion: '3.6' - testToxEnv: 'py36' - buildToxEnv: 'build-py36' - testWheelInstallEnv: 'wheelinstall' - - macOS-py3.6-min-req: - imageName: 'macos-10.15' - pythonVersion: '3.6' - testToxEnv: 'py36-min-req' - buildToxEnv: 'build-py36-min-req' + pythonVersion: '3.7' + testToxEnv: 'py37-min-req' + buildToxEnv: 'build-py37-min-req' testWheelInstallEnv: 'wheelinstall' Windows-py3.9: imageName: 'vs2017-win2016' pythonVersion: '3.9' testToxEnv: 'py39' - coverageToxEnv: '' buildToxEnv: 'build-py39' testWheelInstallEnv: 'wheelinstall' - Windows-py3.8-upgrade-dev-pre: + Windows-py3.9-upgrade-dev-pre: imageName: 'vs2017-win2016' - pythonVersion: '3.8' - testToxEnv: 'py38-upgrade-dev-pre' - coverageToxEnv: '' - buildToxEnv: 'build-py38-upgrade-dev-pre' + pythonVersion: '3.9' + testToxEnv: 'py39-upgrade-dev-pre' + buildToxEnv: 'build-py39-upgrade-dev-pre' testWheelInstallEnv: 'wheelinstall' - Windows-py3.8-upgrade-dev: + Windows-py3.9-upgrade-dev: imageName: 'vs2017-win2016' - pythonVersion: '3.8' - testToxEnv: 'py38-upgrade-dev' - buildToxEnv: 'build-py38-upgrade-dev' + pythonVersion: '3.9' + testToxEnv: 'py39-upgrade-dev' + buildToxEnv: 'build-py39-upgrade-dev' testWheelInstallEnv: 'wheelinstall' Windows-py3.8: @@ -103,18 +92,11 @@ jobs: buildToxEnv: 'build-py37' testWheelInstallEnv: 'wheelinstall' - Windows-py3.6: + Windows-py3.7-min-req: imageName: 'vs2017-win2016' - pythonVersion: '3.6' - testToxEnv: 'py36' - buildToxEnv: 'build-py36' - testWheelInstallEnv: 'wheelinstall' - - Windows-py3.6-min-req: - imageName: 'vs2017-win2016' - pythonVersion: '3.6' - testToxEnv: 'py36-min-req' - buildToxEnv: 'build-py36-min-req' + pythonVersion: '3.7' + testToxEnv: 'py37-min-req' + buildToxEnv: 'build-py37-min-req' testWheelInstallEnv: 'wheelinstall' pool: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b43eeb0a4..a720e78bd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -8,39 +8,38 @@ jobs: strategy: matrix: - macOS-py3.8: + macOS-py3.9: imageName: 'macos-10.15' - pythonVersion: '3.8' - testToxEnv: 'py38' - buildToxEnv: 'build-py38' + pythonVersion: '3.9' + testToxEnv: 'py39' + buildToxEnv: 'build-py39' testWheelInstallEnv: 'wheelinstall' - macOS-py3.6-min-req: + macOS-py3.7-min-req: imageName: 'macos-10.15' - pythonVersion: '3.6' - testToxEnv: 'py36-min-req' - buildToxEnv: 'build-py36-min-req' + pythonVersion: '3.7' + testToxEnv: 'py37-min-req' + buildToxEnv: 'build-py37-min-req' testWheelInstallEnv: 'wheelinstall' - Windows-py3.8: + Windows-py3.9: imageName: 'vs2017-win2016' - pythonVersion: '3.8' - testToxEnv: 'py38' - buildToxEnv: 'build-py38' + pythonVersion: '3.9' + testToxEnv: 'py39' + buildToxEnv: 'build-py39' testWheelInstallEnv: 'wheelinstall' - Windows-py3.6-min-req: + Windows-py3.7-min-req: imageName: 'vs2017-win2016' - pythonVersion: '3.6' - testToxEnv: 'py36-min-req' - buildToxEnv: 'build-py36-min-req' + pythonVersion: '3.7' + testToxEnv: 'py37-min-req' + buildToxEnv: 'build-py37-min-req' testWheelInstallEnv: 'wheelinstall' pool: vmImage: $(imageName) steps: - - checkout: self submodules: true diff --git a/docs/gallery/domain/brain_observatory.py b/docs/gallery/domain/brain_observatory.py index 9be41de72..7aac0938c 100644 --- a/docs/gallery/domain/brain_observatory.py +++ b/docs/gallery/domain/brain_observatory.py @@ -10,8 +10,6 @@ # physiology submodule (pynwb.ophys). We will use the allensdk as a read API, while leveraging the pynwb data model and # write api to transform and write the data back to disk. # -# .. note: Using the latest allensdk package requires Python 3.6 or higher. - ######################################## # .. raw:: html # :url: https://gist.githubusercontent.com/nicain/82e6b3d8f9ff5b85ef01a582e41e2389/raw/ diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index beb2b7542..3acbb94d1 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -6,7 +6,7 @@ Dependencies PyNWB has the following minimum requirements, which must be installed before you can get started using PyNWB. -#. Python 3.5, 3.6, or 3.7 +#. Python 3.7, 3.8, or 3.9 #. pip ------------ diff --git a/requirements-dev.txt b/requirements-dev.txt index 563995cf9..27b099d30 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,8 +2,8 @@ # compute coverage, and create test environments codecov==2.1.11 coverage==5.5 -flake8==3.9.1 +flake8==3.9.2 flake8-debugger==4.0.0 flake8-print==4.0.0 -importlib-metadata==4.0.1 -tox==3.23.0 +importlib-metadata==4.6.1 +tox==3.23.1 diff --git a/requirements-min.txt b/requirements-min.txt index abf6943ef..9b9d14bd3 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,6 +1,6 @@ # minimum versions of package dependencies for installing PyNWB -h5py==2.9 # support for setting attrs to lists of utf-8 added in 2.9 -hdmf==2.5.6 +h5py==2.10 # support for selection of datasets with list of indices added in 2.10 +hdmf==3.0.1 numpy==1.16 pandas==1.0.5 python-dateutil==2.7 diff --git a/requirements.txt b/requirements.txt index f4a416850..ba1493ad7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ # pinned dependencies to reproduce an entire development environment to use PyNWB -h5py==2.10.0 -hdmf==2.5.6 -numpy==1.19.3 -pandas==1.1.5 +h5py==3.3.0 +hdmf==3.0.1 +numpy==1.21.0 +pandas==1.3.0 python-dateutil==2.8.1 -setuptools==56.0.0 +setuptools==57.1.0 diff --git a/setup.py b/setup.py index e04b77fd2..f862c3446 100755 --- a/setup.py +++ b/setup.py @@ -14,8 +14,8 @@ reqs = [ 'h5py>=2.9,<4', - 'hdmf>=2.5.6,<3', - 'numpy>=1.16,<1.21', + 'hdmf>=3.0.1,<4', + 'numpy>=1.16,<1.22', 'pandas>=1.0.5,<2', 'python-dateutil>=2.7,<3', 'setuptools' @@ -40,9 +40,9 @@ 'package_data': {'pynwb': ["%s/*.yaml" % schema_dir, "%s/*.json" % schema_dir]}, 'classifiers': [ "Programming Language :: Python", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "License :: OSI Approved :: BSD License", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index 2fc379e09..72dcc7245 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit 2fc379e09f66ddbde6c06947fa1b94dae1189990 +Subproject commit 72dcc72452f7828c89cd1dd71bc36ed0072b1b36 diff --git a/src/pynwb/ophys.py b/src/pynwb/ophys.py index 3844ddf09..97e3b2468 100644 --- a/src/pynwb/ophys.py +++ b/src/pynwb/ophys.py @@ -267,8 +267,8 @@ def pixel_to_image(pixel_mask): """Converts a 2D pixel_mask of a ROI into an image_mask.""" image_matrix = np.zeros(np.shape(pixel_mask)) npmask = np.asarray(pixel_mask) - x_coords = npmask[:, 0].astype(np.int) - y_coords = npmask[:, 1].astype(np.int) + x_coords = npmask[:, 0].astype(np.int32) + y_coords = npmask[:, 1].astype(np.int32) weights = npmask[:, -1] image_matrix[y_coords, x_coords] = weights return image_matrix diff --git a/src/pynwb/validate.py b/src/pynwb/validate.py index b4c323f1d..f3f127b19 100644 --- a/src/pynwb/validate.py +++ b/src/pynwb/validate.py @@ -26,7 +26,7 @@ def _validate_helper(**kwargs): return (errors is not None and len(errors) > 0) -def main(): +def main(): # noqa: C901 ep = """ use --nspath to validate against an extension. If --ns is not specified, @@ -111,15 +111,22 @@ def main(): if args.ns: if args.ns in namespaces: namespaces = [args.ns] + elif args.cached_namespace and args.ns in ns_deps: # validating against a dependency + for k in ns_deps: + if args.ns in ns_deps[k]: + print(("The namespace '{}' is included by the namespace '{}'. Please validate against " + "that namespace instead.").format(args.ns, k), file=sys.stderr) + ret = 1 + continue else: - print("The namespace {} could not be found in {} as only {} is present.".format( + print("The namespace '{}' could not be found in {} as only {} is present.".format( args.ns, specloc, namespaces), file=sys.stderr) ret = 1 continue with NWBHDF5IO(path, mode='r', manager=manager) as io: for ns in namespaces: - print("Validating {} against {} using namespace {}.".format(path, specloc, ns)) + print("Validating {} against {} using namespace '{}'.".format(path, specloc, ns)) ret = ret or _validate_helper(io=io, namespace=ns) sys.exit(ret) diff --git a/tests/back_compat/test_read.py b/tests/back_compat/test_read.py index 731895c7d..c9ccd51ce 100644 --- a/tests/back_compat/test_read.py +++ b/tests/back_compat/test_read.py @@ -7,6 +7,17 @@ class TestReadOldVersions(TestCase): + expected_errors = { + '1.0.2_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected " + "an array of shape '[None]', got non-array data 'one experimenter'")], + '1.0.3_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected " + "an array of shape '[None]', got non-array data 'one experimenter'")], + '1.0.2_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape " + "- expected an array of shape '[None]', got non-array data 'one publication'")], + '1.0.3_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape " + "- expected an array of shape '[None]', got non-array data 'one publication'")], + } + def test_read(self): """ Attempt to read and validate all NWB files in the same folder as this file. The folder should contain NWB files @@ -21,6 +32,7 @@ def test_read(self): io.read() if errors: for e in errors: - warnings.warn('%s: %s' % (f.name, e)) + if f.name in self.expected_errors and str(e) not in self.expected_errors[f.name]: + warnings.warn('%s: %s' % (f.name, e)) # TODO uncomment below when validation errors have been fixed # raise Exception('%d validation error(s). See warnings.' % len(errors)) diff --git a/tests/integration/hdf5/test_ecephys.py b/tests/integration/hdf5/test_ecephys.py index 0ea69c233..cc70ee9dc 100644 --- a/tests/integration/hdf5/test_ecephys.py +++ b/tests/integration/hdf5/test_ecephys.py @@ -150,6 +150,11 @@ def roundtripContainer(self, cache_spec=False): with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripContainer(cache_spec) + def roundtripExportContainer(self, cache_spec=False): + # catch the DeprecationWarning raised when reading the Clustering object from file + with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): + return super().roundtripExportContainer(cache_spec) + class EventWaveformConstructor(AcquisitionH5IOMixin, TestCase): @@ -200,6 +205,11 @@ def roundtripContainer(self, cache_spec=False): with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): return super().roundtripContainer(cache_spec) + def roundtripExportContainer(self, cache_spec=False): + # catch the DeprecationWarning raised when reading the Clustering object from file + with self.assertWarnsWith(DeprecationWarning, 'use pynwb.misc.Units or NWBFile.units instead'): + return super().roundtripExportContainer(cache_spec) + class FeatureExtractionConstructor(AcquisitionH5IOMixin, TestCase): diff --git a/tests/integration/hdf5/test_misc.py b/tests/integration/hdf5/test_misc.py index c4a371532..3bfa42a33 100644 --- a/tests/integration/hdf5/test_misc.py +++ b/tests/integration/hdf5/test_misc.py @@ -15,7 +15,7 @@ class TestUnitsIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test Units to read/write """ ut = Units(name='UnitsTest', description='a simple table for testing Units') - ut.add_unit(spike_times=[0, 1, 2], obs_intervals=[[0, 1], [2, 3]], + ut.add_unit(spike_times=[0., 1., 2.], obs_intervals=[[0., 1.], [2., 3.]], waveform_mean=[1., 2., 3.], waveform_sd=[4., 5., 6.], waveforms=[ [ # elec 1 @@ -28,7 +28,7 @@ def setUpContainer(self): [1, 2, 3] ] ]) - ut.add_unit(spike_times=[3, 4, 5], obs_intervals=[[2, 5], [6, 7]], + ut.add_unit(spike_times=[3., 4., 5.], obs_intervals=[[2., 5.], [6., 7.]], waveform_mean=[1., 2., 3.], waveform_sd=[4., 5., 6.], waveforms=np.array([ [ # elec 1 @@ -56,19 +56,19 @@ def test_get_spike_times(self): """ Test whether the Units spike times read from file are what was written """ ut = self.roundtripContainer() received = ut.get_unit_spike_times(0) - self.assertTrue(np.array_equal(received, [0, 1, 2])) + self.assertTrue(np.array_equal(received, [0., 1., 2.])) received = ut.get_unit_spike_times(1) - self.assertTrue(np.array_equal(received, [3, 4, 5])) - self.assertTrue(np.array_equal(ut['spike_times'][:], [[0, 1, 2], [3, 4, 5]])) + self.assertTrue(np.array_equal(received, [3., 4., 5.])) + self.assertTrue(np.array_equal(ut['spike_times'][:], [[0., 1., 2.], [3., 4., 5.]])) def test_get_obs_intervals(self): """ Test whether the Units observation intervals read from file are what was written """ ut = self.roundtripContainer() received = ut.get_unit_obs_intervals(0) - self.assertTrue(np.array_equal(received, [[0, 1], [2, 3]])) + self.assertTrue(np.array_equal(received, [[0., 1.], [2., 3.]])) received = ut.get_unit_obs_intervals(1) - self.assertTrue(np.array_equal(received, [[2, 5], [6, 7]])) - self.assertTrue(np.array_equal(ut['obs_intervals'][:], [[[0, 1], [2, 3]], [[2, 5], [6, 7]]])) + self.assertTrue(np.array_equal(received, [[2., 5.], [6., 7.]])) + self.assertTrue(np.array_equal(ut['obs_intervals'][:], [[[0., 1.], [2., 3.]], [[2., 5.], [6., 7.]]])) class TestUnitsFileIO(NWBH5IOMixin, TestCase): diff --git a/tests/unit/test_epoch.py b/tests/unit/test_epoch.py index 774edc41f..64278130d 100644 --- a/tests/unit/test_epoch.py +++ b/tests/unit/test_epoch.py @@ -11,7 +11,7 @@ class TimeIntervalsTest(TestCase): def test_init(self): - tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float) + tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries("test_ts", list(range(len(tstamps))), 'unit', timestamps=tstamps) ept = TimeIntervals('epochs', "TimeIntervals unittest") self.assertEqual(ept.name, 'epochs') diff --git a/tests/unit/test_file.py b/tests/unit/test_file.py index d3afa8155..c68ff5589 100644 --- a/tests/unit/test_file.py +++ b/tests/unit/test_file.py @@ -130,7 +130,7 @@ def test_access_processing(self): def test_epoch_tags(self): tags1 = ['t1', 't2'] tags2 = ['t3', 't4'] - tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float) + tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries("test_ts", list(range(len(tstamps))), 'unit', timestamps=tstamps) expected_tags = tags1 + tags2 self.nwbfile.add_epoch(0.0, 1.0, tags1, ts) diff --git a/tests/unit/test_ophys.py b/tests/unit/test_ophys.py index a9dc9bc59..024c081cb 100644 --- a/tests/unit/test_ophys.py +++ b/tests/unit/test_ophys.py @@ -256,7 +256,7 @@ def test_init(self): format='tiff', timestamps=[1., 2.] ) - tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float) + tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float64) ts = TimeSeries( name='xy_translation', data=list(range(len(tstamps))), diff --git a/tests/validation/test_validate.py b/tests/validation/test_validate.py index cf946aa0d..d491fff47 100644 --- a/tests/validation/test_validate.py +++ b/tests/validation/test_validate.py @@ -39,7 +39,8 @@ def test_validate_file_no_cache_bad_ns(self): r"warnings.warn\(msg\)\s*" r"The file tests/back_compat/1\.0\.2_nwbfile\.nwb has no cached namespace information\. " r"Falling back to pynwb namespace information\.\s*" - r"The namespace 'notfound' could not be found in pynwb namespace information\.\s*" + r"The namespace 'notfound' could not be found in pynwb namespace information as only " + r"\['core'\] is present\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) @@ -63,7 +64,8 @@ def test_validate_file_cached_bad_ns(self): capture_output=True) stderr_regex = re.compile( - r"The namespace 'notfound' could not be found in cached namespace information\.\s*" + r"The namespace 'notfound' could not be found in cached namespace information as only " + r"\['core'\] is present\.\s*" ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) @@ -75,17 +77,11 @@ def test_validate_file_cached_hdmf_common(self): capture_output=True) stderr_regex = re.compile( - r".*ValueError: data type \'NWBFile\' not found in namespace hdmf-common.\s*", - re.DOTALL + r"The namespace 'hdmf-common' is included by the namespace 'core'\. Please validate against that " + r"namespace instead\.\s*", ) self.assertRegex(result.stderr.decode('utf-8'), stderr_regex) - stdout_regex = re.compile( - r"Validating tests/back_compat/1.1.2_nwbfile.nwb against cached namespace information using namespace " - r"'hdmf-common'.\s*" - ) - self.assertRegex(result.stdout.decode('utf-8'), stdout_regex) - def test_validate_file_cached_ignore(self): """Test that validating a file with cached spec against the core namespace succeeds.""" result = subprocess.run("python -m pynwb.validate tests/back_compat/1.1.2_nwbfile.nwb --no-cached-namespace", diff --git a/tox.ini b/tox.ini index a8792efbf..81ed4fcd2 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py36, py37, py38, py39 +envlist = py37, py38, py39 [testenv] usedevelop = True @@ -22,32 +22,32 @@ commands = # Env to create coverage report locally [testenv:localcoverage] -basepython = python3.8 +basepython = python3.9 commands = python -m coverage run test.py --pynwb coverage html -d tests/coverage/htmlcov -# Test with python 3.8, pinned dev reqs, and upgraded run requirements -[testenv:py38-upgrade-dev] -basepython = python3.8 +# Test with python 3.9, pinned dev reqs, and upgraded run requirements +[testenv:py39-upgrade-dev] +basepython = python3.9 install_command = pip install -U -e . {opts} {packages} deps = -rrequirements-dev.txt commands = {[testenv]commands} -# Test with python 3.8, pinned dev reqs, and pre-release run requirements -[testenv:py38-upgrade-dev-pre] -basepython = python3.8 +# Test with python 3.9, pinned dev reqs, and pre-release run requirements +[testenv:py39-upgrade-dev-pre] +basepython = python3.9 install_command = pip install -U --pre -e . {opts} {packages} deps = -rrequirements-dev.txt commands = {[testenv]commands} -# Test with python 3.6, pinned dev reqs, and minimum run requirements -[testenv:py36-min-req] -basepython = python3.6 +# Test with python 3.7, pinned dev reqs, and minimum run requirements +[testenv:py37-min-req] +basepython = python3.7 deps = -rrequirements-dev.txt -rrequirements-min.txt @@ -59,10 +59,6 @@ commands = python setup.py sdist python setup.py bdist_wheel -[testenv:build-py36] -basepython = python3.6 -commands = {[testenv:build]commands} - [testenv:build-py37] basepython = python3.7 commands = {[testenv:build]commands} @@ -75,24 +71,24 @@ commands = {[testenv:build]commands} basepython = python3.9 commands = {[testenv:build]commands} -[testenv:build-py38-upgrade-dev] -basepython = python3.8 +[testenv:build-py39-upgrade-dev] +basepython = python3.9 install_command = pip install -U -e . {opts} {packages} deps = -rrequirements-dev.txt commands = {[testenv:build]commands} -[testenv:build-py38-upgrade-dev-pre] -basepython = python3.8 +[testenv:build-py39-upgrade-dev-pre] +basepython = python3.9 install_command = pip install -U --pre -e . {opts} {packages} deps = -rrequirements-dev.txt commands = {[testenv:build]commands} -[testenv:build-py36-min-req] -basepython = python3.6 +[testenv:build-py37-min-req] +basepython = python3.7 deps = -rrequirements-dev.txt -rrequirements-min.txt @@ -116,11 +112,6 @@ deps = commands = python test.py --example -[testenv:gallery-py36] -basepython = python3.6 -deps = {[testenv:gallery]deps} -commands = {[testenv:gallery]commands} - [testenv:gallery-py37] basepython = python3.7 deps = {[testenv:gallery]deps} @@ -136,10 +127,9 @@ basepython = python3.9 deps = {[testenv:gallery]deps} commands = {[testenv:gallery]commands} - -# Test with python 3.8, pinned dev and doc reqs, and upgraded run requirements -[testenv:gallery-py38-upgrade-dev] -basepython = python3.8 +# Test with python 3.9, pinned dev and doc reqs, and upgraded run requirements +[testenv:gallery-py39-upgrade-dev] +basepython = python3.9 install_command = pip install -U -e . {opts} {packages} deps = @@ -147,9 +137,9 @@ deps = -rrequirements-doc.txt commands = {[testenv:gallery]commands} -# Test with python 3.8, pinned dev and doc reqs, and pre-release run requirements -[testenv:gallery-py38-upgrade-dev-pre] -basepython = python3.8 +# Test with python 3.9, pinned dev and doc reqs, and pre-release run requirements +[testenv:gallery-py39-upgrade-dev-pre] +basepython = python3.9 install_command = pip install -U --pre -e . {opts} {packages} deps = @@ -157,17 +147,17 @@ deps = -rrequirements-doc.txt commands = {[testenv:gallery]commands} -# Test with python 3.6, pinned dev reqs, and minimum run requirements -[testenv:gallery-py36-min-req] -basepython = python3.6 +# Test with python 3.7, pinned dev reqs, and minimum run requirements +[testenv:gallery-py37-min-req] +basepython = python3.7 deps = -rrequirements-dev.txt -rrequirements-min.txt -rrequirements-doc.txt commands = {[testenv:gallery]commands} -[testenv:validation-py38] -basepython = python3.8 +[testenv:validation-py39] +basepython = python3.9 install_command = pip install -U {opts} {packages} deps =