Skip to content

Added Python 3.14 support #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14.0-beta.1"]

steps:
- uses: actions/checkout@v3
Expand All @@ -27,4 +27,4 @@ jobs:
python -m pip install -r requirements-tests.txt --no-deps
- name: Run tests
run: |
python -m unittest discover .
python -m unittest --verbose
11 changes: 8 additions & 3 deletions concoursetools/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
import inspect
from typing import Any, ClassVar, TypeVar, cast, get_type_hints

from concoursetools.typing import TypedVersionT, VersionConfig, VersionT
Expand Down Expand Up @@ -262,9 +263,13 @@ class TypedVersion(Version):

def __init_subclass__(cls) -> None:
try:
annotations = vars(cls)["__annotations__"] # avoid MRO lookup
except KeyError:
annotations = {}
annotations = inspect.get_annotations(cls)
except AttributeError:
# Function isn't available in Python 3.9, so use the old code until EOL
try:
annotations = vars(cls)["__annotations__"] # avoid MRO lookup
except KeyError:
annotations = {}

if len(annotations) == 0:
raise TypeError("Can't instantiate dataclass TypedVersion without any fields")
Expand Down
1 change: 1 addition & 0 deletions docs/source/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ What's New
.. toctree::
:glob:

whats_new/development
whats_new/*
5 changes: 5 additions & 0 deletions docs/source/whats_new/development.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Development
===========


* Added Python 3.14 support.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Software Development",
"Typing :: Typed",
]
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sonar.projectDescription="Static analysis for the Concourse Tools Python library
sonar.sources=concoursetools
sonar.tests=tests

sonar.python.version=3.9,3.10,3.11,3.12,3.13
sonar.python.version=3.9,3.10,3.11,3.12,3.13,3.14

sonar.coverage.exclusions=docs/**/*,tests/**/*,coverage.xml,concoursetools/colour.py,concoursetools/typing.py,**/__init__.py,**/__main__.py
sonar.python.coverage.reportPaths=coverage.xml
Expand Down
8 changes: 7 additions & 1 deletion tests/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import random
import shutil
import string
import sys
from tempfile import TemporaryDirectory
from unittest import SkipTest, TestCase

Expand Down Expand Up @@ -728,7 +729,12 @@ def _build_test_resource_docker_image() -> str:
except FileNotFoundError:
pass

cli_commands.dockerfile(str(temp_dir), resource_file="concourse.py", class_name=TestResource.__name__, dev=True)
# This pins the tag to the exact version of Python we're using, including alpha/beta
# '3.14.0b1 (main, May 9 2025, 23:49:24) [GCC 12.2.0]'
# ^^^^^^^^
tag, *_ = sys.version.split()
cli_commands.dockerfile(str(temp_dir), resource_file="concourse.py", class_name=TestResource.__name__,
tag=tag, dev=True)

stdout, _ = run_command("docker", ["build", ".", "-q"], cwd=temp_dir)
sha1_hash = stdout.strip()
Expand Down
Loading