From 5ceb3adb3c6b632fd405510879cffc9285f8d58a Mon Sep 17 00:00:00 2001 From: Kennedy Kori Date: Mon, 18 Nov 2024 23:16:26 +0300 Subject: [PATCH] chore(deps): upgrade project dependencies Upgrade all project dependencies and add support for Python 3.13. --- .github/workflows/ci.yml | 3 +- .pre-commit-config.yaml | 11 +- docs/conf.py | 1 + pyproject.toml | 168 +++++++++--------- src/sghi/etl/commons/processors.py | 7 +- src/sghi/etl/commons/sinks.py | 7 +- src/sghi/etl/commons/sources.py | 7 +- .../etl/commons/utils/result_gatherers.py | 2 +- 8 files changed, 110 insertions(+), 96 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f33eb6..946c2ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ jobs: python-version: - "3.11" - "3.12" + - "3.13" steps: - uses: actions/checkout@v4 - name: Set up project using python ${{ matrix.python-version }} @@ -50,7 +51,7 @@ jobs: uses: actions/setup-python@v5 with: cache: pip - python-version: "3.12" + python-version: "3.13" - name: Install requirements run: | python -m pip install --upgrade pip diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5bc2665..e4e32c2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,24 +3,29 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer + - id: check-ast - id: check-added-large-files + - id: check-case-conflict + - id: check-json + - id: check-symlinks - id: check-toml - id: check-vcs-permalinks - id: check-yaml + - id: debug-statements - repo: https://github.com/asottile/pyupgrade - rev: v3.15.2 + rev: v3.19.0 hooks: - id: pyupgrade args: - --py311-plus - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.3.6 + rev: v0.7.4 hooks: - id: ruff args: diff --git a/docs/conf.py b/docs/conf.py index a66ff76..a50a7a0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -92,6 +92,7 @@ ("py:exc", "ResourceDisposedError"), # docs aren't published yet ("py:exc", "sghi.disposable.ResourceDisposedError"), # docs aren't published yet ("py:func", "sghi.disposable.not_disposed"), # docs aren't published yet + ("py:meth", "sghi.etl.core.Processor.apply"), # docs aren't published yet ("py:meth", "sghi.etl.core.Source.draw"), # docs aren't published yet ("py:obj", "sghi.etl.commons.processors._PDT"), # private type annotations ("py:obj", "sghi.etl.commons.processors._RDT"), # private type annotations diff --git a/pyproject.toml b/pyproject.toml index 91420b9..c99cdac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [build-system] build-backend = "setuptools.build_meta" requires = [ - "setuptools>=69.2.0", - "setuptools_scm>=8.0.4", + "setuptools>=75.5.0", + "setuptools_scm>=8.1.0", ] [project] @@ -23,9 +23,9 @@ classifiers = [ "Typing :: Typed" ] dependencies = [ - "typing-extensions>=4.10.0", - "sghi-commons @ git+https://github.com/savannahghi/sghi-commons.git@v1.4.0", - "sghi-etl-core @ git+https://github.com/savannahghi/sghi-etl-core.git@v1.1.1", + "typing-extensions>=4.12.2", + "sghi-commons @ git+https://github.com/savannahghi/sghi-commons.git@v1.5.1", + "sghi-etl-core @ git+https://github.com/savannahghi/sghi-etl-core.git@v1.2.0", ] description = "Collection of utilities for working with SGHI ETL Workflows." dynamic = ["version"] @@ -40,34 +40,35 @@ readme = "README.md" requires-python = ">=3.11" # Support Python 3.10+. [project.optional-dependencies] +coveralls = ["coveralls~=4.0.1"] + dev = [ - "pre-commit~=3.7.0", + "pre-commit~=4.0.1", ] docs = [ - "furo==2024.1.29", - "jaraco.packaging~=9.5.0", - "rst.linker~=2.4.0", - "Sphinx~=7.2.6", + "furo==2024.8.6", + "jaraco.packaging~=10.2.3", + "rst.linker~=2.6.0", + "Sphinx~=8.1.3", "sphinx-favicon~=1.0.1", - "sphinx-hoverxref~=1.3.0", + "sphinx-hoverxref~=1.4.2", "sphinx-inline-tabs~=2023.4.21", - "sphinx-lint~=0.9.1", + "sphinx-lint~=1.0.0", "sphinx-notfound-page~=1.0.0", ] test = [ - "coverage~=6.5.0", - "coveralls~=3.3.1", + "coverage~=7.6.7", "packaging", - "pyright>=1.1.358", - "pytest~=8.1.1", - "pytest-cov~=5.0.0", + "pyright>=1.1.389", + "pytest~=8.3.3", + "pytest-cov~=6.0.0", "pytest-forked~=1.6.0", "pytest-sugar~=1.0.0", - "pytest-xdist~=3.5.0", - "ruff~=0.3.6", - "tox~=4.14.2", + "pytest-xdist~=3.6.1", + "ruff~=0.7.4", + "tox~=4.23.2", "tox-gh-actions~=3.2.0", ] @@ -87,7 +88,7 @@ extend-exclude = """ """ include = ["src", "test"] line-length = 79 -target-version = ["py311", "py312"] +target-version = ["py311", "py312", "py313"] [tool.coverage.html] directory = "coverage" @@ -264,71 +265,62 @@ where = ["src"] root = "." [tool.tox] -legacy_tox_ini = """ - [tox] - env_list = {py311, py312}, coveralls, docs, package - isolated_build = true - no_package = false - requires = - tox>4 - skip_missing_interpreters = true - - - [gh-actions] - python = - 3.11: py311 - 3.12: py312, coveralls, docs, package - - - [testenv] - commands = - ruff check . - ruff format --check . - pyright . - coverage erase - pytest {posargs:.} - coverage html - deps = - . - description = test and lint the project - download = true - extras = - test - set_env = - PYTHONPATH = {toxinidir}/src - PYRIGHT_PYTHON_FORCE_VERSION = latest - - - ;If running outside Github, ensure that the the `COVERALLS_REPO_TOKEN` - ;environment variable is set. - [testenv:coveralls] - commands = - coveralls --service=github - description = submit coverage results to coverall.io - extras = - test - pass_env = - COVERALLS_REPO_TOKEN - GITHUB_* - - - [testenv:docs] - changedir = docs - commands = - sphinx-build -EW --keep-going -b html . {toxinidir}/docs/build/html - sphinx-lint -i api - description = build sphinx documentation - extras = - docs - - - [testenv:package] - commands = - python -c "import shutil; shutil.rmtree('dist', ignore_errors=True)" - python -m build - depends = testenv - deps = - build - description = build the library - skip_install = true +env_list = ["py311", "py312", "py313", "coveralls", "docs", "package"] +isolated_build = true +requires = ["tox>=4.23.2", "tox-uv>=1.16.0"] +no_package = false +skip_missing_interpreters = true + +[tool.tox.env_run_base] +# allowlist_externals = ["uv"] +commands = [ + ["ruff", "check", "."], + ["ruff", "format", "--check", "."], + ["pyright", "."], + ["coverage", "erase"], + ["pytest", { replace = "posargs", default = ["."], extend = true}], + ["coverage", "html"], +] +deps = ["."] +description = "test and lint the project" +download = true +extras = ["test"] +set_env = { PYTHONPATH = "{toxinidir}/src", PYRIGHT_PYTHON_FORCE_VERSION = "latest" } + +[tool.tox.env.coveralls] +# If running outside Github, ensure that the the `COVERALLS_REPO_TOKEN` +# environment variable is set. +# Also, this only works for Python = ">=3.8,<3.13". +# See https://github.com/TheKevJames/coveralls-python/issues/523 +base_python = ["py312"] +commands = [["coveralls", "--service=github"]] +description = "submit coverage results to coverall.io" +depends = ["env_run_base"] +extras = ["coveralls"] +pass_env = ["COVERALLS_REPO_TOKEN", "GITHUB_*"] + +[tool.tox.env.docs] +changedir = "docs" +commands = [ + ["sphinx-build", "-EW", "--keep-going", "-b", "html", ".", "{toxinidir}/docs/build/html"], + ["sphinx-lint", "-i", "api"] +] +description = "build sphinx documentation" +extras = ["docs"] + +[tool.tox.env.package] +commands = [ + ["python", "-c", "import shutil; shutil.rmtree('dist', ignore_errors=True)"], + ["python", "-m", "build"] +] +depends = ["env_run_base"] +deps = ["build"] +description = "build the library" +skip_install = true + +[tool.tox.gh-actions] +python = """ + 3.11: py311 + 3.12: py312, coveralls + 3.13: py313, docs, package """ diff --git a/src/sghi/etl/commons/processors.py b/src/sghi/etl/commons/processors.py index fb0a961..e3e2b8f 100644 --- a/src/sghi/etl/commons/processors.py +++ b/src/sghi/etl/commons/processors.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import sys from collections.abc import Callable, Iterable, Sequence from concurrent.futures import Executor, Future, ThreadPoolExecutor from contextlib import ExitStack @@ -803,7 +804,11 @@ def do_apply(raw_data: Sequence[_RDT]) -> _PDT: @final class _ProcessorOfCallable(Processor[_RDT, _PDT], Generic[_RDT, _PDT]): - __slots__ = ("_delegate_to", "_is_disposed", "_logger") + # See: https://github.com/python/cpython/pull/106771 + if sys.version_info[:3] >= (3, 13, 0): # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger", "__dict__") + else: # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger") def __init__(self, delegate_to: _ProcessorCallable[_RDT, _PDT]) -> None: super().__init__() diff --git a/src/sghi/etl/commons/sinks.py b/src/sghi/etl/commons/sinks.py index 49c9b93..d0834a5 100644 --- a/src/sghi/etl/commons/sinks.py +++ b/src/sghi/etl/commons/sinks.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import sys from collections.abc import Callable, Iterable, Sequence from concurrent.futures import Executor, Future, ThreadPoolExecutor from contextlib import ExitStack @@ -596,7 +597,11 @@ def do_drain(processed_data: Sequence[_PDT]) -> None: @final class _SinkOfCallable(Sink[_PDT], Generic[_PDT]): - __slots__ = ("_delegate_to", "_is_disposed", "_logger") + # See: https://github.com/python/cpython/pull/106771 + if sys.version_info[:3] >= (3, 13, 0): # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger", "__dict__") + else: # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger") def __init__(self, delegate_to: _SinkCallable[_PDT]) -> None: super().__init__() diff --git a/src/sghi/etl/commons/sources.py b/src/sghi/etl/commons/sources.py index ea2a2d9..fc21216 100644 --- a/src/sghi/etl/commons/sources.py +++ b/src/sghi/etl/commons/sources.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import sys from collections.abc import Callable, Iterable, Sequence from concurrent.futures import Executor, Future, ThreadPoolExecutor from contextlib import ExitStack @@ -299,7 +300,11 @@ def do_draw() -> _RDT: @final class _SourceOfCallable(Source[_RDT], Generic[_RDT]): - __slots__ = ("_delegate_to", "_is_disposed", "_logger") + # See: https://github.com/python/cpython/pull/106771 + if sys.version_info[:3] >= (3, 13, 0): # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger", "__dict__") + else: # pragma: no cover + __slots__ = ("_delegate_to", "_is_disposed", "_logger") def __init__(self, delegate_to: _SourceCallable[_RDT]) -> None: super().__init__() diff --git a/src/sghi/etl/commons/utils/result_gatherers.py b/src/sghi/etl/commons/utils/result_gatherers.py index ff6ca6f..d6023b7 100644 --- a/src/sghi/etl/commons/utils/result_gatherers.py +++ b/src/sghi/etl/commons/utils/result_gatherers.py @@ -90,7 +90,7 @@ def _do_gather() -> Iterable[_T]: for future in futures: try: yield future.result() - except BaseException as exp: # noqa: BLE001 + except BaseException as exp: if exc_wrapper_factory: raise exc_wrapper_factory(exc_wrapper_message) from exp else: