From 70903261cd75dc40b350b4fd103ebc5bf906ff58 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:19:21 -0300 Subject: [PATCH 01/11] update --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a1effd4..5dcb8a2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: seawater/tests/seawater_v3_3/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: check-ast @@ -16,12 +16,12 @@ repos: files: requirements-dev.txt - repo: https://github.com/keewis/blackdoc - rev: v0.3.9 + rev: v0.4.6 hooks: - id: blackdoc - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.1 hooks: - id: codespell exclude: > @@ -32,12 +32,12 @@ repos: - --ignore-words-list=pres,delt,arry - repo: https://github.com/asottile/add-trailing-comma - rev: v3.1.0 + rev: v4.0.0 hooks: - id: add-trailing-comma - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.6 + rev: v0.14.14 hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -45,7 +45,7 @@ repos: - repo: https://github.com/tox-dev/pyproject-fmt - rev: 2.1.3 + rev: v2.11.1 hooks: - id: pyproject-fmt From 05bad9a5077cecd7f4905c31cfe4b385099c0032 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:19:52 -0300 Subject: [PATCH 02/11] fix metadata --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 72cce39..82c9645 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,8 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dynamic = [ "dependencies", From 5ddaa8ca3f37795a1e10f00deb7e1f9925a2a6ca Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:20:08 -0300 Subject: [PATCH 03/11] lints --- seawater/eos80.py | 14 +++---- seawater/geostrophic.py | 2 +- seawater/library.py | 6 +-- seawater/tests/sw_test.py | 88 +++++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 55 deletions(-) diff --git a/seawater/eos80.py b/seawater/eos80.py index 9bd6f2a..f33ab55 100644 --- a/seawater/eos80.py +++ b/seawater/eos80.py @@ -8,17 +8,17 @@ "alpha", "aonb", "beta", + "cp", + "dens", + "dens0", "dpth", - "g", - "salt", "fp", - "svel", - "pres", - "dens0", - "dens", + "g", "pden", - "cp", + "pres", "ptmp", + "salt", + "svel", "temp", ] diff --git a/seawater/geostrophic.py b/seawater/geostrophic.py index 371f850..7bc3c00 100644 --- a/seawater/geostrophic.py +++ b/seawater/geostrophic.py @@ -7,9 +7,9 @@ __all__ = [ "bfrq", - "svan", "gpan", "gvel", + "svan", ] diff --git a/seawater/library.py b/seawater/library.py index 4e0f18f..cfda96c 100644 --- a/seawater/library.py +++ b/seawater/library.py @@ -1,15 +1,15 @@ import numpy as np __all__ = [ + "T68conv", + "T90conv", "cndr", "salds", "salrp", "salrt", - "seck", "sals", + "seck", "smow", - "T68conv", - "T90conv", ] diff --git a/seawater/tests/sw_test.py b/seawater/tests/sw_test.py index d5587b9..dbbc0c8 100644 --- a/seawater/tests/sw_test.py +++ b/seawater/tests/sw_test.py @@ -102,10 +102,10 @@ def test(fileout="python-test.txt"): PT[:, icol], ), ) - for iline in range(m): - f.write( - " %4.0f %4.0f %5.0f %8.4f %11.5f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %5.0f %8.4f %11.5f\n" % tuple(result[:, iline]) + for iline in range(m) + ) # Test main module svan. f.write("\n%s" % asterisks) @@ -144,10 +144,10 @@ def test(fileout="python-test.txt"): f.write("\n Sal Temp Press SVAN svan") f.write("\n (psu) (C) (db) (1e-8*m3/kg) (1e-8*m3/kg)\n") result = np.vstack([s, t, p, UN_svan, 1e8 * SVAN]) - for iline in range(len(SVAN)): - f.write( - " %4.0f %4.0f %5.0f %11.2f %11.3f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %5.0f %11.2f %11.3f\n" % tuple(result[:, iline]) + for iline in range(len(SVAN)) + ) # Test main module salt. f.write("\n%s" % asterisks) @@ -177,10 +177,10 @@ def test(fileout="python-test.txt"): f.write("\n (C) (db) (no units) (psu) (psu)\n") table = np.vstack([T, P, R, UN_S, S]) m, n = table.shape - for iline in range(n): - f.write( - " %4.0f %4.0f %8.2f %11.6f %14.7f\n" % tuple(table[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %8.2f %11.6f %14.7f\n" % tuple(table[:, iline]) + for iline in range(n) + ) # Test main module cndr. f.write("\n%s" % asterisks) @@ -217,10 +217,10 @@ def test(fileout="python-test.txt"): f.write("\n (C) (db) (psu) (no units) (no units)\n") table = np.vstack([T, P, S, UN_R, R]) m, n = table.shape - for iline in range(n): - f.write( - " %4.0f %4.0f %8.6f %11.6f %14.8f\n" % tuple(table[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %8.6f %11.6f %14.8f\n" % tuple(table[:, iline]) + for iline in range(n) + ) # Test main module depth. f.write("\n%s" % asterisks) @@ -261,10 +261,10 @@ def test(fileout="python-test.txt"): f.write("\n (degree) (db) (meter) (meter)\n") table = np.vstack([lat, P[irow, :], UN_dpth[irow, :], dpth[irow, :]]) m, n = table.shape - for iline in range(n): - f.write( - " %6.3f %6.0f %8.2f %8.3f\n" % tuple(table[:, iline]), - ) + f.writelines( + " %6.3f %6.0f %8.2f %8.3f\n" % tuple(table[:, iline]) + for iline in range(n) + ) # Test main module fp. f.write("\n%s" % asterisks) @@ -334,10 +334,10 @@ def test(fileout="python-test.txt"): ], ) m, n = table.shape - for iline in range(n): - f.write( - " %4.0f %5.0f %8.3f %11.4f\n" % tuple(table[:, iline]), - ) + f.writelines( + " %4.0f %5.0f %8.3f %11.4f\n" % tuple(table[:, iline]) + for iline in range(n) + ) # Test main module cp. f.write("\n%s" % asterisks) @@ -413,10 +413,10 @@ def test(fileout="python-test.txt"): CP[:, icol], ], ) - for iline in range(m): - f.write( - " %4.0f %4.0f %5.0f %8.1f %11.2f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %5.0f %8.1f %11.2f\n" % tuple(result[:, iline]) + for iline in range(m) + ) # Test main module svel. f.write("\n%s" % asterisks) @@ -493,10 +493,10 @@ def test(fileout="python-test.txt"): SVEL[:, icol], ], ) - for iline in range(m): - f.write( - " %4.0f %4.0f %5.0f %8.1f %11.3f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %5.0f %8.1f %11.3f\n" % tuple(result[:, iline]) + for iline in range(m) + ) # Test submodules alpha beta aonb. f.write("\n%s" % asterisks) @@ -625,10 +625,10 @@ def test(fileout="python-test.txt"): O2[:, icol], ], ) - for iline in range(m): - f.write( - " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]) + for iline in range(m) + ) for icol in range(n): f.write("\n Sal Temp N2 satN2") @@ -641,10 +641,10 @@ def test(fileout="python-test.txt"): N2[:, icol], ], ) - for iline in range(m): - f.write( - " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]) + for iline in range(m) + ) for icol in range(n): f.write("\n Sal Temp Ar satAr") @@ -657,10 +657,10 @@ def test(fileout="python-test.txt"): Ar[:, icol], ], ) - for iline in range(m): - f.write( - " %4.0f %4.0f %8.4f %9.4f\n" % tuple(result[:, iline]), - ) + f.writelines( + " %4.0f %4.0f %8.4f %9.4f\n" % tuple(result[:, iline]) + for iline in range(m) + ) if __name__ == "__main__": From 0c59f72a95d890c97743a87acb7e673c52236339 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:27:39 -0300 Subject: [PATCH 04/11] skip conflicting COM812 rule --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index 4dd06af..762dc34 100644 --- a/ruff.toml +++ b/ruff.toml @@ -3,6 +3,7 @@ line-length = 90 lint.select = ["ALL"] lint.ignore = [ + "COM812", # missing-trailing-comma "ANN001", # Missing type annotation for function argument "ANN002", # Missing type annotation for `*arys` "ANN101", # Missing type annotation for `self` in method From 90195f26c0858a52f9e704c40a7a61160d1d0dcd Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:27:46 -0300 Subject: [PATCH 05/11] fix all security issues --- .github/dependabot.yml | 2 ++ .github/workflows/deploy-docs.yml | 6 ++++++ .github/workflows/tests.yml | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7818bef..6c93c11 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,3 +13,5 @@ updates: github-actions: patterns: - '*' + cooldown: + default-days: 7 diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 26c4c33..3e38eb5 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,5 +1,8 @@ name: Documentation +# no permissions by default +permissions: {} + on: pull_request: push: @@ -12,12 +15,15 @@ on: jobs: build-docs: runs-on: ubuntu-latest + permissions: + contents: write steps: - name: checkout uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 with: fetch-depth: 0 + persist-credentials: false - name: Setup Micromamba uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4f414e6..91afd84 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,5 +1,8 @@ name: Full Tests +# no permissions by default +permissions: {} + on: pull_request: push: @@ -10,12 +13,15 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] - os: [ubuntu-latest] + python-version: [ "3.10", "3.11", "3.12", "3.13" , "3.14" ] + os: [ ubuntu-latest ] fail-fast: false steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 + with: + fetch-depth: 0 + persist-credentials: false - name: Setup Micromamba Python ${{ matrix.python-version }} uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7 From 0e2a073d59b32e62043337bc02190acac1b52b04 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:28:13 -0300 Subject: [PATCH 06/11] add zizmor checks --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5dcb8a2..35a1c76 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,6 +49,11 @@ repos: hooks: - id: pyproject-fmt +- repo: https://github.com/woodruffw/zizmor-pre-commit + rev: v1.22.0 + hooks: + - id: zizmor + ci: autofix_commit_msg: | [pre-commit.ci] auto fixes from pre-commit.com hooks From a44c401a30ee322dd788778c32cf0acf8c674a8e Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:28:21 -0300 Subject: [PATCH 07/11] lint --- seawater/tests/sw_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/seawater/tests/sw_test.py b/seawater/tests/sw_test.py index dbbc0c8..f8e3aef 100644 --- a/seawater/tests/sw_test.py +++ b/seawater/tests/sw_test.py @@ -7,8 +7,9 @@ import seawater as sw -def test(fileout="python-test.txt"): +def test(): """Copy of the Matlab test.""" + fileout = "python-test.txt" f = open(fileout, "w") asterisks = "*" * 76 From bb1690b4f5ead39f0fd9f6a2a68e6d42c92d0fe3 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:47:33 -0300 Subject: [PATCH 08/11] try numpy>2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fc52dc5..dc49729 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -numpy<2 +numpy>=2 scipy From 7bfc97671d983832e2ead1e8b1b0f7ea6c8f5f0c Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:47:37 -0300 Subject: [PATCH 09/11] fix metadata --- pyproject.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 82c9645..eae343d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,11 +14,9 @@ license = { file = "LICENSE.txt" } maintainers = [ { name = "Filipe Fernandes", email = "ocefpaf+seawater@gmail.com" }, ] -requires-python = ">=3.8" +requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", From 4fabd8cda6b54c6866f09a76a78364666b0777f5 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 13:59:13 -0300 Subject: [PATCH 10/11] fix for numpy 2 --- seawater/eos80.py | 12 ++++++------ seawater/extras.py | 4 ++-- seawater/library.py | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/seawater/eos80.py b/seawater/eos80.py index f33ab55..fcf656a 100644 --- a/seawater/eos80.py +++ b/seawater/eos80.py @@ -133,7 +133,7 @@ def alpha(s, t, p, *, pt=False): >>> import seawater as sw >>> s, t, p = 40, 10, 4000 >>> sw.alpha(s, t, p, pt=True) - 0.00025061316481624323 + np.float64(0.00025061316481624323) References ---------- @@ -170,7 +170,7 @@ def aonb(s, t, p, *, pt=False): >>> import seawater as sw >>> s, t, p = 40, 10, 4000 >>> sw.aonb(s, t, p, pt=True) - 0.347650567047807 + np.float64(0.347650567047807) References ---------- @@ -241,7 +241,7 @@ def beta(s, t, p, *, pt=False): >>> import seawater as sw >>> s, t, p = 40, 10, 4000 >>> sw.beta(s, t, p, pt=True) - 0.0007208766174161893 + np.float64(0.0007208766174161893) References ---------- @@ -612,7 +612,7 @@ def g(lat, z=0): -------- >>> import seawater as sw >>> sw.g(45, z=0) - 9.8061898752054 + np.float64(9.8061898752054) References ---------- @@ -705,7 +705,7 @@ def pres(depth, lat): >>> import seawater as sw >>> depth, lat = 7321.45, 30 >>> sw.pres(depth, lat) - 7500.006513011802 + np.float64(7500.006513011802) References ---------- @@ -1020,7 +1020,7 @@ def temp(s, pt, p, pr=0): >>> import seawater as sw >>> s, t, p = 35, 15, 100 >>> sw.temp(s, sw.ptmp(s, t, p), p) - 15.0 + np.float64(15.0) References ---------- diff --git a/seawater/extras.py b/seawater/extras.py index f0902da..82b65bf 100644 --- a/seawater/extras.py +++ b/seawater/extras.py @@ -111,7 +111,7 @@ def f(lat): -------- >>> import seawater as sw >>> sw.f(45) - 0.00010312445296824608 + np.float64(0.00010312445296824608) References ---------- @@ -316,7 +316,7 @@ def swvel(length, depth): -------- >>> import seawater as sw >>> sw.swvel(10, 100) - 3.949327084834294 + np.float64(3.949327084834294) """ length, depth = list(map(np.asanyarray, (length, depth))) diff --git a/seawater/library.py b/seawater/library.py index cfda96c..8c6b78a 100644 --- a/seawater/library.py +++ b/seawater/library.py @@ -437,7 +437,7 @@ def T68conv(T90): -------- >>> import seawater as sw >>> T68conv(19.995201151723585) - 20.0 + np.float64(20.0) References ---------- @@ -483,9 +483,9 @@ def T90conv(t, t_type="T68"): Examples -------- >>> T90conv(20.004799999999999) - 20.0 + np.float64(20.0) >>> T90conv(20.0, t_type="T48") - 19.98816284091818 + np.float64(19.98816284091818) References ---------- From aca5d98a5d3897cd392d99447dc0dd8f6d035d08 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Fri, 23 Jan 2026 15:28:28 -0300 Subject: [PATCH 11/11] split octace tests --- .github/workflows/tests.yml | 4 +- .github/workflows/tests_octave.yml | 42 +++++++ seawater/library.py | 2 +- seawater/tests/test_result_comparison.py | 140 +++++++++++++++-------- 4 files changed, 138 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/tests_octave.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 91afd84..19794b1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: environment-name: TEST init-shell: bash create-args: >- - python=${{ matrix.python-version }} --file requirements.txt --file requirements-dev.txt octave --channel conda-forge + python=${{ matrix.python-version }} --file requirements.txt --file requirements-dev.txt --channel conda-forge - name: Install seawater shell: bash -l {0} @@ -39,4 +39,4 @@ jobs: - name: Full Tests shell: bash -l {0} run: | - python -m pytest -rxs --doctest-modules --pyargs seawater + python -m pytest -rxs -m "not octave" --doctest-modules --pyargs seawater diff --git a/.github/workflows/tests_octave.yml b/.github/workflows/tests_octave.yml new file mode 100644 index 0000000..68dcb5d --- /dev/null +++ b/.github/workflows/tests_octave.yml @@ -0,0 +1,42 @@ +name: Full Tests + +# no permissions by default +permissions: {} + +on: + pull_request: + push: + branches: [main] + +jobs: + run: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [ "3.10" ] + os: [ ubuntu-latest ] + fail-fast: false + + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Micromamba Python ${{ matrix.python-version }} + uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7 + with: + environment-name: TEST + init-shell: bash + create-args: >- + python=${{ matrix.python-version }} octave=6 --file requirements.txt --file requirements-dev.txt --channel conda-forge + + - name: Install seawater + shell: bash -l {0} + run: | + python -m pip install -e . --no-deps --force-reinstall + + - name: Full Tests + shell: bash -l {0} + run: | + python -m pytest -rxs -m "octave" --doctest-modules --pyargs seawater diff --git a/seawater/library.py b/seawater/library.py index 8c6b78a..101729e 100644 --- a/seawater/library.py +++ b/seawater/library.py @@ -66,7 +66,7 @@ def cndr(s, t, p): s, t = list(map(np.ravel, (s, t))) # Do a Newton-Raphson iteration for inverse interpolation of Rt from s. Rx = [] - for S, T in zip(s, t): + for S, T in zip(s, t, strict=True): Rx_loop = np.sqrt(S / 35.0) # first guess at Rx = sqrt(Rt). SInc = sals(Rx_loop * Rx_loop, T) # S Increment (guess) from Rx. iloop = 0 diff --git a/seawater/tests/test_result_comparison.py b/seawater/tests/test_result_comparison.py index 0712870..46e36a8 100644 --- a/seawater/tests/test_result_comparison.py +++ b/seawater/tests/test_result_comparison.py @@ -3,59 +3,27 @@ import numpy as np import pytest -from oct2py import Oct2Py import seawater as sw from seawater.constants import c3515 from seawater.library import T68conv, T90conv, atleast_2d rootpath = Path(__file__).parent -octave = Oct2Py(timeout=3) -path = rootpath.joinpath("seawater_v3_3") -_ = octave.addpath(octave.genpath(str(path))) - - -functions = { - "adtg": octave.sw_adtg, - "alpha": octave.sw_alpha, - "aonb": octave.sw_aonb, - "beta": octave.sw_beta, - "bfrq": octave.sw_bfrq, - "c3515": octave.sw_c3515, - "cndr": octave.sw_cndr, - "cp": octave.sw_cp, - "dens0": octave.sw_dens0, - "dens": octave.sw_dens, - "dist": octave.sw_dist, - "dpth": octave.sw_dpth, - "f": octave.sw_f, - "fp": octave.sw_fp, - "g": octave.sw_g, - "gpan": octave.sw_gpan, - "gvel": octave.sw_gvel, - "pden": octave.sw_pden, - "pres": octave.sw_pres, - "ptmp": octave.sw_ptmp, - "salds": octave.sw_salds, - "salrp": octave.sw_salrp, - "salrpP": octave.sw_salrp, - "salrt": octave.sw_salrt, - "sals": octave.sw_sals, - "salt": octave.sw_salt, - "satAr": octave.sw_satAr, - "satN2": octave.sw_satN2, - "satO2": octave.sw_satO2, - "seck": octave.sw_seck, - "smow": octave.sw_smow, - "svan": octave.sw_svan, - "svel": octave.sw_svel, - "swvel": octave.sw_swvel, - "temp": octave.sw_temp, - "test": octave.sw_test, -} - - -def compare_results(name, function, args, values): + + +def initiate_octave(): + """Start the octave instance. + Note that this import hangs on conda-forge's octave>6. + """ + from oct2py import Oct2Py # noqa: PLC0415 + + octave = Oct2Py(timeout=3) + path = rootpath.joinpath("seawater_v3_3") + _ = octave.addpath(octave.genpath(str(path))) + return octave + + +def compare_results(name, function, args, values, functions): """Compare Python and Matlab results.""" args = [values.get(arg) for arg in args] res = function(*args) # Python call. @@ -68,8 +36,50 @@ def compare_results(name, function, args, values): np.testing.assert_allclose(val, res) +@pytest.mark.octave class OctaveResultComparison(unittest.TestCase): def setUp(self): + octave = initiate_octave() + + self.functions = { + "adtg": octave.sw_adtg, + "alpha": octave.sw_alpha, + "aonb": octave.sw_aonb, + "beta": octave.sw_beta, + "bfrq": octave.sw_bfrq, + "c3515": octave.sw_c3515, + "cndr": octave.sw_cndr, + "cp": octave.sw_cp, + "dens0": octave.sw_dens0, + "dens": octave.sw_dens, + "dist": octave.sw_dist, + "dpth": octave.sw_dpth, + "f": octave.sw_f, + "fp": octave.sw_fp, + "g": octave.sw_g, + "gpan": octave.sw_gpan, + "gvel": octave.sw_gvel, + "pden": octave.sw_pden, + "pres": octave.sw_pres, + "ptmp": octave.sw_ptmp, + "salds": octave.sw_salds, + "salrp": octave.sw_salrp, + "salrpP": octave.sw_salrp, + "salrt": octave.sw_salrt, + "sals": octave.sw_sals, + "salt": octave.sw_salt, + "satAr": octave.sw_satAr, + "satN2": octave.sw_satN2, + "satO2": octave.sw_satO2, + "seck": octave.sw_seck, + "smow": octave.sw_smow, + "svan": octave.sw_svan, + "svel": octave.sw_svel, + "swvel": octave.sw_swvel, + "temp": octave.sw_temp, + "test": octave.sw_test, + } + kw = {"comments": "#", "skiprows": 6, "delimiter": ","} station_61 = "Endeavor_Cruise-88_Station-61.csv" station_64 = "Endeavor_Cruise-88_Station-64.csv" @@ -163,6 +173,7 @@ def test_cndr(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_salds(self): @@ -173,6 +184,7 @@ def test_salds(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_salrp(self): @@ -183,6 +195,7 @@ def test_salrp(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_salrt(self): @@ -193,6 +206,7 @@ def test_salrt(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_seck(self): @@ -203,6 +217,7 @@ def test_seck(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_sals(self): @@ -213,6 +228,7 @@ def test_sals(self): function=function, args=args, values=self.values, + functions=self.functions, ) # `extras.py` @@ -224,6 +240,7 @@ def test_dist(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_f(self): @@ -234,6 +251,7 @@ def test_f(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_satAr(self): @@ -244,6 +262,7 @@ def test_satAr(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_satN2(self): @@ -254,6 +273,7 @@ def test_satN2(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_satO2(self): @@ -264,6 +284,7 @@ def test_satO2(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_swvel(self): @@ -274,6 +295,7 @@ def test_swvel(self): function=function, args=args, values=self.values, + functions=self.functions, ) # `eos80.py` @@ -285,6 +307,7 @@ def test_adtg(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_alpha(self): @@ -295,6 +318,7 @@ def test_alpha(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_aonb(self): @@ -305,6 +329,7 @@ def test_aonb(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_beta(self): @@ -315,6 +340,7 @@ def test_beta(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_bfrq1d(self): @@ -325,6 +351,7 @@ def test_bfrq1d(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_dpth(self): @@ -335,6 +362,7 @@ def test_dpth(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_g(self): @@ -345,6 +373,7 @@ def test_g(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_salt(self): @@ -355,6 +384,7 @@ def test_salt(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_fp(self): @@ -365,6 +395,7 @@ def test_fp(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_svel(self): @@ -375,6 +406,7 @@ def test_svel(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_pres(self): @@ -385,6 +417,7 @@ def test_pres(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_dens0(self): @@ -395,6 +428,7 @@ def test_dens0(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_smow(self): @@ -405,6 +439,7 @@ def test_smow(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_dens(self): @@ -415,6 +450,7 @@ def test_dens(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_pden(self): @@ -425,6 +461,7 @@ def test_pden(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_cp(self): @@ -435,6 +472,7 @@ def test_cp(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_ptmp(self): @@ -445,6 +483,7 @@ def test_ptmp(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_temp(self): @@ -455,6 +494,7 @@ def test_temp(self): function=function, args=args, values=self.values, + functions=self.functions, ) # `geostrophic.py` @@ -466,6 +506,7 @@ def test_svan(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_bfrq(self): @@ -476,6 +517,7 @@ def test_bfrq(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_gpan(self): @@ -486,6 +528,7 @@ def test_gpan(self): function=function, args=args, values=self.values, + functions=self.functions, ) def test_gvel(self): @@ -496,9 +539,11 @@ def test_gvel(self): function=function, args=args, values=self.values, + functions=self.functions, ) +@pytest.mark.octave class TConv(unittest.TestCase): def setUp(self): self.temp = np.arange(-4.0, 45.0) @@ -516,6 +561,7 @@ def test_raise(self): T90conv(self.temp, t_type="T10") +@pytest.mark.octave class Arrays(unittest.TestCase): def setUp(self): self.res = np.array(