diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1419d6ba..de37764e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "pypy3.9", "pypy3.10"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.10"] steps: - uses: actions/checkout@v5 diff --git a/NEWS b/NEWS index 40b5866b..40b11b5b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,16 @@ testtools NEWS Changes and improvements to testtools_, grouped by release. +NEXT +~~~~ + +Changes +------- + +* Drop support for Python 3.9. (Jelmer Vernooij) + +* Add support for Python 3.13 and 3.14. (Jelmer Vernooij) + 2.8.0 ~~~~~ diff --git a/README.rst b/README.rst index 0f77f88f..2895048a 100644 --- a/README.rst +++ b/README.rst @@ -34,7 +34,7 @@ under the same license as Python, see LICENSE for details. Supported platforms ------------------- -* Python 3.9+ or PyPy3 +* Python 3.10+ or PyPy3 If you would like to use testtools for earlier Pythons, consult the compatibility docs: diff --git a/doc/overview.rst b/doc/overview.rst index f21c53af..c02d1bc1 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -84,7 +84,7 @@ Cross-Python compatibility -------------------------- testtools gives you the very latest in unit testing technology in a way that -will work with Python 3.9+ and PyPy3. +will work with Python 3.10+ and PyPy3. If you wish to use testtools with Python 2.4 or 2.5, then please use testtools 0.9.15. diff --git a/pyproject.toml b/pyproject.toml index 983a885b..3290db04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,10 +14,11 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "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", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", @@ -26,7 +27,7 @@ classifiers = [ "Topic :: Software Development :: Testing", ] dynamic = ["version"] -requires-python = ">=3.9" +requires-python = ">=3.10" [project.urls] Homepage = "https://github.com/testing-cabal/testtools" diff --git a/testtools/testresult/real.py b/testtools/testresult/real.py index 626f1240..9e430b70 100644 --- a/testtools/testresult/real.py +++ b/testtools/testresult/real.py @@ -221,7 +221,6 @@ def startTestRun(self): self.unexpectedSuccesses = [] self.failfast = failfast # -- End: As per python 2.7 -- - # -- Python 3.5 self.tb_locals = tb_locals # -- Python 3.12 self.collectedDurations = [] diff --git a/testtools/tests/test_testresult.py b/testtools/tests/test_testresult.py index 366d7ef6..3c60cc7a 100644 --- a/testtools/tests/test_testresult.py +++ b/testtools/tests/test_testresult.py @@ -3053,11 +3053,9 @@ def test_syntax_error(self): """Syntax errors should still have fancy special-case formatting""" if platform.python_implementation() == "PyPy": spaces = " " - elif sys.version_info >= (3, 10): - spaces = " " else: - spaces = " " - marker = "^^^" if sys.version_info >= (3, 10) else "^" + spaces = " " + marker = "^^^" textoutput = self._test_external_case("exec ('f(a, b c)')") self.assertIn( self._as_output( @@ -3143,7 +3141,7 @@ def test_syntax_error_line_utf_8(self): textoutput = self._setup_external_case("import bad") self._write_module("bad", "utf-8", f"\ufeff^ = 0 # {text}\n") textoutput = self._run_external_case() - # Python 3.9 no longer prints the '\ufeff' + # Python no longer prints the '\ufeff' textoutput = textoutput.replace("\ufeff", "") self.assertThat( textoutput, diff --git a/testtools/twistedsupport/_spinner.py b/testtools/twistedsupport/_spinner.py index e0904204..b26d1d83 100644 --- a/testtools/twistedsupport/_spinner.py +++ b/testtools/twistedsupport/_spinner.py @@ -17,7 +17,7 @@ ] import signal -from typing import ClassVar, Union +from typing import ClassVar from fixtures import Fixture from twisted.internet import defer @@ -159,7 +159,7 @@ class Spinner: # the ideal, and it actually works for many cases. _OBLIGATORY_REACTOR_ITERATIONS = 0 - _failure: Union[Failure, object] + _failure: Failure | object def __init__(self, reactor, debug=False): """Construct a Spinner. diff --git a/tox.ini b/tox.ini index 02edefaf..545fccfb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py39,py310,py311,py312,py313,pypy3 +envlist = py310,py311,py312,py313,py314,pypy3 minversion = 4.2 [testenv]