From 7f4b682d727c470e3cfcaeb5e3ec0e7f641f71ef Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sat, 28 Mar 2026 15:28:47 -0400 Subject: [PATCH 1/5] Separate GitHub Actions into 3 separate workflows: Quality, Test, and TypeCheck Changes include: - Updated ruff to 0.15.8 in .pre-commit-config.yaml - Added default entry for next version to CHANGELOG with info on changes since last release - New quality.yml workflow for running pre-commit checks using prek (ruff, typos, and some generic whitespace checks) - ruff and typos checks moved here - Modified tests.yaml to run on all 3 supported oses: Windows and MacOs in addition to previous testing on Linux (Ubuntu) - New typecheck.yml - moved mypy type checking here --- .github/workflows/quality.yml | 36 +++++++++++++++++++++++++++++ .github/workflows/test.yaml | 35 ++++++++++------------------- .github/workflows/typecheck.yml | 40 +++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 2 +- CHANGELOG | 12 ++++++++++ 5 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/quality.yml create mode 100644 .github/workflows/typecheck.yml diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 000000000..d2402f2f8 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,36 @@ +# For documentation on GitHub Actions Workflows, see: +# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +# This workflow runs the pre-commit checks using prek on pull requests and pushes to the main branch. +# Specifically it runs ruff autoformatting and linting, typos for spellchecking, and other +# pre-commit hooks defined in .pre-commit-config.yaml. +name: Quality +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: [main] + +permissions: + contents: read + +jobs: + quality: + runs-on: ubuntu-latest + steps: + - name: Check out + uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 # Needed for setuptools_scm to work correctly + + - uses: actions/cache@v5 + with: + path: ~/.cache/pre-commit + key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v7 + with: + python-version: "3.14" + - name: Install the project + run: uv sync --group quality + - name: Run prek + run: uv run prek run -a --show-diff-on-failure diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 09092d2e5..bdb659b34 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,48 +1,37 @@ -name: test +# This workflow runs pytest unit tests and code coverage reporting on push and pull requests to the main branch. +# It tests against multiple Python versions and operating systemsto ensure compatibility. The workflow uses Codecov +# for coverage reporting, and the results are uploaded to Codecov using a secret token. +name: Test on: - push: # any branch - pull_request: + pull_request: # any branch + types: [opened, synchronize, reopened] + push: branches: [main] env: FORCE_COLOR: 1 jobs: - test-ubuntu: - runs-on: ubuntu-latest + test: strategy: fail-fast: false matrix: - python-version: - ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"] - + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15-dev"] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6.0.2 - uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} - - name: Code formatting - if: ${{ matrix.python-version == '3.14' }} - run: | - uv run ruff check . - uv run ruff format --check . - - name: Typos - if: ${{ matrix.python-version == '3.14' }} - run: | - uv run typos . - name: Unit test run: | uv run coverage run -m pytest tests/ - - name: Type Checking - run: | - uv run mypy --strict src/ --platform win32 - uv run mypy --strict src/ --platform linux - uv run mypy --strict src/ --platform darwin - name: Run codecov run: | uv run codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v6 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml new file mode 100644 index 000000000..67c8fee8a --- /dev/null +++ b/.github/workflows/typecheck.yml @@ -0,0 +1,40 @@ +# For documentation on GitHub Actions Workflows, see: +# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +# This workflow runs mypy type checking on push and pull requests to the main branch. +# It tests against multiple Python versions to ensure compatibility. +name: TypeCheck +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: [main] + +permissions: + contents: read + +jobs: + type-check: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + fail-fast: false + defaults: + run: + shell: bash + steps: + - name: Check out + uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v7 + with: + python-version: ${{ matrix.python-version }} + + - name: Type Checking + run: | + uv run mypy --strict src/ --platform win32 + uv run mypy --strict src/ --platform linux + uv run mypy --strict src/ --platform darwin diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ab2291c8b..99b577cc9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.6" + rev: "v0.15.8" hooks: - id: ruff-format args: [--config=pyproject.toml] diff --git a/CHANGELOG b/CHANGELOG index aba20450f..a663c0a7d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,18 @@ CHANGELOG ========= +3.0.53: 2026-0-TBD +------------------ + +New features: +- Lazy loading of `__version__` + +Fixes: +- Fix get_word_before_cursor behavior +- Fix various typing issues +- Set missing minimal requirement on `wcwidth` +- Fix vt100 6x6x6 color cube range and missing grayscale shades (232, 254-255) + 3.0.52: 2025-08-27 ------------------ From 198449ee3341d42a2edf0fd1a38ef4e90b5c8732 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sat, 28 Mar 2026 15:38:03 -0400 Subject: [PATCH 2/5] Fix a couple issues in quality.yaml and test.yaml --- .github/workflows/{quality.yml => quality.yaml} | 2 +- .github/workflows/test.yaml | 2 +- .github/workflows/{typecheck.yml => typecheck.yaml} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{quality.yml => quality.yaml} (96%) rename .github/workflows/{typecheck.yml => typecheck.yaml} (100%) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yaml similarity index 96% rename from .github/workflows/quality.yml rename to .github/workflows/quality.yaml index d2402f2f8..463b7e8f1 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yaml @@ -31,6 +31,6 @@ jobs: with: python-version: "3.14" - name: Install the project - run: uv sync --group quality + run: uv sync --group dev - name: Run prek run: uv run prek run -a --show-diff-on-failure diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index bdb659b34..f70e3dfc4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15-dev"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6.0.2 diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yaml similarity index 100% rename from .github/workflows/typecheck.yml rename to .github/workflows/typecheck.yaml From dbe792e1998f5eec88b287a4e77f844829564217 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sat, 28 Mar 2026 15:49:31 -0400 Subject: [PATCH 3/5] Remove unused appveyor.yml file This file was apparently used once upon a time for Windows testing using AppVeyor. --- appveyor.yml | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 892b1865e..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,45 +0,0 @@ -environment: - matrix: - - PYTHON: "C:\\Python36" - PYTHON_VERSION: "3.6" - - PYTHON: "C:\\Python36-x64" - PYTHON_VERSION: "3.6" - - - PYTHON: "C:\\Python35" - PYTHON_VERSION: "3.5" - - PYTHON: "C:\\Python35-x64" - PYTHON_VERSION: "3.5" - - - PYTHON: "C:\\Python34" - PYTHON_VERSION: "3.4" - - PYTHON: "C:\\Python34-x64" - PYTHON_VERSION: "3.4" - - - PYTHON: "C:\\Python33" - PYTHON_VERSION: "3.3" - - PYTHON: "C:\\Python33-x64" - PYTHON_VERSION: "3.3" - - - PYTHON: "C:\\Python27" - PYTHON_VERSION: "2.7" - - PYTHON: "C:\\Python27-x64" - PYTHON_VERSION: "2.7" - - - PYTHON: "C:\\Python26" - PYTHON_VERSION: "2.6" - - PYTHON: "C:\\Python27-x64" - PYTHON_VERSION: "2.6" - -install: - - "set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - pip install . pytest coverage codecov flake8 - - pip list - -build: false - -test_script: - - If not ($env:PYTHON_VERSION==2.6) flake8 prompt_toolkit - - coverage run -m pytest - -after_test: - - codecov From 978e064e804d984547e5a623607bd44f6296b2a1 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sat, 28 Mar 2026 16:14:01 -0400 Subject: [PATCH 4/5] Skip emacs history keybinding tests on Windows --- tests/test_cli.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index a876f2993..3de33cdf5 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -5,6 +5,7 @@ from __future__ import annotations +import sys from functools import partial import pytest @@ -318,6 +319,10 @@ def test_controlx_controlx(): assert result.text == "hello worldX" +@pytest.mark.skipif( + sys.platform.startswith("win"), + reason="emacs history bindings don't work on Windows", +) def test_emacs_history_bindings(): # Adding a new item to the history. history = _history() @@ -348,6 +353,10 @@ def test_emacs_history_bindings(): assert result.text == "line2 second input" +@pytest.mark.skipif( + sys.platform.startswith("win"), + reason="emacs history bindings don't work on Windows", +) def test_emacs_reverse_search(): history = _history() From 7f64dd2c83d89a60bb8badc13f0846fca69561c2 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Sat, 28 Mar 2026 16:21:41 -0400 Subject: [PATCH 5/5] Skip 2 tests failing on windows with a prompt_toolkit.output.win32.NoConsoleScreenBufferError --- tests/test_memory_leaks.py | 8 ++++++++ tests/test_shortcuts.py | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/tests/test_memory_leaks.py b/tests/test_memory_leaks.py index 08afac5e2..8c5f685c4 100644 --- a/tests/test_memory_leaks.py +++ b/tests/test_memory_leaks.py @@ -1,6 +1,9 @@ from __future__ import annotations import gc +import sys + +import pytest from prompt_toolkit.shortcuts.prompt import PromptSession @@ -15,6 +18,11 @@ def _count_prompt_session_instances() -> int: # This test used to fail in GitHub CI, probably due to GC differences. +# Still fails on Windows due to win32.NoConsoleScreenBufferError. +@pytest.mark.skipif( + sys.platform.startswith("win"), + reason="Fails in GitHug CI due to win32.NoConsoleScreenBufferError", +) def test_prompt_session_memory_leak() -> None: before_count = _count_prompt_session_instances() diff --git a/tests/test_shortcuts.py b/tests/test_shortcuts.py index 287c6d33a..5d395342d 100644 --- a/tests/test_shortcuts.py +++ b/tests/test_shortcuts.py @@ -1,5 +1,9 @@ from __future__ import annotations +import sys + +import pytest + from prompt_toolkit.shortcuts import print_container from prompt_toolkit.shortcuts.prompt import _split_multiline_prompt from prompt_toolkit.widgets import Frame, TextArea @@ -55,6 +59,11 @@ def test_split_multiline_prompt(): assert first_input_line() == [("class:testclass", "a"), ("class:testclass", "b")] +# Test fails on Windows due to win32.NoConsoleScreenBufferError. +@pytest.mark.skipif( + sys.platform.startswith("win"), + reason="Fails in GitHug CI due to win32.NoConsoleScreenBufferError", +) def test_print_container(tmpdir): # Call `print_container`, render to a dummy file. f = tmpdir.join("output")