From dd2e848152e3a50ddde1591eae268481db08a015 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Thu, 14 Dec 2023 20:04:38 +0100 Subject: [PATCH 1/8] fix bug with w- io mode (#1795) Co-authored-by: Ryan Ly --- CHANGELOG.md | 3 +++ src/pynwb/__init__.py | 3 ++- tests/integration/hdf5/test_io.py | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd4dbfd05..09bc731e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ - Updated timeseries data checks to warn instead of error when reading invalid files. @stephprince [#1793](https://github.com/NeurodataWithoutBorders/pynwb/pull/1793) - Expose the offset, conversion and channel conversion parameters in `mock_ElectricalSeries`. @h-mayorquin [#1796](https://github.com/NeurodataWithoutBorders/pynwb/pull/1796) +### Bug fixes +- Fix bug where namespaces were loaded in "w-" mode. @h-mayorquin [#1795](https://github.com/NeurodataWithoutBorders/pynwb/pull/1795) + ## PyNWB 2.5.0 (August 18, 2023) ### Enhancements and minor changes diff --git a/src/pynwb/__init__.py b/src/pynwb/__init__.py index 7cf32e074..6e3b3104f 100644 --- a/src/pynwb/__init__.py +++ b/src/pynwb/__init__.py @@ -261,7 +261,8 @@ def __init__(self, **kwargs): popargs('path', 'mode', 'manager', 'extensions', 'load_namespaces', 'file', 'comm', 'driver', 'herd_path', kwargs) # Define the BuildManager to use - if mode in 'wx' or manager is not None or extensions is not None: + io_modes_that_create_file = ['w', 'w-', 'x'] + if mode in io_modes_that_create_file or manager is not None or extensions is not None: load_namespaces = False if load_namespaces: diff --git a/tests/integration/hdf5/test_io.py b/tests/integration/hdf5/test_io.py index 0fd790073..d68334c89 100644 --- a/tests/integration/hdf5/test_io.py +++ b/tests/integration/hdf5/test_io.py @@ -3,6 +3,7 @@ import numpy as np from h5py import File from pathlib import Path +import tempfile from pynwb import NWBFile, TimeSeries, get_manager, NWBHDF5IO, validate @@ -14,6 +15,7 @@ from pynwb.spec import NWBGroupSpec, NWBDatasetSpec, NWBNamespace from pynwb.ecephys import ElectricalSeries, LFP from pynwb.testing import remove_test_file, TestCase +from pynwb.testing.mock.file import mock_NWBFile class TestHDF5Writer(TestCase): @@ -122,6 +124,19 @@ def test_write_no_cache_spec(self): with File(self.path, 'r') as f: self.assertNotIn('specifications', f) + def test_file_creation_io_modes(self): + io_modes_that_create_file = ["w", "w-", "x"] + + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir = Path(temp_dir) + for io_mode in io_modes_that_create_file: + file_path = temp_dir / f"test_io_mode={io_mode}.nwb" + + # Test file creation + nwbfile = mock_NWBFile() + with NWBHDF5IO(str(file_path), io_mode) as io: + io.write(nwbfile) + class TestHDF5WriterWithInjectedFile(TestCase): From d9a409d1456c0477e2cb393f0323b82993f6556e Mon Sep 17 00:00:00 2001 From: Steph Prince <40640337+stephprince@users.noreply.github.com> Date: Tue, 19 Dec 2023 17:41:44 -0500 Subject: [PATCH 2/8] change from error to warn when timeseries has a zero rate (#1809) * only warn when writing zero rates instead of error * update changelog --- CHANGELOG.md | 2 +- src/pynwb/base.py | 6 ++++-- tests/unit/test_base.py | 10 ++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09bc731e9..b096f6bdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - For `NWBHDF5IO()`, change the default of arg `load_namespaces` from `False` to `True`. @bendichter [#1748](https://github.com/NeurodataWithoutBorders/pynwb/pull/1748) - Add `NWBHDF5IO.can_read()`. @bendichter [#1703](https://github.com/NeurodataWithoutBorders/pynwb/pull/1703) - Add `pynwb.get_nwbfile_version()`. @bendichter [#1703](https://github.com/NeurodataWithoutBorders/pynwb/pull/1703) -- Updated timeseries data checks to warn instead of error when reading invalid files. @stephprince [#1793](https://github.com/NeurodataWithoutBorders/pynwb/pull/1793) +- Updated timeseries data checks to warn instead of error when reading invalid files. @stephprince [#1793](https://github.com/NeurodataWithoutBorders/pynwb/pull/1793) and [#1809](https://github.com/NeurodataWithoutBorders/pynwb/pull/1809) - Expose the offset, conversion and channel conversion parameters in `mock_ElectricalSeries`. @h-mayorquin [#1796](https://github.com/NeurodataWithoutBorders/pynwb/pull/1796) ### Bug fixes diff --git a/src/pynwb/base.py b/src/pynwb/base.py index 5514288e8..846266853 100644 --- a/src/pynwb/base.py +++ b/src/pynwb/base.py @@ -187,10 +187,12 @@ def __init__(self, **kwargs): if isinstance(timestamps, TimeSeries): timestamps.__add_link('timestamp_link', self) elif self.rate is not None: - if self.rate <= 0: + if self.rate < 0: self._error_on_new_warn_on_construct( - error_msg='Rate must be a positive value.' + error_msg='Rate must not be a negative value.' ) + elif self.rate == 0.0 and get_data_shape(data)[0] > 1: + warn('Timeseries has a rate of 0.0 Hz, but the length of the data is greater than 1.') if self.starting_time is None: # override default if rate is provided but not starting time self.starting_time = 0.0 self.starting_time_unit = self.__time_unit diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py index 899628190..ad4ce6739 100644 --- a/tests/unit/test_base.py +++ b/tests/unit/test_base.py @@ -406,10 +406,12 @@ def test_get_data_in_units(self): assert_array_equal(ts.get_data_in_units(), [1., 2., 3.]) def test_non_positive_rate(self): - with self.assertRaisesWith(ValueError, 'Rate must be a positive value.'): + with self.assertRaisesWith(ValueError, 'Rate must not be a negative value.'): TimeSeries(name='test_ts', data=list(), unit='volts', rate=-1.0) - with self.assertRaisesWith(ValueError, 'Rate must be a positive value.'): - TimeSeries(name='test_ts1', data=list(), unit='volts', rate=0.0) + + with self.assertWarnsWith(UserWarning, + 'Timeseries has a rate of 0.0 Hz, but the length of the data is greater than 1.'): + TimeSeries(name='test_ts1', data=[1, 2, 3], unit='volts', rate=0.0) def test_file_with_non_positive_rate_in_construct_mode(self): """Test that UserWarning is raised when rate is 0 or negative @@ -419,7 +421,7 @@ def test_file_with_non_positive_rate_in_construct_mode(self): parent=None, object_id="test", in_construct_mode=True) - with self.assertWarnsWith(warn_type=UserWarning, exc_msg='Rate must be a positive value.'): + with self.assertWarnsWith(warn_type=UserWarning, exc_msg='Rate must not be a negative value.'): obj.__init__( name="test_ts", data=list(), From ac17d17799b1d17a09e259ed187db9fc1f7d0808 Mon Sep 17 00:00:00 2001 From: Steph Prince <40640337+stephprince@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:00:18 -0500 Subject: [PATCH 3/8] update versioneer configuration to fix reported readthedocs version (#1810) * update _version.py configuration * update changelog --------- Co-authored-by: Ryan Ly --- CHANGELOG.md | 1 + setup.cfg | 1 + src/pynwb/_version.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b096f6bdc..60f0e42fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Bug fixes - Fix bug where namespaces were loaded in "w-" mode. @h-mayorquin [#1795](https://github.com/NeurodataWithoutBorders/pynwb/pull/1795) +- Fix bug where pynwb version was reported as "unknown" to readthedocs @stephprince [#1810](https://github.com/NeurodataWithoutBorders/pynwb/pull/1810) ## PyNWB 2.5.0 (August 18, 2023) diff --git a/setup.cfg b/setup.cfg index cccacf048..0b7c5ee50 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,7 @@ VCS = git versionfile_source = src/pynwb/_version.py versionfile_build = pynwb/_version.py tag_prefix = '' +style = pep440-pre [flake8] max-line-length = 120 diff --git a/src/pynwb/_version.py b/src/pynwb/_version.py index 57dfeb9fc..bf16355e1 100644 --- a/src/pynwb/_version.py +++ b/src/pynwb/_version.py @@ -44,7 +44,7 @@ def get_config(): cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "pep440-pre" - cfg.tag_prefix = "*.*.*" + cfg.tag_prefix = "" cfg.parentdir_prefix = "None" cfg.versionfile_source = "src/pynwb/_version.py" cfg.verbose = False From 17b5621eb52e5158b8950930dbb3e69e834fd230 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Thu, 21 Dec 2023 03:17:18 +0100 Subject: [PATCH 4/8] Make `get_data_in_units` work with `channel_conversion` (#1806) Co-authored-by: Ryan Ly --- CHANGELOG.md | 1 + src/pynwb/base.py | 6 +++++- tests/unit/test_ecephys.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f0e42fa..078eb5ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Add `pynwb.get_nwbfile_version()`. @bendichter [#1703](https://github.com/NeurodataWithoutBorders/pynwb/pull/1703) - Updated timeseries data checks to warn instead of error when reading invalid files. @stephprince [#1793](https://github.com/NeurodataWithoutBorders/pynwb/pull/1793) and [#1809](https://github.com/NeurodataWithoutBorders/pynwb/pull/1809) - Expose the offset, conversion and channel conversion parameters in `mock_ElectricalSeries`. @h-mayorquin [#1796](https://github.com/NeurodataWithoutBorders/pynwb/pull/1796) +- Enhance `get_data_in_units()` to work with objects that have a `channel_conversion` attribute like the `ElectricalSeries` @h-mayorquin [#1806](https://github.com/NeurodataWithoutBorders/pynwb/pull/1806) ### Bug fixes - Fix bug where namespaces were loaded in "w-" mode. @h-mayorquin [#1795](https://github.com/NeurodataWithoutBorders/pynwb/pull/1795) diff --git a/src/pynwb/base.py b/src/pynwb/base.py index 846266853..42f7b7ff3 100644 --- a/src/pynwb/base.py +++ b/src/pynwb/base.py @@ -298,7 +298,11 @@ def get_timestamps(self): return np.arange(len(self.data)) / self.rate + self.starting_time def get_data_in_units(self): - return np.asarray(self.data) * self.conversion + self.offset + if "channel_conversion" in self.fields: + scale_factor = self.conversion * self.channel_conversion[:, np.newaxis] + else: + scale_factor = self.conversion + return np.asarray(self.data) * scale_factor + self.offset @register_class('Image', CORE_NAMESPACE) diff --git a/tests/unit/test_ecephys.py b/tests/unit/test_ecephys.py index 6f76a5e8c..f81b61f84 100644 --- a/tests/unit/test_ecephys.py +++ b/tests/unit/test_ecephys.py @@ -18,6 +18,7 @@ from pynwb.device import Device from pynwb.file import ElectrodeTable from pynwb.testing import TestCase +from pynwb.testing.mock.ecephys import mock_ElectricalSeries from hdmf.common import DynamicTableRegion @@ -115,6 +116,24 @@ def test_dimensions_warning(self): "but instead the first does. Data is oriented incorrectly and should be transposed." ) in str(w[-1].message) + def test_get_data_in_units(self): + + data = np.asarray([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]) + conversion = 1.0 + offset = 3.0 + channel_conversion = np.asarray([2.0, 2.0]) + electrical_series = mock_ElectricalSeries( + data=data, + conversion=conversion, + offset=offset, + channel_conversion=channel_conversion, + ) + + data_in_units = electrical_series.get_data_in_units() + expected_data = data * conversion * channel_conversion[:, np.newaxis] + offset + + np.testing.assert_almost_equal(data_in_units, expected_data) + class SpikeEventSeriesConstructor(TestCase): From 649800088ffb4bffb95bf0f55302d82537a8d78f Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 22 Dec 2023 01:43:41 +0100 Subject: [PATCH 5/8] Expose starting time in `mock_ElectricalSeries` (#1805) Co-authored-by: Ryan Ly --- CHANGELOG.md | 3 ++- src/pynwb/testing/mock/ecephys.py | 2 ++ src/pynwb/testing/mock/ophys.py | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 078eb5ce3..f38f6001d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ - Add `pynwb.get_nwbfile_version()`. @bendichter [#1703](https://github.com/NeurodataWithoutBorders/pynwb/pull/1703) - Updated timeseries data checks to warn instead of error when reading invalid files. @stephprince [#1793](https://github.com/NeurodataWithoutBorders/pynwb/pull/1793) and [#1809](https://github.com/NeurodataWithoutBorders/pynwb/pull/1809) - Expose the offset, conversion and channel conversion parameters in `mock_ElectricalSeries`. @h-mayorquin [#1796](https://github.com/NeurodataWithoutBorders/pynwb/pull/1796) -- Enhance `get_data_in_units()` to work with objects that have a `channel_conversion` attribute like the `ElectricalSeries` @h-mayorquin [#1806](https://github.com/NeurodataWithoutBorders/pynwb/pull/1806) +- Expose `starting_time` in `mock_ElectricalSeries`. @h-mayorquin [#1805](https://github.com/NeurodataWithoutBorders/pynwb/pull/1805) +- Enhance `get_data_in_units()` to work with objects that have a `channel_conversion` attribute like the `ElectricalSeries`. @h-mayorquin [#1806](https://github.com/NeurodataWithoutBorders/pynwb/pull/1806) ### Bug fixes - Fix bug where namespaces were loaded in "w-" mode. @h-mayorquin [#1795](https://github.com/NeurodataWithoutBorders/pynwb/pull/1795) diff --git a/src/pynwb/testing/mock/ecephys.py b/src/pynwb/testing/mock/ecephys.py index 8afa9ebc3..54edf7680 100644 --- a/src/pynwb/testing/mock/ecephys.py +++ b/src/pynwb/testing/mock/ecephys.py @@ -71,6 +71,7 @@ def mock_ElectricalSeries( data=None, rate: float = 30000.0, timestamps=None, + starting_time: Optional[float] = None, electrodes: Optional[DynamicTableRegion] = None, filtering: str = "filtering", nwbfile: Optional[NWBFile] = None, @@ -83,6 +84,7 @@ def mock_ElectricalSeries( description=description, data=data if data is not None else np.ones((10, 5)), rate=rate, + starting_time=starting_time, timestamps=timestamps, electrodes=electrodes or mock_electrodes(nwbfile=nwbfile), filtering=filtering, diff --git a/src/pynwb/testing/mock/ophys.py b/src/pynwb/testing/mock/ophys.py index d9ba02572..cd99d5957 100644 --- a/src/pynwb/testing/mock/ophys.py +++ b/src/pynwb/testing/mock/ophys.py @@ -132,6 +132,7 @@ def mock_OnePhotonSeries( conversion=conversion, timestamps=timestamps, starting_time=starting_time, + offset=offset, rate=rate, comments=comments, description=description, @@ -162,6 +163,7 @@ def mock_TwoPhotonSeries( dimension=None, resolution=-1.0, conversion=1.0, + offset=0.0, timestamps=None, starting_time=None, comments="no comments", @@ -194,6 +196,7 @@ def mock_TwoPhotonSeries( control=control, control_description=control_description, device=device, + offset=offset, ) if nwbfile is not None: From 883b1b15810b4a040698c9e40d717f143b3a3248 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 22 Dec 2023 14:55:13 -0500 Subject: [PATCH 6/8] RF: centralize invocation of coverage within run_coverage and use sys.executable -m coverage (#1811) Co-authored-by: Ryan Ly --- CHANGELOG.md | 1 + tests/validation/test_validate.py | 84 ++++++++++++------------------- 2 files changed, 34 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f38f6001d..c5cfa5a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Expose the offset, conversion and channel conversion parameters in `mock_ElectricalSeries`. @h-mayorquin [#1796](https://github.com/NeurodataWithoutBorders/pynwb/pull/1796) - Expose `starting_time` in `mock_ElectricalSeries`. @h-mayorquin [#1805](https://github.com/NeurodataWithoutBorders/pynwb/pull/1805) - Enhance `get_data_in_units()` to work with objects that have a `channel_conversion` attribute like the `ElectricalSeries`. @h-mayorquin [#1806](https://github.com/NeurodataWithoutBorders/pynwb/pull/1806) +- Refactor validation CLI tests to use `{sys.executable} -m coverage` to use the same Python version and run correctly on Debian systems. @yarikoptic [#1811](https://github.com/NeurodataWithoutBorders/pynwb/pull/1811) ### Bug fixes - Fix bug where namespaces were loaded in "w-" mode. @h-mayorquin [#1795](https://github.com/NeurodataWithoutBorders/pynwb/pull/1795) diff --git a/tests/validation/test_validate.py b/tests/validation/test_validate.py index 6aa2ee25e..c2829ee1f 100644 --- a/tests/validation/test_validate.py +++ b/tests/validation/test_validate.py @@ -1,5 +1,6 @@ import subprocess import re +import sys from unittest.mock import patch from io import StringIO import warnings @@ -8,26 +9,35 @@ from pynwb import validate, NWBHDF5IO +# NOTE we use "coverage run -m pynwb.validate" instead of "python -m pynwb.validate" +# so that we can both test pynwb.validate and compute code coverage from that test. +# NOTE we also use "coverage run -p" which will generate a .coverage file with the +# machine name, process id, and a random number appended to the filename to +# simplify collecting and merging coverage data from multiple subprocesses. if "-p" +# is not used, then each "coverage run" will overwrite the .coverage file from a +# previous "coverage run". +# NOTE we run "coverage" as "{sys.executable} -m coverage" to 1. make sure to use +# the same python version, and on Debian systems executable is "python3-coverage", not +# just "coverage". +# NOTE the run_coverage.yml GitHub Action runs "python -m coverage combine" to +# combine the individual coverage reports into one .coverage file. +def run_coverage(extra_args: list[str]): + return subprocess.run( + [sys.executable, "-m", "coverage", "run", "-p", "-m", "pynwb.validate"] + + extra_args, + capture_output=True + ) + + class TestValidateCLI(TestCase): # 1.0.2_nwbfile.nwb has no cached specifications # 1.0.3_nwbfile.nwb has cached "core" specification # 1.1.2_nwbfile.nwb has cached "core" and "hdmf-common" specifications - # NOTE we use "coverage run -m pynwb.validate" instead of "python -m pynwb.validate" - # so that we can both test pynwb.validate and compute code coverage from that test. - # NOTE we also use "coverage run -p" which will generate a .coverage file with the - # machine name, process id, and a random number appended to the filename to - # simplify collecting and merging coverage data from multiple subprocesses. if "-p" - # is not used, then each "coverage run" will overwrite the .coverage file from a - # previous "coverage run". - # NOTE the run_coverage.yml GitHub Action runs "python -m coverage combine" to - # combine the individual coverage reports into one .coverage file. - def test_validate_file_no_cache(self): """Test that validating a file with no cached spec against the core namespace succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/1.0.2_nwbfile.nwb"], capture_output=True) + result = run_coverage(["tests/back_compat/1.0.2_nwbfile.nwb"]) stderr_regex = re.compile( r"The file tests/back_compat/1\.0\.2_nwbfile\.nwb has no cached namespace information\. " @@ -42,8 +52,7 @@ def test_validate_file_no_cache(self): def test_validate_file_no_cache_bad_ns(self): """Test that validating a file with no cached spec against a specified, unknown namespace fails.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.0.2_nwbfile.nwb", - "--ns", "notfound"], capture_output=True) + result = run_coverage(["tests/back_compat/1.0.2_nwbfile.nwb", "--ns", "notfound"]) stderr_regex = re.compile( r"The file tests/back_compat/1\.0\.2_nwbfile\.nwb has no cached namespace information\. " @@ -57,8 +66,7 @@ def test_validate_file_no_cache_bad_ns(self): def test_validate_file_cached(self): """Test that validating a file with cached spec against its cached namespace succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/1.1.2_nwbfile.nwb"], capture_output=True) + result = run_coverage(["tests/back_compat/1.1.2_nwbfile.nwb"]) self.assertEqual(result.stderr.decode('utf-8'), '') @@ -69,8 +77,7 @@ def test_validate_file_cached(self): def test_validate_file_cached_bad_ns(self): """Test that validating a file with cached spec against a specified, unknown namespace fails.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/1.1.2_nwbfile.nwb", "--ns", "notfound"], capture_output=True) + result = run_coverage(["tests/back_compat/1.1.2_nwbfile.nwb", "--ns", "notfound"]) stderr_regex = re.compile( r"The namespace 'notfound' could not be found in cached namespace information as only " @@ -82,8 +89,7 @@ def test_validate_file_cached_bad_ns(self): def test_validate_file_cached_extension(self): """Test that validating a file with cached spec against the cached namespaces succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/2.1.0_nwbfile_with_extension.nwb"], capture_output=True) + result = run_coverage(["tests/back_compat/2.1.0_nwbfile_with_extension.nwb"]) self.assertEqual(result.stderr.decode('utf-8'), '') @@ -94,9 +100,7 @@ def test_validate_file_cached_extension(self): def test_validate_file_cached_extension_pass_ns(self): """Test that validating a file with cached spec against the extension namespace succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", - "--ns", "ndx-testextension"], capture_output=True) + result = run_coverage(["tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--ns", "ndx-testextension"]) self.assertEqual(result.stderr.decode('utf-8'), '') @@ -107,9 +111,7 @@ def test_validate_file_cached_extension_pass_ns(self): def test_validate_file_cached_core(self): """Test that validating a file with cached spec against the core namespace succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", - "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", - "--ns", "core"], capture_output=True) + result = run_coverage(["tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--ns", "core"]) stdout_regex = re.compile( r"The namespace 'core' is included by the namespace 'ndx-testextension'. " @@ -119,8 +121,7 @@ def test_validate_file_cached_core(self): def test_validate_file_cached_hdmf_common(self): """Test that validating a file with cached spec against the hdmf-common namespace fails.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", - "--ns", "hdmf-common"], capture_output=True) + result = run_coverage(["tests/back_compat/1.1.2_nwbfile.nwb", "--ns", "hdmf-common"]) stderr_regex = re.compile( r"The namespace 'hdmf-common' is included by the namespace 'core'\. Please validate against that " @@ -130,8 +131,7 @@ def test_validate_file_cached_hdmf_common(self): def test_validate_file_cached_ignore(self): """Test that validating a file with cached spec against the core namespace succeeds.""" - result = subprocess.run(["coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", - "--no-cached-namespace"], capture_output=True) + result = run_coverage(["tests/back_compat/1.1.2_nwbfile.nwb", "--no-cached-namespace"]) self.assertEqual(result.stderr.decode('utf-8'), '') @@ -142,13 +142,7 @@ def test_validate_file_cached_ignore(self): def test_validate_file_invalid(self): """Test that validating an invalid file outputs errors.""" - result = subprocess.run( - [ - "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.0.2_str_experimenter.nwb", - "--no-cached-namespace" - ], - capture_output=True - ) + result = run_coverage(["tests/back_compat/1.0.2_str_experimenter.nwb", "--no-cached-namespace"]) stderr_regex = re.compile( r" - found the following errors:\s*" @@ -164,13 +158,7 @@ def test_validate_file_invalid(self): def test_validate_file_list_namespaces_core(self): """Test listing namespaces from a file""" - result = subprocess.run( - [ - "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/1.1.2_nwbfile.nwb", - "--list-namespaces" - ], - capture_output=True - ) + result = run_coverage(["tests/back_compat/1.1.2_nwbfile.nwb", "--list-namespaces"]) self.assertEqual(result.stderr.decode('utf-8'), '') @@ -179,13 +167,7 @@ def test_validate_file_list_namespaces_core(self): def test_validate_file_list_namespaces_extension(self): """Test listing namespaces from a file with an extension""" - result = subprocess.run( - [ - "coverage", "run", "-p", "-m", "pynwb.validate", "tests/back_compat/2.1.0_nwbfile_with_extension.nwb", - "--list-namespaces" - ], - capture_output=True - ) + result = run_coverage(["tests/back_compat/2.1.0_nwbfile_with_extension.nwb", "--list-namespaces"]) self.assertEqual(result.stderr.decode('utf-8'), '') From 306048faa5153b31d48cf0d2526ee68939a381d8 Mon Sep 17 00:00:00 2001 From: Ryan Ly Date: Wed, 10 Jan 2024 10:59:56 -0800 Subject: [PATCH 7/8] Fix broken links in docs (#1816) --- docs/source/install_users.rst | 2 +- docs/source/software_process.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/install_users.rst b/docs/source/install_users.rst index 6e33c2035..368ab7bd0 100644 --- a/docs/source/install_users.rst +++ b/docs/source/install_users.rst @@ -34,7 +34,7 @@ This will automatically install the following required dependencies: Install release from Conda-forge -------------------------------- -`Conda-forge `_ is a community led collection of recipes, build infrastructure +`Conda-forge `_ is a community led collection of recipes, build infrastructure and distributions for the `conda `_ package manager. To install or update PyNWB distribution from conda-forge using conda simply run: diff --git a/docs/source/software_process.rst b/docs/source/software_process.rst index f2ccb335d..07fd97246 100644 --- a/docs/source/software_process.rst +++ b/docs/source/software_process.rst @@ -17,7 +17,7 @@ tested on all supported operating systems and python distributions. That way, as a contributor, you know if you introduced regressions or coding style inconsistencies. -There are badges in the :pynwb:`README <#readme>` file which shows +There are badges in the :pynwb:`README ` file which shows the current condition of the dev branch. -------- @@ -25,7 +25,7 @@ Coverage -------- Code coverage is computed and reported using the coverage_ tool. There are two coverage-related -badges in the :pynwb:`README <#readme>` file. One shows the status of the :pynwb:`GitHub Action workflow ` which runs the coverage_ tool and uploads the report to +badges in the :pynwb:`README ` file. One shows the status of the :pynwb:`GitHub Action workflow ` which runs the coverage_ tool and uploads the report to codecov_, and the other badge shows the percentage coverage reported from codecov_. A detailed report can be found on codecov_, which shows line by line which lines are covered by the tests. From 60ec8fe436c2eea1ec60b762648b5914165d707b Mon Sep 17 00:00:00 2001 From: Ryan Ly Date: Wed, 10 Jan 2024 16:13:11 -0800 Subject: [PATCH 8/8] Update dandi req in environment-ros3.yml (#1817) --- environment-ros3.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment-ros3.yml b/environment-ros3.yml index ae15e985c..2bf2678d2 100644 --- a/environment-ros3.yml +++ b/environment-ros3.yml @@ -12,7 +12,7 @@ dependencies: - pandas==2.0.0 - python-dateutil==2.8.2 - setuptools - - dandi==0.55.1 # NOTE: dandi does not support osx-arm64 + - dandi==0.59.0 # NOTE: dandi does not support osx-arm64 - fsspec==2023.6.0 - requests==2.28.1 - aiohttp==3.8.3