diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a38b706a..5344d66e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,24 +21,24 @@ jobs: matrix: # Test all supported versions on Ubuntu: os: [ubuntu-latest, ubuntu-24.04-arm] - python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python: ["3.11", "3.12", "3.13", "3.14", "3.15"] experimental: [false] build: [''] include: # As the experimental task for the dev version. - os: ubuntu-latest - python: "3.14" + python: "3.15" experimental: true build: 'free-threading' - os: ubuntu-24.04-arm - python: "3.14" + python: "3.15" experimental: true build: 'free-threading' - os: ubuntu-latest - python: "3.15-dev" + python: "3.16-dev" experimental: true - os: ubuntu-latest - python: "3.15-dev" + python: "3.16-dev" experimental: true build: 'free-threading' # Also test PyPy, macOS, and Windows: @@ -46,10 +46,10 @@ jobs: python: pypy-3.11 experimental: false - os: macos-latest - python: "3.14" + python: "3.15" experimental: true - os: windows-latest - python: "3.14" + python: "3.15" experimental: false steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/doc/changelog.rst b/doc/changelog.rst index 8735b3bb..6e0adfd3 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,7 +1,13 @@ Changelog ========= -Version 1.14.0 +Version 1.15.0 (unreleased) +-------------- +* Add support for Python 3.15 and drop 3.10 +* Bump tornado to 6.6 (fixes ``BufferError`` on PyPy) +* Bump genshi to 0.7.12 (fixes ``TypeError`` on Python 3.15) + +Version 1.14.0 (2026-02-07) -------------- * Bump ``pyperf`` to 2.10.0 * Add base64 module benchmark (b64, b32, b16, a85, b85) diff --git a/doc/conf.py b/doc/conf.py index 202335f6..d3bc05ea 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Python Performance Benchmark Suite documentation build configuration file, created by # sphinx-quickstart on Tue Mar 28 15:59:41 2017. diff --git a/examples/benchmarking-scripts/backfill.py b/examples/benchmarking-scripts/backfill.py index 313ca479..5b873fdd 100644 --- a/examples/benchmarking-scripts/backfill.py +++ b/examples/benchmarking-scripts/backfill.py @@ -16,7 +16,7 @@ def get_revisions() -> tuple[str, str]: revisions = [] - with open("backfill_shas.txt", "r") as f: + with open("backfill_shas.txt") as f: for line in f: sha, branch = line.split("=") revisions.append((sha, branch.rstrip())) diff --git a/pyperformance/_pyproject_toml.py b/pyperformance/_pyproject_toml.py index 40b26e82..17d4afd4 100644 --- a/pyperformance/_pyproject_toml.py +++ b/pyperformance/_pyproject_toml.py @@ -12,6 +12,7 @@ import os.path import re +import tomllib import urllib.parse import packaging.requirements @@ -19,11 +20,6 @@ import packaging.utils import packaging.version -try: - import tomllib # type: ignore[import-not-found] # tomllib doesn't exist on 3.7-3.10 -except ImportError: - import tomli as tomllib - from ._utils import check_name NAME_RE = re.compile("^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE) diff --git a/pyperformance/compare.py b/pyperformance/compare.py index 176d797d..b9089796 100644 --- a/pyperformance/compare.py +++ b/pyperformance/compare.py @@ -231,7 +231,7 @@ def format_table(base_label, changed_label, results): return "\n".join(output) -class BenchmarkResult(object): +class BenchmarkResult: """An object representing data from a succesful benchmark run.""" def __init__(self, base, changed): diff --git a/pyperformance/compile.py b/pyperformance/compile.py index c1ffe06d..447256fd 100644 --- a/pyperformance/compile.py +++ b/pyperformance/compile.py @@ -43,7 +43,7 @@ def replace_timezone(regs): return datetime.datetime.strptime(text2, "%Y-%m-%dT%H:%M:%S%z") -class Task(object): +class Task: def __init__(self, app, cwd): self.app = app self.cwd = cwd @@ -118,14 +118,14 @@ def get_revision_info(self, revision): node, date = stdout.split("|") date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S %z") # convert local date to UTC - date = (date - date.utcoffset()).replace(tzinfo=datetime.timezone.utc) + date = (date - date.utcoffset()).replace(tzinfo=datetime.UTC) else: node, date = stdout.split("|") date = datetime.datetime.strptime(date[:16], "%Y-%m-%d %H:%M") return (node, date) -class Application(object): +class Application: def __init__(self, conf, options): self.conf = conf self.options = options diff --git a/pyperformance/data-files/benchmarks/bm_genshi/requirements.txt b/pyperformance/data-files/benchmarks/bm_genshi/requirements.txt index 3ea4b594..333291bd 100644 --- a/pyperformance/data-files/benchmarks/bm_genshi/requirements.txt +++ b/pyperformance/data-files/benchmarks/bm_genshi/requirements.txt @@ -1,2 +1 @@ -genshi==0.7.7 -six==1.16.0 +genshi==0.7.12 diff --git a/pyperformance/data-files/benchmarks/bm_tornado_http/requirements.txt b/pyperformance/data-files/benchmarks/bm_tornado_http/requirements.txt index 180ff786..f60a887b 100644 --- a/pyperformance/data-files/benchmarks/bm_tornado_http/requirements.txt +++ b/pyperformance/data-files/benchmarks/bm_tornado_http/requirements.txt @@ -1 +1 @@ -tornado==6.5.2 +tornado==6.6 diff --git a/pyperformance/tests/test_commands.py b/pyperformance/tests/test_commands.py index 5b44f015..f3924692 100644 --- a/pyperformance/tests/test_commands.py +++ b/pyperformance/tests/test_commands.py @@ -456,7 +456,7 @@ def test_compare_csv(self): filename = self.resolve_tmp("outfile.csv", unique=True) with tests.CleanupFile(filename): self.compare("--csv", filename) - with open(filename, "r", encoding="utf-8") as infile: + with open(filename, encoding="utf-8") as infile: csv = infile.read() self.assertEqual(csv, expected) diff --git a/pyperformance/tests/test_venv.py b/pyperformance/tests/test_venv.py index 3e0a6800..31912579 100644 --- a/pyperformance/tests/test_venv.py +++ b/pyperformance/tests/test_venv.py @@ -16,8 +16,6 @@ def new_venv_config( system_site_packages=False, executable=None, command=None, - *, - old=sys.version_info < (3, 11), ): if not home: home = os.path.dirname(sys.executable) @@ -26,11 +24,10 @@ def new_venv_config( if not isinstance(system_site_packages, str): system_site_packages = "true" if system_site_packages else "false" system_site_packages = system_site_packages == "true" - if not old: - if executable is None: - executable = sys.executable - if command is None: - command = f"{executable} -m venv {root}" + if executable is None: + executable = sys.executable + if command is None: + command = f"{executable} -m venv {root}" return types.SimpleNamespace( home=home, version=version, diff --git a/pyperformance/venv.py b/pyperformance/venv.py index 6c7301a9..871790e8 100644 --- a/pyperformance/venv.py +++ b/pyperformance/venv.py @@ -12,7 +12,7 @@ PYPERF_OPTIONAL = ["psutil"] -class Requirements(object): +class Requirements: @classmethod def from_file(cls, filename): self = cls() diff --git a/pyproject.toml b/pyproject.toml index 177d3c73..d1de8675 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ description = "Python benchmark suite" readme = "README.rst" license = { text = "MIT" } authors = [ { name = "Collin Winter" }, { name = "Jeffrey Yasskin" } ] -requires-python = ">=3.10" +requires-python = ">=3.11" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -55,21 +55,19 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "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.15", ] dynamic = [ "version" ] dependencies = [ "packaging", "pyperf", - "tomli; python_version<'3.11'", ] optional-dependencies.dev = [ "mypy==2.3.1", - "tomli", # Needed even on 3.11+ for typechecking with mypy "tox", ] urls = { Homepage = "https://github.com/python/pyperformance" } @@ -81,7 +79,7 @@ dynamic.version = { attr = "pyperformance.__version__" } packages.find = {} # Scanning implicit namespaces is active by default [tool.ruff] -target-version = "py310" +target-version = "py311" exclude = [ "pyperformance/data-files/", ] @@ -99,10 +97,10 @@ lint.ignore = [ ] [tool.pyproject-fmt] -max_supported_python = "3.14" +max_supported_python = "3.15" [tool.mypy] -python_version = "3.10" +python_version = "3.11" pretty = true enable_error_code = "ignore-without-code" disallow_any_generics = true diff --git a/requirements.in b/requirements.in index 55f432ef..04abf276 100644 --- a/requirements.in +++ b/requirements.in @@ -13,7 +13,6 @@ pyperf # for benchmark metadata: packaging -tomli; python_version < '3.11' # Optional dependencies diff --git a/tox.ini b/tox.ini index 12ab9b65..96836941 100644 --- a/tox.ini +++ b/tox.ini @@ -32,5 +32,4 @@ ignore = E501,E741,W503 basepython = python3 deps= mypy - tomli commands = mypy