From 41f221e1f8e1d32e139e009a3dd40884e9193730 Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Tue, 30 Apr 2024 12:37:54 -0700 Subject: [PATCH 1/8] Allow specification of CF source by url --- compliance_checker/cf/util.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index 6f100653..3c125812 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -289,7 +289,13 @@ 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/{}/src/cf-standard-name-table.xml".format( + version + ) r = requests.get(url, allow_redirects=True) r.raise_for_status() From c17f5f61eb37027bfae4a1522f270ffd6ef189ba Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Tue, 30 Apr 2024 12:40:15 -0700 Subject: [PATCH 2/8] Remove f-string specifier --- compliance_checker/cf/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index 3c125812..6ae1be12 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -293,7 +293,7 @@ def download_cf_standard_name_table(version, location=None): url = version version = '"url specified"' else: - url = f"http://cfconventions.org/Data/cf-standard-names/{}/src/cf-standard-name-table.xml".format( + url = "http://cfconventions.org/Data/cf-standard-names/{}/src/cf-standard-name-table.xml".format( version ) From e4f13f995ccb1652edb313d45870153d70036fcc Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Sun, 12 May 2024 18:04:15 -0700 Subject: [PATCH 3/8] ruff recommended updates * Convert print statements to f-strings --- cchecker.py | 2 +- compliance_checker/acdd.py | 2 +- compliance_checker/cf/cf_1_6.py | 6 +++--- compliance_checker/cf/util.py | 15 ++++++--------- compliance_checker/runner.py | 5 ++--- compliance_checker/tests/conftest.py | 4 ++-- compliance_checker/tests/test_base.py | 2 +- compliance_checker/tests/test_cf.py | 2 +- 8 files changed, 17 insertions(+), 21 deletions(-) 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 6ae1be12..e46aa688 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]) @@ -293,9 +292,7 @@ def download_cf_standard_name_table(version, location=None): url = version version = '"url specified"' else: - url = "http://cfconventions.org/Data/cf-standard-names/{}/src/cf-standard-name-table.xml".format( - version - ) + 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) From a4819db7a7e6be7714490f538d51db62a09da06e Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Mon, 13 May 2024 17:07:29 -0700 Subject: [PATCH 4/8] Updates with python black linter --- compliance_checker/cf/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index e46aa688..608e1f3a 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -288,7 +288,7 @@ 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: - if version.startswith('http'): + if version.startswith("http"): url = version version = '"url specified"' else: From b49f60f41ab653bdfba55d520e8363de32ffeac7 Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Mon, 13 May 2024 17:26:27 -0700 Subject: [PATCH 5/8] Updates * add-trailing-commas fix for cf/util.py * adjust requirement.txt files to conform to plugin format * remove pinning; works with python 3.11 --- compliance_checker/cf/util.py | 2 +- requirements-dev.txt | 11 ++++++++ requirements-docs.txt | 4 +++ ..._requirements.txt => requirements-test.txt | 0 requirements.txt | 27 +++++++++---------- 5 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 requirements-dev.txt create mode 100644 requirements-docs.txt rename test_requirements.txt => requirements-test.txt (100%) diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index 608e1f3a..6bfe1e8b 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -244,7 +244,7 @@ def __getitem__(self, key): if len(entryids) != 1: raise Exception( - f"Inconsistency in standard name table, could not lookup alias for {key}" + f"Inconsistency in standard name table, could not lookup alias for {key}", ) key = entryids[0].text diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..d0074e4e --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,11 @@ +add-trailing-comma +black +flake8 +flake8-builtins +flake8-comprehensions +flake8-mutable +flake8-print +httpretty +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..7929767c 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 +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 +netcdf4 +regex +requests +shapely +validators From 4ab682ff00fd24e1632641059a43fde36abb6267 Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Mon, 13 May 2024 17:38:53 -0700 Subject: [PATCH 6/8] Updates * Update pre-commit-config with requirements files * Fix sorting on requirements.txt * Add pre-commit for local testing first; add to requirements-dev.txt --- .pre-commit-config.yaml | 4 +++- requirements-dev.txt | 1 + requirements.txt | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) 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/requirements-dev.txt b/requirements-dev.txt index d0074e4e..6153856a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,6 +6,7 @@ flake8-comprehensions flake8-mutable flake8-print httpretty +pre-commit pytest pytest-flake8 requests-mock diff --git a/requirements.txt b/requirements.txt index 7929767c..4289d060 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,12 +3,12 @@ importlib-metadata # drop this when dropping Python 3.8 importlib-resources # drop this when dropping Python 3.8 isodate lxml +netcdf4 owslib packaging pendulum pygeoif pyproj -netcdf4 regex requests shapely From a6bb792f9efaa2ffc820950291feb1b4b9acb5da Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Mon, 13 May 2024 17:49:27 -0700 Subject: [PATCH 7/8] Removed items that pre-commit installs itself --- requirements-dev.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 6153856a..704f1027 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,3 @@ -add-trailing-comma -black flake8 flake8-builtins flake8-comprehensions From 9069b06e728c070a16b1bac080d5c317eb93d26e Mon Sep 17 00:00:00 2001 From: Rob Cermak Date: Mon, 13 May 2024 18:15:51 -0700 Subject: [PATCH 8/8] Adjust workflow to use requirements-test.txt --- .github/workflows/cc-plugin-glider-test.yml | 2 +- .github/workflows/cc-plugin-sgrid-test.yml | 2 +- .github/workflows/cc-plugin-ugrid-test.yml | 2 +- .github/workflows/codecov.yml | 2 +- .github/workflows/default-tests.yml | 2 +- .github/workflows/deploy-docs.yml | 2 +- .github/workflows/integration-tests.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) 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