Skip to content

Commit

Permalink
Drop Python 3.8 support, explicitly support Python 3.13
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-c committed Dec 22, 2024
1 parent c408a5a commit d9feef2
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 56 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ jobs:
tox:
name: CI tests via Tox

runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
py-ver-major: [3]
py-ver-minor: [8, 9, 10, 11, 12]
py-ver-minor: [9, 10, 11, 12, 13]
step: [lint, unit, mypy]

env:
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
tox-style:
name: CI linters via Tox

runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

strategy:
matrix:
Expand Down Expand Up @@ -115,7 +115,7 @@ jobs:

conformance_tests:
name: upgrade & test conformance tests
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
Expand All @@ -130,8 +130,8 @@ jobs:
run: ./conformance-test.sh

release_test:
name: cwl-utils release test
runs-on: ubuntu-22.04
name: cwl-upgrader release test
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ shellcheck: FORCE
shellcheck conformance-test.sh release-test.sh

pyupgrade: $(PYSOURCES)
pyupgrade --exit-zero-even-if-changed --py38-plus $^
pyupgrade --exit-zero-even-if-changed --py39-plus $^
auto-walrus $^

release-test: FORCE
Expand Down
2 changes: 1 addition & 1 deletion cwlupgrader/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Transforms draft-3 CWL documents into v1.0+ as idiomatically as possible."""

__version__ = "1.2.11"
__version__ = "1.2.12"
46 changes: 23 additions & 23 deletions cwlupgrader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import os.path
import stat
import sys
from collections.abc import MutableSequence, Sequence
from collections.abc import MutableMapping, MutableSequence, Sequence
from pathlib import Path
from typing import Any, Callable, Dict, List, MutableMapping, Optional, Set, Union
from typing import Any, Callable, Optional, Union

import ruamel.yaml
from ruamel.yaml.comments import CommentedMap # for consistent sort order
Expand All @@ -27,7 +27,7 @@
yaml.default_flow_style = False


def parse_args(args: List[str]) -> argparse.Namespace:
def parse_args(args: list[str]) -> argparse.Namespace:
"""Argument parser."""
parser = argparse.ArgumentParser(
description="Tool to upgrade CWL documents from one version to another. "
Expand Down Expand Up @@ -59,7 +59,7 @@ def parse_args(args: List[str]) -> argparse.Namespace:
return parser.parse_args(args)


def main(args: Optional[List[str]] = None) -> int:
def main(args: Optional[list[str]] = None) -> int:
"""Hook to set the args."""
if not args:
args = sys.argv[1:]
Expand All @@ -68,7 +68,7 @@ def main(args: Optional[List[str]] = None) -> int:

def run(args: argparse.Namespace) -> int:
"""Main function."""
imports: Set[str] = set()
imports: set[str] = set()
if args.dir and not os.path.exists(args.dir):
os.makedirs(args.dir)
for path in args.inputs:
Expand Down Expand Up @@ -107,7 +107,7 @@ def upgrade_document(
document: Any,
output_dir: str,
target_version: Optional[str] = "latest",
imports: Optional[Set[str]] = None,
imports: Optional[set[str]] = None,
) -> Any:
if imports is None:
imports = set()
Expand Down Expand Up @@ -210,7 +210,7 @@ def write_cwl_document(document: Any, name: str, dirname: str) -> None:


def process_imports(
document: Any, imports: Set[str], updater: Callable[[Any, str], Any], outdir: str
document: Any, imports: set[str], updater: Callable[[Any, str], Any], outdir: str
) -> None:
"""Find any '$import's and process them."""
if isinstance(document, CommentedMap):
Expand Down Expand Up @@ -481,10 +481,10 @@ def _v1_1_to_v1_2(document: CommentedMap, outdir: str) -> CommentedMap:
return document


def cleanup_v1_0_input_bindings(document: Dict[str, Any]) -> None:
def cleanup_v1_0_input_bindings(document: dict[str, Any]) -> None:
"""In v1.1 Workflow or ExpressionTool level inputBindings are deprecated."""

def cleanup(inp: Dict[str, Any]) -> None:
def cleanup(inp: dict[str, Any]) -> None:
"""Serialize non loadContents fields and add that to the doc."""
if "inputBinding" in inp:
bindings = inp["inputBinding"]
Expand All @@ -505,10 +505,10 @@ def cleanup(inp: Dict[str, Any]) -> None:
cleanup(inputs[input_name])


def move_up_loadcontents(document: Dict[str, Any]) -> None:
def move_up_loadcontents(document: dict[str, Any]) -> None:
"""Promote 'loadContents' up a level for CWL v1.1."""

def cleanup(inp: Dict[str, Any]) -> None:
def cleanup(inp: dict[str, Any]) -> None:
"""Move loadContents to the preferred location."""
if "inputBinding" in inp:
bindings = inp["inputBinding"]
Expand All @@ -525,7 +525,7 @@ def cleanup(inp: Dict[str, Any]) -> None:
cleanup(inputs[input_name])


def upgrade_v1_0_hints_and_reqs(document: Dict[str, Any]) -> None:
def upgrade_v1_0_hints_and_reqs(document: dict[str, Any]) -> None:
"""Rename some pre-v1.1 extensions to their official CWL v1.1 names."""
for extra in ("requirements", "hints"):
if extra in document:
Expand Down Expand Up @@ -555,7 +555,7 @@ def upgrade_v1_0_hints_and_reqs(document: Dict[str, Any]) -> None:
)


def has_hint_or_req(document: Dict[str, Any], name: str) -> bool:
def has_hint_or_req(document: dict[str, Any], name: str) -> bool:
"""Detects an existing named hint or requirement."""
for extra in ("requirements", "hints"):
if extra in document:
Expand All @@ -571,7 +571,7 @@ def has_hint_or_req(document: Dict[str, Any], name: str) -> bool:
return False


def workflow_clean(document: Dict[str, Any]) -> None:
def workflow_clean(document: dict[str, Any]) -> None:
"""Transform draft-3 style Workflows to more idiomatic v1.0"""
input_output_clean(document)
hints_and_requirements_clean(document)
Expand Down Expand Up @@ -652,7 +652,7 @@ def workflow_clean(document: Dict[str, Any]) -> None:
document["steps"] = new_steps


def input_output_clean(document: Dict[str, Any]) -> None:
def input_output_clean(document: dict[str, Any]) -> None:
"""Transform draft-3 style input/output listings into idiomatic v1.0."""
for param_type in ["inputs", "outputs"]:
if param_type not in document:
Expand Down Expand Up @@ -701,7 +701,7 @@ def array_type_raise_sf(param: MutableMapping[str, Any]) -> None:
del typ["secondaryFiles"]


def hints_and_requirements_clean(document: Dict[str, Any]) -> None:
def hints_and_requirements_clean(document: dict[str, Any]) -> None:
"""Transform draft-3 style hints/reqs into idiomatic v1.0 hints/reqs."""
for section in ["hints", "requirements"]:
if section in document:
Expand Down Expand Up @@ -736,13 +736,13 @@ def hints_and_requirements_clean(document: Dict[str, Any]) -> None:
document[section] = new_section


def shorten_type(type_obj: Union[str, List[Any]]) -> Union[str, List[Any]]:
def shorten_type(type_obj: Union[str, list[Any]]) -> Union[str, list[Any]]:
"""Transform draft-3 style type declarations into idiomatic v1.0 types."""
if isinstance(type_obj, str) or not isinstance(type_obj, Sequence):
return type_obj
new_type = [] # type: List[str]
new_type: list[str] = []
for entry in type_obj: # find arrays that we can shorten and do so
if isinstance(entry, Dict):
if isinstance(entry, dict):
if entry["type"] == "array" and isinstance(entry["items"], str):
entry = entry["items"] + "[]"
elif entry["type"] == "enum":
Expand All @@ -759,7 +759,7 @@ def shorten_type(type_obj: Union[str, List[Any]]) -> Union[str, List[Any]]:
return new_type


def clean_secondary_files(document: Dict[str, Any]) -> None:
def clean_secondary_files(document: dict[str, Any]) -> None:
"""Cleanup for secondaryFiles"""
if "secondaryFiles" in document:
for i, sfile in enumerate(document["secondaryFiles"]):
Expand All @@ -769,7 +769,7 @@ def clean_secondary_files(document: Dict[str, Any]) -> None:
).replace(".path", ".location")


def sort_v1_0(document: Dict[str, Any]) -> CommentedMap:
def sort_v1_0(document: dict[str, Any]) -> CommentedMap:
"""Sort the sections of the CWL document in a more meaningful order."""
keyorder = [
"cwlVersion",
Expand Down Expand Up @@ -800,7 +800,7 @@ def sort_v1_0(document: Dict[str, Any]) -> CommentedMap:
)


def sort_enum(enum: Dict[str, Any]) -> Dict[str, Any]:
def sort_enum(enum: dict[str, Any]) -> dict[str, Any]:
"""Sort the enum type definitions in a more meaningful order."""
keyorder = ["type", "name", "label", "symbols", "inputBinding"]
return CommentedMap(
Expand All @@ -811,7 +811,7 @@ def sort_enum(enum: Dict[str, Any]) -> Dict[str, Any]:
)


def sort_input_or_output(io_def: Dict[str, Any]) -> Dict[str, Any]:
def sort_input_or_output(io_def: dict[str, Any]) -> dict[str, Any]:
"""Sort the input definitions in a more meaningful order."""
keyorder = [
"label",
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ classifiers = [
"Operating System :: MacOS :: MacOS X",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"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 :: File Formats",
"Topic :: Software Development :: Libraries",
"Typing :: Typed",
]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = [
"setuptools",
"ruamel.yaml >= 0.16.0, < 0.19",
Expand Down
45 changes: 22 additions & 23 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
[tox]
envlist =
py3{8,9,10,11,12}-lint,
py3{8,9,10,11,12}-unit,

py3{8,9,10,11,12}-mypy,
py3{9,10,11,12,13}-lint,
py3{9,10,11,12,13}-unit,
py3{9,10,11,12,13}-mypy,
py312-lintreadme,
py312-pydocstyle
isolated_build = True
Expand All @@ -14,47 +13,47 @@ addopts=-n auto

[gh-actions]
python =
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
3.13: py313

[testenv]
description =
py3{8,9,10,11,12}-unit: Run the unit tests
py3{8,9,10,11,12}-lint: Lint the Python code
py3{8,9,10,11,12}-mypy: Check for type safety
py3{9,10,11,12,13}-unit: Run the unit tests
py3{9,10,11,12,13}-lint: Lint the Python code
py3{9,10,11,12,13}-mypy: Check for type safety
py312-pydocstyle: docstring style checker
py312-lintreadme: Lint the README.rst->.md conversion

passenv =
CI
GITHUB_*
deps =
py3{8,9,10,11,12}-{unit,mypy}: -rrequirements.txt
py3{8,9,10,11,12}-{unit,mypy}: -rtest-requirements.txt
py3{8,9,10,11,12}-lint: flake8-bugbear
py3{8,9,10,11,12}-lint: black
py3{8,9,10,11,12}-mypy: -rmypy-requirements.txt
py3{9,10,11,12,13}-{unit,mypy}: -rrequirements.txt
py3{9,10,11,12,13}-{unit,mypy}: -rtest-requirements.txt
py3{9,10,11,12,13}-lint: flake8-bugbear
py3{9,10,11,12,13}-lint: black
py3{9,10,11,12,13}-mypy: -rmypy-requirements.txt

setenv =
py3{8,9,10,11,12}-unit: LC_ALL = C.UTF-8
py3{9,10,11,12,13}-unit: LC_ALL = C.UTF-8

commands =
py3{8,9,10,11,12}-unit: python -m pip install -U pip setuptools wheel
py3{8,9,10,11,12}-unit: make coverage-report coverage.xml PYTEST_EXTRA="{posargs}"
py3{8,9,10,11,12}-lint: make flake8
py3{8,9,10,11,12}-lint: make format-check
py3{8,9,10,11,12}-mypy: make mypy
py3{9,10,11,12,13}-unit: python -m pip install -U pip setuptools wheel
py3{9,10,11,12,13}-unit: make coverage-report coverage.xml PYTEST_EXTRA="{posargs}"
py3{9,10,11,12,13}-lint: make flake8
py3{9,10,11,12,13}-lint: make format-check
py3{9,10,11,12,13}-mypy: make mypy

allowlist_externals =
py3{8,9,10,11,12}-lint: flake8
py3{8,9,10,11,12}-lint: black
py3{8,9,10,11,12}-{mypy,shellcheck,lint,unit}: make
py3{9,10,11,12,13}-lint: flake8
py3{9,10,11,12,13}-lint: black
py3{9,10,11,12,13}-{mypy,shellcheck,lint,unit}: make

skip_install =
py3{8,9,10,11,12}-lint: true
py3{9,10,11,12,13}-lint: true

[testenv:py312-pydocstyle]
allowlist_externals = make
Expand Down

0 comments on commit d9feef2

Please sign in to comment.