diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1afc4c..7a29f4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: "3.12" + python-version: "3.14" cache: pip - run: pip install -e ".[dev]" - name: Ruff (lint) @@ -34,7 +34,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.12", "3.13"] + python-version: ["3.14"] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74803bb..e0006c5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,17 +3,17 @@ # pyproject.toml (run `pre-commit autoupdate` and bump pyproject together). repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.4 + rev: v0.16.4 hooks: - id: ruff-check args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.2 + rev: v2.3.1 hooks: - id: mypy pass_filenames: false additional_dependencies: - - chess==1.10.0 - - pytest==9.0.3 + - chess==1.11.2 + - pytest==9.1.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8efeab8..4c2ca45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,13 +19,13 @@ follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Packaging: `src/pychess/` layout, `pyproject.toml`, `pychess` console script, `py.typed`. - Tooling: Ruff (lint + format), Mypy, pytest-cov (85% gate), `pre-commit`, all - run in CI on Python 3.12 and 3.13, with Codecov coverage + test-analytics - uploads. + run in CI, with Codecov coverage + test-analytics uploads. - `perft` regression tests against published node counts; unit tests for every module. ### Changed +- Require Python 3.14 (`requires-python = ">=3.14"`); CI runs on 3.14 only. - Search rebuilt as composed collaborators (`Negamax` is handed an evaluator, move orderer, TT, and clock) instead of a cooperative-multiple-inheritance mixin stack. diff --git a/CLAUDE.md b/CLAUDE.md index c86432c..052d03e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,7 +1,7 @@ # Agent guide `pychess` is a UCI chess engine: Lazy SMP negamax with a tapered PeSTO -evaluation. `src/` layout, Python 3.12+. +evaluation. `src/` layout, Python 3.14+. ## Commands @@ -15,7 +15,7 @@ pytest # tests + coverage; gate is 85% ``` All tool config lives in `pyproject.toml`. CI (`.github/workflows/ci.yml`) runs -exactly these on 3.12 and 3.13; `pre-commit` mirrors lint/format/type locally. +exactly these on 3.14; `pre-commit` mirrors lint/format/type locally. Skills in `.claude/skills/`: `/pr-check`, `/update-docs`, `/bench`, `/release`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3c2264e..10c917b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Setup ```bash -python3.12 -m venv .venv && source .venv/bin/activate +python3.14 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" pre-commit install ``` diff --git a/README.md b/README.md index df984a0..6d99475 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # pychess [![ci](https://github.com/cjunius/pyChess/actions/workflows/ci.yml/badge.svg)](https://github.com/cjunius/pyChess/actions/workflows/ci.yml) -[![python](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue)](pyproject.toml) +[![python](https://img.shields.io/badge/python-3.14-blue)](pyproject.toml) [![codecov](https://codecov.io/gh/cjunius/pyChess/branch/main/graph/badge.svg)](https://codecov.io/gh/cjunius/pyChess) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE) [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) @@ -34,7 +34,7 @@ rating; [docs/performance.md](docs/performance.md) for search-speed benchmarks. ## Quick start -Requires Python 3.12+. +Requires Python 3.14+. ```bash git clone https://github.com/cjunius/pyChess.git @@ -98,7 +98,7 @@ pytest # tests + coverage (gate: 85%) ``` CI (`.github/workflows/ci.yml`) runs lint + format + type-check once and the -test suite on Python 3.12 and 3.13. All tool config lives in `pyproject.toml`. +test suite on Python 3.14. All tool config lives in `pyproject.toml`. ## License diff --git a/pyproject.toml b/pyproject.toml index deb70b1..b026b27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" name = "pychess" description = "A UCI chess engine: Lazy SMP negamax with a tapered PeSTO evaluation." readme = "README.md" -requires-python = ">=3.12" +requires-python = ">=3.14" license = { file = "LICENSE" } authors = [{ name = "cjunius" }] keywords = ["chess", "uci", "engine", "negamax", "lazy-smp", "pesto"] @@ -15,8 +15,7 @@ classifiers = [ "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Games/Entertainment :: Board Games", "Typing :: Typed", ] @@ -67,7 +66,7 @@ exclude_also = [ [tool.ruff] line-length = 100 -target-version = "py312" +target-version = "py314" src = ["src", "tests"] [tool.ruff.lint] @@ -89,7 +88,7 @@ select = [ known-first-party = ["pychess"] [tool.mypy] -python_version = "3.12" +python_version = "3.14" files = ["src", "tests"] strict = true diff --git a/src/pychess/__main__.py b/src/pychess/__main__.py index 3b24965..ec2713d 100644 --- a/src/pychess/__main__.py +++ b/src/pychess/__main__.py @@ -117,7 +117,7 @@ def book_move(self) -> chess.Move | None: try: with polyglot.MemoryMappedReader(BOOK_PATH) as reader: return reader.weighted_choice(self.board).move - except (IndexError, FileNotFoundError, OSError): + except IndexError, FileNotFoundError, OSError: return None def print_info(self, result: SearchResult) -> None: diff --git a/src/pychess/eval_board.py b/src/pychess/eval_board.py index 2b919f4..865415e 100644 --- a/src/pychess/eval_board.py +++ b/src/pychess/eval_board.py @@ -71,7 +71,7 @@ def pop(self) -> chess.Move: # -- copying ---------------------------------------------------------- - def copy(self, *, stack: bool | int = True) -> "EvalBoard": + def copy(self, *, stack: bool | int = True) -> EvalBoard: board = super().copy(stack=stack) board._mg, board._eg, board._phase = self._mg, self._eg, self._phase board._eval_stack = list(self._eval_stack) if stack else []