diff --git a/.github/workflows/cc-plugin-glider-test.yml b/.github/workflows/cc-plugin-glider-test.yml index 82cb9030..97ed4745 100644 --- a/.github/workflows/cc-plugin-glider-test.yml +++ b/.github/workflows/cc-plugin-glider-test.yml @@ -19,7 +19,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/cc-plugin-sgrid-test.yml b/.github/workflows/cc-plugin-sgrid-test.yml index e8872401..b8c8bd7e 100644 --- a/.github/workflows/cc-plugin-sgrid-test.yml +++ b/.github/workflows/cc-plugin-sgrid-test.yml @@ -19,7 +19,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/cc-plugin-ugrid-test.yml b/.github/workflows/cc-plugin-ugrid-test.yml index b3b74d36..696a2c27 100644 --- a/.github/workflows/cc-plugin-ugrid-test.yml +++ b/.github/workflows/cc-plugin-ugrid-test.yml @@ -19,7 +19,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index c32a9fb4..8a15d437 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -19,7 +19,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/default-tests.yml b/.github/workflows/default-tests.yml index 68b90948..0f23856d 100644 --- a/.github/workflows/default-tests.yml +++ b/.github/workflows/default-tests.yml @@ -24,7 +24,7 @@ jobs: create-args: >- python=${{ matrix.python-version }} pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 6b0fe0da..bdbd2cd7 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -26,7 +26,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 87c46cfe..75e24b10 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -19,7 +19,7 @@ jobs: create-args: >- python=3 pip --file requirements.txt - --file test_requirements.txt + --file requirements-test.txt --channel conda-forge - name: Install compliance-checker diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 805ce058..fb8d407d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,9 @@ repos: - id: requirements-txt-fixer args: - requirements.txt - - test_requirements.txt + - requirements-dev.txt + - requirements-docs.txt + - requirements-test.txt - repo: https://github.com/psf/black rev: 24.4.0 diff --git a/cchecker.py b/cchecker.py index fd3ef88b..4e5ed5d4 100755 --- a/cchecker.py +++ b/cchecker.py @@ -232,7 +232,7 @@ def main(): check_suite.load_generated_checkers(args) if args.version: - print("IOOS compliance checker version %s" % __version__) + print(f"IOOS compliance checker version {__version__}") sys.exit(0) options_dict = parse_options(args.option) if args.option else defaultdict(set) diff --git a/compliance_checker/acdd.py b/compliance_checker/acdd.py index 9b0abdc7..73d681c1 100644 --- a/compliance_checker/acdd.py +++ b/compliance_checker/acdd.py @@ -626,7 +626,7 @@ def check_time_extents(self, ds): BaseCheck.MEDIUM, False, "time_coverage_extents_match", - ["Failed to retrieve and convert times for variables %s." % timevar], + [f"Failed to retrieve and convert times for variables {timevar}."], ) start_dt = abs(time0 - t_min) diff --git a/compliance_checker/cf/cf_1_6.py b/compliance_checker/cf/cf_1_6.py index f059e0f7..4b45b3e9 100644 --- a/compliance_checker/cf/cf_1_6.py +++ b/compliance_checker/cf/cf_1_6.py @@ -302,7 +302,7 @@ def check_names_unique(self, ds): names[k.lower()] += 1 fails = [ - "Variables are not case sensitive. Duplicate variables named: %s" % k + f"Variables are not case sensitive. Duplicate variables named: {k}" for k, v in names.items() if v > 1 ] @@ -1822,7 +1822,7 @@ def check_time_coordinate(self, ds): BaseCheck.HIGH, False, self.section_titles["4.4"], - ["%s does not have units" % name], + [f"{name} does not have units"], ) ret_val.append(result) continue @@ -1833,7 +1833,7 @@ def check_time_coordinate(self, ds): correct_units = util.units_temporal(variable.units) reasoning = None if not correct_units: - reasoning = ["%s does not have correct time units" % name] + reasoning = [f"{name} does not have correct time units"] result = Result( BaseCheck.HIGH, correct_units, diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index 6f100653..6bfe1e8b 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -199,9 +199,9 @@ def __init__(self, entrynode): def _get(self, entrynode, attrname, required=False): vals = entrynode.xpath(attrname) if len(vals) > 1: - raise Exception("Multiple attrs (%s) found" % attrname) + raise Exception(f"Multiple attrs ({attrname}) found") elif required and len(vals) == 0: - raise Exception("Required attr (%s) not found" % attrname) + raise Exception(f"Required attr ({attrname}) not found") return vals[0].text @@ -236,7 +236,7 @@ def __len__(self): def __getitem__(self, key): if not (key in self._names or key in self._aliases): - raise KeyError("%s not found in standard name table" % key) + raise KeyError(f"{key} not found in standard name table") if key in self._aliases: idx = self._aliases.index(key) @@ -244,14 +244,13 @@ def __getitem__(self, key): if len(entryids) != 1: raise Exception( - "Inconsistency in standard name table, could not lookup alias for %s" - % key, + f"Inconsistency in standard name table, could not lookup alias for {key}", ) key = entryids[0].text if key not in self._names: - raise KeyError("%s not found in standard name table" % key) + raise KeyError(f"{key} not found in standard name table") idx = self._names.index(key) entry = self.NameEntry(self._root.xpath("entry")[idx]) @@ -289,7 +288,11 @@ def download_cf_standard_name_table(version, location=None): if version == "latest": url = "http://cfconventions.org/Data/cf-standard-names/current/src/cf-standard-name-table.xml" else: - url = f"http://cfconventions.org/Data/cf-standard-names/{version}/src/cf-standard-name-table.xml" + if version.startswith("http"): + url = version + version = '"url specified"' + else: + url = f"http://cfconventions.org/Data/cf-standard-names/{version}/src/cf-standard-name-table.xml" r = requests.get(url, allow_redirects=True) r.raise_for_status() diff --git a/compliance_checker/runner.py b/compliance_checker/runner.py index 0a8c6d2f..536888f5 100644 --- a/compliance_checker/runner.py +++ b/compliance_checker/runner.py @@ -125,7 +125,7 @@ def run_checker( cls.json_output(cs, score_dict, output_filename, ds_loc, limit, out_fmt) else: - raise TypeError("Invalid format %s" % out_fmt) + raise TypeError(f"Invalid format {out_fmt}") errors_occurred = cls.check_errors(score_groups, verbose) @@ -259,8 +259,7 @@ def check_errors(cls, score_groups, verbose): if len(errors): errors_occurred = True print( - "WARNING: The following exceptions occurred during the %s checker (possibly indicate compliance checker issues):" - % checker, + f"WARNING: The following exceptions occurred during the {checker} checker (possibly indicate compliance checker issues):", file=sys.stderr, ) for check_name, epair in errors.items(): diff --git a/compliance_checker/tests/conftest.py b/compliance_checker/tests/conftest.py index 2c662c16..d78fcbb1 100644 --- a/compliance_checker/tests/conftest.py +++ b/compliance_checker/tests/conftest.py @@ -91,7 +91,7 @@ def new_nc_file(tmpdir): """ nc_file_path = os.path.join(tmpdir, "example.nc") if os.path.exists(nc_file_path): - raise OSError("File Exists: %s" % nc_file_path) + raise OSError(f"File Exists: {nc_file_path}") nc = Dataset(nc_file_path, "w") # no need for cleanup, built-in tmpdir fixture will handle it return nc @@ -101,7 +101,7 @@ def new_nc_file(tmpdir): def tmp_txt_file(tmpdir): file_path = os.path.join(tmpdir, "output.txt") if os.path.exists(file_path): - raise OSError("File Exists: %s" % file_path) + raise OSError(f"File Exists: {file_path}") return file_path diff --git a/compliance_checker/tests/test_base.py b/compliance_checker/tests/test_base.py index 18cc6c7b..08401127 100644 --- a/compliance_checker/tests/test_base.py +++ b/compliance_checker/tests/test_base.py @@ -65,7 +65,7 @@ def test_attr_in_valid_choices(self): priority, (1, 2), "test", - ["test present, but not in expected value list (%s)" % valid_choices], + [f"test present, but not in expected value list ({valid_choices})"], ) self.ds.test = "a" base.attr_check(attr, self.ds, priority, rv3) diff --git a/compliance_checker/tests/test_cf.py b/compliance_checker/tests/test_cf.py index 292bfd82..5e13bb7b 100644 --- a/compliance_checker/tests/test_cf.py +++ b/compliance_checker/tests/test_cf.py @@ -86,7 +86,7 @@ def new_nc_file(self): """ nc_file_path = os.path.join(gettempdir(), "example.nc") if os.path.exists(nc_file_path): - raise OSError("File Exists: %s" % nc_file_path) + raise OSError(f"File Exists: {nc_file_path}") nc = Dataset(nc_file_path, "w") self.addCleanup(os.remove, nc_file_path) self.addCleanup(nc.close) diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..704f1027 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,10 @@ +flake8 +flake8-builtins +flake8-comprehensions +flake8-mutable +flake8-print +httpretty +pre-commit +pytest +pytest-flake8 +requests-mock diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 00000000..c7022057 --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,4 @@ +myst-parser +numpydoc +pydata-sphinx-theme +sphinx diff --git a/test_requirements.txt b/requirements-test.txt similarity index 100% rename from test_requirements.txt rename to requirements-test.txt diff --git a/requirements.txt b/requirements.txt index fd3bbe9a..4289d060 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,15 @@ -cf-units>=2 -cftime>=1.1.0 +cf-units importlib-metadata # drop this when dropping Python 3.8 importlib-resources # drop this when dropping Python 3.8 -isodate>=0.6.1 -jinja2>=2.7.3 -lxml>=3.2.1 -netcdf4>=1.6.4 -owsLib>=0.8.3 +isodate +lxml +netcdf4 +owslib packaging -pendulum>=1.2.4 -pygeoif>=0.6 -pyproj>=2.2.1 -regex>=2017.07.28 -requests>=2.2.1 -setuptools>=15.0 -shapely>=1.7.1 -validators>=0.14.2 +pendulum +pygeoif +pyproj +regex +requests +shapely +validators