Skip to content

Drop python 3.10 support - #207

Merged
Kilo59 merged 10 commits into
mainfrom
drop-py310
Aug 22, 2026
Merged

Drop python 3.10 support#207
Kilo59 merged 10 commits into
mainfrom
drop-py310

Conversation

@Kilo59

@Kilo59 Kilo59 commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Python 3.10 is going end of life on Oct 2026 (in approximately 2 months).
https://endoflife.date/python

Dropping support earlier simplifies our dependencies and enables new python 3.11+ features.

Summary by Sourcery

Drop Python 3.10 support and standardize development, CI, and runtime configuration on Python 3.11 and newer.

Bug Fixes:

  • Improve concurrent upstream error handling so failures from cancelled sibling tasks are reported consistently.

Enhancements:

  • Raise the minimum supported Python version to 3.11 and adopt Python 3.11 features and standard-library typing improvements.
  • Refresh development tooling and dependency requirements, including migration from pre-commit to prek.
  • Update project documentation and type-checking, linting, and test configuration for Python 3.11+.

Build:

  • Update package metadata, versioning, Python requirements, classifiers, and lockfile for the refreshed dependency baseline.

CI:

  • Remove Python 3.10 from CI, static analysis, complexity, documentation, and build workflows while retaining testing across Python 3.11–3.14.

Documentation:

  • Update contributor documentation and project guidance to reflect Python 3.11+ support and prek-based hooks.

Tests:

  • Update tests for the new Python baseline and add coverage for concurrent upstream failures with cancelled sibling tasks.

Chores:

  • Upgrade the Ruff pre-commit hook and clean up obsolete type-check suppression comments.

@sourcery-ai

sourcery-ai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Reviewer's Guide

Drop Python 3.10 support, standardize tooling and CI on Python 3.11+, and adopt Python 3.11-specific language and stdlib features while cleaning up type hints and tests.

File-Level Changes

Change Details Files
Raise minimum supported Python version to 3.11 and align project metadata, linting, and type checking configuration.
  • Set project requires-python to >=3.11 and remove Python 3.10 classifier.
  • Update mypy configuration to python_version = "3.11" and keep strict mode.
  • Retarget Ruff configuration to target-version = "py311" and adjust test expectations accordingly.
  • Update internal constants and tests to reflect MIN_PYTHON_VERSION = 3.11.
pyproject.toml
src/ruff_sync/constants.py
tests/test_project.py
tests/test_basic.py
tests/test_serialization.py
tests/test_benchmarks.py
tests/lifecycle_tomls/multi_upstream_final.toml
Update CI workflows and documentation to drop Python 3.10 from the matrix and run against Python 3.11+ only.
  • Change all workflow setup steps to install/use Python 3.11 instead of 3.10.
  • Remove 3.10 from the CI test matrix while keeping 3.11–3.14.
  • Update complexity analysis workflow to run on Python 3.11.
  • Align contributor and agent documentation with new Python version range and CI behavior.
.github/workflows/ci.yaml
.github/workflows/complexity.yaml
AGENTS.md
CONTRIBUTING.md
docs/contributing.md
Modernize async concurrency and typing imports using Python 3.11+ features.
  • Remove Python 3.10-specific async fallback and use asyncio.TaskGroup unconditionally with except* handling for upstream fetch errors.
  • Switch enum classes from str, enum.Enum to enum.StrEnum now that Python 3.11+ is guaranteed.
  • Move NotRequired import from typing_extensions to typing and simplify type hints accordingly.
src/ruff_sync/core.py
src/ruff_sync/config_io.py
src/ruff_sync/constants.py
src/ruff_sync/types_.py
Standardize development tooling on prek and newer dependency versions and clean up tests/tasks type ignores.
  • Replace pre-commit dev dependency with prek and bump versions of mypy, pytest, pytest-codspeed, ruff, and other dev tools.
  • Update documentation to instruct contributors to install hooks via uv run prek install and describe tooling accordingly.
  • Remove several mypy type-ignore comments in tasks and tests where they are no longer needed or where TOML structures are now treated as Any.
  • Bump project version to 0.1.9.dev0 and refresh uv.lock to reflect new dependency set.
pyproject.toml
.pre-commit-config.yaml
AGENTS.md
CONTRIBUTING.md
docs/contributing.md
tasks.py
tests/test_basic.py
tests/test_project.py
tests/test_serialization.py
tests/test_benchmarks.py
tests/test_basic.py
uv.lock

Possibly linked issues

  • #unknown: The PR directly implements the issue by raising the minimum Python version to 3.11 and removing Python 3.10 support.
  • #unknown: The PR resolves the issue by choosing Python 3.11 as the minimum supported version and updating tooling, CI, and documentation.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="pyproject.toml" line_range="11" />
<code_context>
 ]
 license = { text = "MIT" }
 readme = "README.md"
-requires-python = ">=3.10"
+requires-python = ">=3.11"
 classifiers = [
     "Development Status :: 4 - Beta",
</code_context>
<issue_to_address>
**issue (broader_impact):** The repository CI and contributor instructions still provision Python 3.10, but `uv sync --frozen` and `pip install .` now reject Python 3.10 because the project metadata requires `>=3.11`. The 3.10 entries remain in `.github/workflows/ci.yaml`, `.github/workflows/complexity.yaml`, `CONTRIBUTING.md`, and `AGENTS.md`, so CI jobs and documented development setup fail until those references are updated or removed.

**Triggers:** When the existing Python 3.10 CI jobs run or contributors follow the documented setup.

**Suggested fix:** Update all CI matrices/setup steps and contributor documentation to use Python 3.11+; remove Python 3.10 from the test matrix.
</issue_to_address>

### Comment 2
<location path="pyproject.toml" line_range="53-52" />
<code_context>
     "invoke>=2.2.0",
     "mypy>=1.10.0",
     "packaging>=26.0",
-    "pre-commit>=3.7.0",
+    "prek>=0.4.14",
     "pyfakefs>=5.4.1",
-    "pytest>=8.0.0",
</code_context>
<issue_to_address>
**issue (bug_risk):** The development dependency now installs `prek` instead of `pre-commit`, but `CONTRIBUTING.md` still instructs contributors to run `uv run pre-commit install`; that executable is not provided by the renamed dependency, so the documented hook-installation command fails.

**Triggers:** When a contributor follows the current Getting Started instructions after syncing dependencies.

**Suggested fix:** Change the documented command to `uv run prek install` and update any remaining setup instructions that invoke `pre-commit` as a local executable.
</issue_to_address>

### Comment 3
<location path="pyproject.toml" line_range="89-88" />
<code_context>
 packages = ["src/ruff_sync"]

 [tool.mypy]
-python_version = "3.10"
+python_version = "3.11"
 files = ["src", "tests/", "tasks.py", ".agents/"]
 strict = true
</code_context>
<issue_to_address>
**nitpick:** The repository's agent/development instructions still state that mypy uses `python_version = "3.10"`, while the configuration now analyzes code as Python 3.11. Contributors following those instructions receive incorrect type-checking expectations and can misdiagnose differences between documented and actual checks.

**Triggers:** When contributors use `AGENTS.md` to understand or reproduce the type-check configuration.

**Suggested fix:** Update the stale Python-version references in `AGENTS.md` and related development documentation from 3.10 to 3.11.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and this changes the published compatibility policy so every Python 3.10 user is blocked from installing or upgrading to this version, and the decision is effective immediately without a runtime failure signal. Reverting the repository change would not undo the incompatibility for any package artifact already released.

Blocking findings: pyproject.toml:11, pyproject.toml:52


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread pyproject.toml
Comment thread pyproject.toml
Comment thread pyproject.toml
@codspeed-hq

codspeed-hq Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 1.21%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

#### 🎉 Hooray! `pytest-codspeed` just leveled up to 5.0.3!

A heads-up, this is a breaking change and it might affect your current performance baseline a bit. But here's the exciting part - it's packed with new, cool features and promises improved result stability 🥳!
Curious about what's new? Visit our releases page to delve into all the awesome details about this new version.

⚡ 4 improved benchmarks
❌ 4 regressed benchmarks
✅ 7 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_bench_resolve_raw_url_github_blob 187 µs 286.6 µs -34.77%
test_bench_resolve_raw_url_github_repo 249.9 µs 361.9 µs -30.94%
test_bench_resolve_raw_url_gitlab 224.9 µs 324.9 µs -30.78%
test_bench_resolve_raw_url_github_tree 284.1 µs 382 µs -25.64%
test_bench_get_ruff_config_small 2.7 ms 1.6 ms +69.44%
test_bench_get_ruff_config_large 17.5 ms 13.1 ms +33.86%
test_bench_toml_parse_and_serialize 18 ms 13.6 ms +32.86%
test_bench_get_ruff_config_with_exclusions 18.3 ms 14.1 ms +29.86%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing drop-py310 (4435a46) with main (b8bece2)

Open in CodSpeed

@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.44444% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.21%. Comparing base (b8bece2) to head (4435a46).

Files with missing lines Patch % Lines
src/ruff_sync/core.py 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #207      +/-   ##
==========================================
+ Coverage   94.06%   94.21%   +0.14%     
==========================================
  Files          10       10              
  Lines        1602     1590      -12     
==========================================
- Hits         1507     1498       -9     
+ Misses         95       92       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Kilo59 Kilo59 added dependencies Pull requests that update a dependency file dev-ex Developer Experiance related improvements labels Aug 22, 2026
@Kilo59

Kilo59 commented Aug 22, 2026

Copy link
Copy Markdown
Owner Author

@sourcery-ai review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/ruff_sync/core.py" line_range="711-714" />
<code_context>
-
-        return fetch_results
+        return [t.result() for t in tasks]
+    except* Exception as eg:
+        errors: list[tuple[URL, BaseException]] = []
+        for i, t in enumerate(tasks):
+            if t.done():
+                exc = t.exception()
+                if exc is not None:
+                    errors.append((upstream_list[i], exc))
+        if errors:
+            raise UpstreamError(errors) from eg
</code_context>
<issue_to_address>
**issue (bug_risk):** When one upstream task fails and TaskGroup cancels a slower sibling, `t.exception()` raises `asyncio.CancelledError` for the cancelled task instead of returning an exception. The exception handler therefore escapes before raising the documented `UpstreamError`, so callers receive cancellation rather than the aggregated upstream failure.

**Triggers:** When upstream fetches complete at different times and at least one failing fetch cancels another in-flight fetch.

**Suggested fix:** Skip cancelled tasks before calling `t.exception()`, for example with `if t.done() and not t.cancelled():`, while preserving the original failure in the aggregated errors.

```suggestion
            if t.done() and not t.cancelled():
                exc = t.exception()
                if exc is not None:
                    errors.append((upstream_list[i], exc))
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: src/ruff_sync/core.py:714


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/ruff_sync/core.py Outdated
@Kilo59
Kilo59 enabled auto-merge (squash) August 22, 2026 17:58
@github-actions

Copy link
Copy Markdown
Contributor
╒═══════════════╤═════════════════╤════════════╤═════════════════╤══════════════╕
│ File          │ Maintainabili   │ Unique     │ Lines of Code   │ Cyclomatic   │
│               │ ty Index        │ Operands   │                 │ Complexity   │
╞═══════════════╪═════════════════╪════════════╪═════════════════╪══════════════╡
│ tasks.py      │ 43.89 ->        │ 11 -> 11   │ 299 -> 299      │ 54 -> 54     │
│               │ 42.2348         │            │                 │              │
├───────────────┼─────────────────┼────────────┼─────────────────┼──────────────┤
│ tests/test_pr │ 70.132 ->       │ 2 -> 2     │ 78 -> 78        │ 7 -> 7       │
│ oject.py      │ 69.1672         │            │                 │              │
├───────────────┼─────────────────┼────────────┼─────────────────┼──────────────┤
│ tests/test_se │ 36.2583 ->      │ 6 -> 6     │ 516 -> 516      │ 21 -> 21     │
│ rialization.p │ 36.0148         │            │                 │              │
│ y             │                 │            │                 │              │
├───────────────┼─────────────────┼────────────┼─────────────────┼──────────────┤
│ tests/test_be │ 69.9279 ->      │ 1 -> 1     │ 338 -> 338      │ 15 -> 15     │
│ nchmarks.py   │ 69.6286         │            │                 │              │
├───────────────┼─────────────────┼────────────┼─────────────────┼──────────────┤
│ tests/test_ba │ 21.0398 ->      │ 13 -> 13   │ 984 -> 1007     │ 58 -> 59     │
│ sic.py        │ 19.5941         │            │                 │              │
╘═══════════════╧═════════════════╧════════════╧═════════════════╧══════════════╛

@Kilo59
Kilo59 merged commit 4903d8e into main Aug 22, 2026
18 checks passed
@Kilo59
Kilo59 deleted the drop-py310 branch August 22, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file dev-ex Developer Experiance related improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant