From 7b122ea1ff837b304180e12425849b364d0f32c8 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:40:50 +0200 Subject: [PATCH 1/5] Cleanup and update pyproject metadata --- .github/workflows/ci.yml | 16 ++++++---------- .travis.yml | 40 ---------------------------------------- docs/source/install.rst | 18 ------------------ pyproject.toml | 9 +++++++++ requirements.txt | 2 -- 5 files changed, 15 insertions(+), 70 deletions(-) delete mode 100644 .travis.yml delete mode 100644 requirements.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93e4569..da0d81e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: jobs: build: - + name: unit-test py${{ matrix.python-version }} runs-on: ubuntu-latest strategy: @@ -19,22 +19,18 @@ jobs: python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - + - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - pip install -e .[test] + pip install .[test] - name: Test with pytest - run: | - pytest tests + run: pytest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8d89d41..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: python - -sudo: false - -python: - - "2.7" - - "3.5" - - "3.6" - - "3.7" - -before_install: - - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh; - else - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; - fi - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - hash -r - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - # Useful for debugging any issues with conda - - conda info -a - -install: - - conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy pytest - - source activate test-environment - - pip install -r requirements_dev.txt - - pip install codecov pytest-cov - - python setup.py install - -before_script: - # Download the required sample data files. - - python -c "import seabird.utils; seabird.utils.sampledata()" - -script: - - py.test --cov --cov-report=term-missing -vv - -after_success: - - codecov diff --git a/docs/source/install.rst b/docs/source/install.rst index afcd5be..076325f 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -1,21 +1,3 @@ -************ -Installation -************ - -Requirements -============ - -- `Python `_ 2.7 or 3.X (recommended >=3.5) - -- `Numpy `_ (>=1.1) - -Optional requirement --------------------- - -- `netCDF4 `_, if you want to be able to export the data into netCDF files. - -- `CoTeDe `_, if you want to quality control your data with custom or pre-set group of checks. - Installing Seabird ================== diff --git a/pyproject.toml b/pyproject.toml index becf56d..35834cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ description="Parser for Sea-Bird's CTD and TSG" readme = "README.rst" requires-python = ">=3.6" keywords = ["oceanography", "ocean data", "CTD", "TSG", "SeaBird", "hydrography", "parser"] +license = {file = "LICENSE.rst"} classifiers=[ "Development Status :: 5 - Production/Stable", "Natural Language :: English", @@ -51,6 +52,8 @@ QC = ["cotede>=0.20.2"] [project.urls] repository = "https://github.com/castelao/seabird" +documentation = "https://seabird.readthedocs.io" + [project.scripts] "seabird" = "seabird.cli:cli" @@ -60,3 +63,9 @@ line-length = 88 [tool.setuptools_scm] write_to = "seabird/version.py" git_describe_command = "git describe --dirty --tags --long --match 'v*' --first-parent" + +[tool.pytest.ini_options] +minversion = "6.0" +testpaths = [ + "tests", +] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 68b129e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -numpy>=1.14 -Click>=6.6 From fa2e2709ff7be1057b7ab9baa499214c260ec5bd Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:24:35 +0200 Subject: [PATCH 2/5] Support python 3.11-3.13 and deprecate 3.6, 3.7, 3.8 Python 3.6-3.8 have reached end of life. * Remove dependency on deprecated pkg_resources * Update test matrix * add __init__.py to `rules` so its seen as a module and can be loaded in --- .github/workflows/ci.yml | 6 +++--- pyproject.toml | 8 ++++---- seabird/__init__.py | 8 +++----- seabird/cnv.py | 24 +++++++++--------------- seabird/rules/__init__.py | 0 seabird/utils.py | 16 +++++++--------- tests/test_rules.py | 16 +++++++--------- 7 files changed, 33 insertions(+), 45 deletions(-) create mode 100644 seabird/rules/__init__.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da0d81e..25ddccf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,6 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] schedule: - cron: "7 18 * * 0" @@ -16,14 +15,15 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python ${{ matrix.python-version }} + - name: "Set up Python ${{ matrix.python-version }}" uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/pyproject.toml b/pyproject.toml index 35834cb..cc81afe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ name="seabird" dynamic = ["version"] description="Parser for Sea-Bird's CTD and TSG" readme = "README.rst" -requires-python = ">=3.6" +requires-python = ">=3.9" keywords = ["oceanography", "ocean data", "CTD", "TSG", "SeaBird", "hydrography", "parser"] license = {file = "LICENSE.rst"} classifiers=[ @@ -22,11 +22,11 @@ classifiers=[ "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "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", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering" ] dependencies = [ diff --git a/seabird/__init__.py b/seabird/__init__.py index 4172e67..9c6b7ad 100644 --- a/seabird/__init__.py +++ b/seabird/__init__.py @@ -3,15 +3,13 @@ from .cnv import CNV, fCNV from .exceptions import CNVError +import importlib.metadata # __all__ = ['CNV', 'fCNV'] - -from pkg_resources import get_distribution, DistributionNotFound - try: - __version__ = get_distribution(__name__).version -except DistributionNotFound: + __version__ = importlib.metadata.version(__name__) +except Exception: try: from .version import version as __version__ except ImportError: diff --git a/seabird/cnv.py b/seabird/cnv.py index a7c3244..cb6621c 100644 --- a/seabird/cnv.py +++ b/seabird/cnv.py @@ -1,20 +1,13 @@ from datetime import datetime, timedelta import re -import pkg_resources +import importlib.resources import os import logging import struct import json +from . import rules +import hashlib -try: - import hashlib - - md5 = hashlib.md5 -except ImportError: - # for Python << 2.5 - import md5 - - md5 = md5.new # import codecs import numpy as np @@ -150,9 +143,9 @@ def get_attrs(self): # ---- # Temporary solution. Failsafe MD5 try: - self.attrs["md5"] = md5(self.raw_text.encode("utf-8")).hexdigest() + self.attrs["md5"] = hashlib.md5(self.raw_text.encode("utf-8")).hexdigest() except: - self.attrs["md5"] = md5( + self.attrs["md5"] = hashlib.md5( self.raw_text.decode("latin1", "replace").encode("utf-8") ).hexdigest() @@ -162,9 +155,10 @@ def prepare_data(self): self.data = [] self.ids = [] # ---- - rule_file = "rules/refnames.json" - text = pkg_resources.resource_string(__name__, rule_file) - refnames = json.loads(text.decode("utf-8")) + + with importlib.resources.open_text(rules, "refnames.json") as file: + text = file.read() + refnames = json.loads(text) # ---- Parse fields if ("attributes" in self.rule) and ( diff --git a/seabird/rules/__init__.py b/seabird/rules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/seabird/utils.py b/seabird/utils.py index 476f450..0d3bfdf 100644 --- a/seabird/utils.py +++ b/seabird/utils.py @@ -1,13 +1,13 @@ import os import re import logging -import pkg_resources +import importlib.resources import json -# import codecs - +from seabird import rules from seabird.exceptions import CNVError + module_logger = logging.getLogger("seabird.utils") @@ -74,14 +74,12 @@ def load_rule(raw_text): It should try all available rules, one by one, and use the one which fits. """ - rules_dir = "rules" - rule_files = pkg_resources.resource_listdir(__name__, rules_dir) + rule_files = [entry.name for entry in importlib.resources.files(rules).iterdir() if entry.is_file()] rule_files = [f for f in rule_files if re.match(r"^cnv.*\.json$", f)] for rule_file in rule_files: - text = pkg_resources.resource_string( - __name__, os.path.join(rules_dir, rule_file) - ) - rule = json.loads(text.decode("utf-8")) + with importlib.resources.files(rules).joinpath(rule_file).open('r') as file: + text = file.read() + rule = json.loads(text) # Should I load using codec, for UTF8?? Do I need it? # f = codecs.open(rule_file, 'r', 'utf-8') # rule = yaml.load(f.read()) diff --git a/tests/test_rules.py b/tests/test_rules.py index 8d514d1..745af23 100644 --- a/tests/test_rules.py +++ b/tests/test_rules.py @@ -3,11 +3,10 @@ """ Check the rules """ -import os -import pkg_resources +import importlib.resources import json import re -import seabird +from seabird import rules def test_load_available_rules(): @@ -15,14 +14,13 @@ def test_load_available_rules(): https://github.com/castelao/seabird/issues/7 """ - rules_dir = "rules" - rule_files = pkg_resources.resource_listdir(seabird.__name__, rules_dir) + rules_dir_path = importlib.resources.files(rules) + rule_files = [entry.name for entry in rules_dir_path.iterdir() if entry.is_file()] rule_files = [f for f in rule_files if re.match("^(?!refnames).*json$", f)] for rule_file in rule_files: print("loading rule: %s", (rule_file)) - text = pkg_resources.resource_string( - seabird.__name__, os.path.join(rules_dir, rule_file) - ) - rule = json.loads(text.decode("utf-8")) + with importlib.resources.files(rules).joinpath(rule_file).open('r') as file: + text = file.read() + rule = json.loads(text) assert type(rule) == dict assert len(rule.keys()) > 0 From d793ad3a1cfcf7c071400261943ea7a65b2c52be Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:29:37 +0800 Subject: [PATCH 3/5] Upgrade pytest warnings to errors --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cc81afe..eb309d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,4 +68,5 @@ git_describe_command = "git describe --dirty --tags --long --match 'v*' --first- minversion = "6.0" testpaths = [ "tests", -] \ No newline at end of file +] +filterwarnings = ["error"] \ No newline at end of file From e59b91107cb2569ed65cefb7c2f9758b2716cf28 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:43:15 +0800 Subject: [PATCH 4/5] Update contributing page --- CONTRIBUTING.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index a017c16..72a49b7 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -66,13 +66,7 @@ Ready to contribute? Here's how to set up `seabird` for local development. a. Using Conda (assuming you already have it installed) - I. Python 2:: - - $ conda create --name seabird python=2 - - II. Or, Python 3:: - - $ conda create --name seabird python=3 + $ conda create --name seabird python=3.10 Activate your conda environment, and take advantage of conda:: From 66bc623ab74c410dcb870d02fc41ddcce7cabef3 Mon Sep 17 00:00:00 2001 From: Vecko <36369090+VeckoTheGecko@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:54:18 +0800 Subject: [PATCH 5/5] Update regex to use raw string \s would be an invalid escape character --- seabird/cnv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seabird/cnv.py b/seabird/cnv.py index cb6621c..1f6c5c2 100644 --- a/seabird/cnv.py +++ b/seabird/cnv.py @@ -46,7 +46,7 @@ def __init__(self, raw_text, defaults=None): module_logger.debug("Initializing CNV class") # Clean empty lines first - self.raw_text = re.sub("\n\s*(?=\n)", "", raw_text) + self.raw_text = re.sub(r"\n\s*(?=\n)", "", raw_text) self.defaults = defaults self.attrs = {} # ----