diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 839c8ea..caa2176 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -5,12 +5,15 @@ on: [push, pull_request] jobs: tests: runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.11"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 name: Set up Python with: - python-version: "3.8" + python-version: ${{ matrix.python-version }} - name: Install poetry run: pip install poetry - name: Install repo @@ -18,6 +21,7 @@ jobs: - name: Run tests run: bash scripts/tests.sh - name: Upload coverage HTML + if: ${{ matrix.python-version == '3.8' }} uses: actions/upload-artifact@v3 with: name: htmlcov diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dfc898f..e6ad01c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: hooks: - id: mypy additional_dependencies: - [tokenize-rt==3.2.0, pydantic>=2.0.0, types-toml, types-pyyaml] + [tokenize-rt==3.2.0, pydantic>=2.0.0, types-pyyaml] - repo: https://github.com/crate-ci/typos rev: v1.16.10 hooks: diff --git a/chemcloud/http_client.py b/chemcloud/http_client.py index 0fb4222..8f758f2 100644 --- a/chemcloud/http_client.py +++ b/chemcloud/http_client.py @@ -1,4 +1,5 @@ import json +import sys from base64 import urlsafe_b64decode from getpass import getpass from pathlib import Path @@ -6,7 +7,13 @@ from typing import Any, Dict, List, Optional, Tuple, Union import httpx -import toml + +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + +import tomli_w from qcio.utils import json_dumps from chemcloud.models import FutureOutput, FutureOutputGroup, QCIOInputs @@ -72,8 +79,8 @@ def _set_tokens(self) -> None: access_token, refresh_token = self._tokens_from_username_password(un, pw) elif credentials_file.is_file(): # Look for tokens in credentials file - with open(credentials_file) as f: - credentials = toml.load(f) + with open(credentials_file, "rb") as f: + credentials = tomllib.load(f) try: access_token = credentials[self._profile]["access_token"] refresh_token = credentials[self._profile]["refresh_token"] @@ -146,8 +153,8 @@ def write_tokens_to_credentials_file( ) if credentials_file.is_file(): - with open(credentials_file, "r") as f: - credentials = toml.load(f) + with open(credentials_file, "rb") as f: + credentials = tomllib.load(f) else: credentials_file.parent.mkdir(parents=True, exist_ok=True) credentials = {} @@ -156,8 +163,8 @@ def write_tokens_to_credentials_file( "access_token": access_token, "refresh_token": refresh_token, } - with open(credentials_file, "w") as f: - toml.dump(credentials, f) + with open(credentials_file, "wb") as f: + tomli_w.dump(credentials, f) def _request( self, diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0956c09..fc689df 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Changed - Updated GitHub actions to run on `pull_request` in addition to `push`. +- Migrated dependency `uiri/toml` to `hukkin/tomli` (Python < 3.11) or the built-in `tomllib` (Python >= 3.11) +- Updated GitHub actions to test against both Python 3.8 and Python 3.11 ## [0.8.2] - 2023-09-25 diff --git a/poetry.lock b/poetry.lock index c858a61..d13acd4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "annotated-types" @@ -1250,6 +1250,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1257,8 +1258,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1275,6 +1283,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1282,6 +1291,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -1541,14 +1551,14 @@ files = [ ] [[package]] -name = "types-toml" -version = "0.10.8.7" -description = "Typing stubs for toml" +name = "tomli-w" +version = "1.0.0" +description = "A lil' TOML writer" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "types-toml-0.10.8.7.tar.gz", hash = "sha256:58b0781c681e671ff0b5c0319309910689f4ab40e8a2431e205d70c94bb6efb1"}, - {file = "types_toml-0.10.8.7-py3-none-any.whl", hash = "sha256:61951da6ad410794c97bec035d59376ce1cbf4453dc9b6f90477e81e4442d631"}, + {file = "tomli_w-1.0.0-py3-none-any.whl", hash = "sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463"}, + {file = "tomli_w-1.0.0.tar.gz", hash = "sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9"}, ] [[package]] @@ -1656,4 +1666,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "08c9a6f1a6ab29757c8a40a49289b20da9bda2858279b5df12f0ae12de73abeb" +content-hash = "cebcbe4cbf100c724da5468b5bee46f2027ee7ba8af787afb975c4188df3d2a3" diff --git a/pyproject.toml b/pyproject.toml index 5ed1b47..82750f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,8 @@ classifiers = [ [tool.poetry.dependencies] python = "^3.8" -toml = "^0.10.2" +tomli = { version = ">=1.1.0", python = "<3.11" } +tomli-w = "^1.0.0" httpx = "^0.23.1" qcio = "^0.7.0" pydantic = ">=2.0.0, !=2.4.0" @@ -43,7 +44,6 @@ pytest-cov = "^4.1.0" coverage = "^7.3.0" pytest-httpx = "<0.23.0" pytest-mock = "^3.11.1" -types-toml = "^0.10.8.7" [tool.poetry.group.docs.dependencies] diff --git a/tests/conftest.py b/tests/conftest.py index db0b54f..9905e96 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,7 @@ from typing import Dict import pytest -import toml +import tomli_w from pytest_httpx import HTTPXMock from qcio import Molecule @@ -42,8 +42,8 @@ def _write_credentials_file( credentials_file = ( settings.chemcloud_base_directory / settings.chemcloud_credentials_file ) - with open(credentials_file, "w+") as f: - toml.dump(credentials, f) + with open(credentials_file, "wb+") as f: + tomli_w.dump(credentials, f) return _write_credentials_file diff --git a/tests/test_http_client.py b/tests/test_http_client.py index a0ef6be..c22f840 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -1,8 +1,12 @@ import json import re +import sys from pathlib import Path -import toml +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib from pytest_httpx import HTTPXMock from qcio import Model, ProgramInput, SinglePointOutput @@ -135,8 +139,8 @@ def test_write_tokens_to_credentials_file(settings): assert credentials_file.is_file() - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) assert ( data[settings.chemcloud_credentials_profile]["access_token"] @@ -166,8 +170,8 @@ def test_write_tokens_to_credentials_file_adds_new_profiles_to_credentials_file( assert credentials_file.is_file() - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) assert ( data[settings.chemcloud_credentials_profile]["access_token"] @@ -186,8 +190,8 @@ def test_write_tokens_to_credentials_file_adds_new_profiles_to_credentials_file( new_profile_access_token, new_profile_refresh_token, profile=new_profile_name ) - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) # Default profile still exists assert ( @@ -224,8 +228,8 @@ def test_write_tokens_to_credentials_file_overwrites_tokens_of_existing_profiles assert credentials_file.is_file() - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) assert ( data[settings.chemcloud_credentials_profile]["access_token"] @@ -241,8 +245,8 @@ def test_write_tokens_to_credentials_file_overwrites_tokens_of_existing_profiles client.write_tokens_to_credentials_file(new_access_token, new_refresh_token) - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) # Default profile has new tokens assert ( @@ -316,8 +320,8 @@ def test__refresh_tokens_writes_to_credentials_file_only_if_flag_set( client._refresh_tokens(original_refresh_token) assert credentials_file.is_file() - with open(credentials_file) as f: - data = toml.load(f) + with open(credentials_file, "rb") as f: + data = tomllib.load(f) assert ( data[settings.chemcloud_credentials_profile]["access_token"]