mirror of
https://github.com/ankitects/anki.git
synced 2026-06-10 11:59:23 -04:00
dependabot/uv/python-minor-patch-e6e7004fb4
12276 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7a69185950 |
chore(deps): bump the python-minor-patch group across 1 directory with 5 updates
Bumps the python-minor-patch group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [ruff](https://github.com/astral-sh/ruff) | `0.13.3` | `0.15.15` | | [coverage](https://github.com/coveragepy/coveragepy) | `7.13.5` | `7.14.1` | | [decorator](https://github.com/micheles/decorator) | `5.2.1` | `5.3.1` | | [orjson](https://github.com/ijl/orjson) | `3.11.8` | `3.11.9` | | [requests](https://github.com/psf/requests) | `2.33.1` | `2.34.2` | Updates `ruff` from 0.13.3 to 0.15.15 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.13.3...0.15.15) Updates `coverage` from 7.13.5 to 7.14.1 - [Release notes](https://github.com/coveragepy/coveragepy/releases) - [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst) - [Commits](https://github.com/coveragepy/coveragepy/compare/7.13.5...7.14.1) Updates `decorator` from 5.2.1 to 5.3.1 - [Release notes](https://github.com/micheles/decorator/releases) - [Changelog](https://github.com/micheles/decorator/blob/master/CHANGES.md) - [Commits](https://github.com/micheles/decorator/compare/5.2.1...5.3.1) Updates `orjson` from 3.11.8 to 3.11.9 - [Release notes](https://github.com/ijl/orjson/releases) - [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md) - [Commits](https://github.com/ijl/orjson/compare/3.11.8...3.11.9) Updates `requests` from 2.33.1 to 2.34.2 - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.33.1...v2.34.2) --- updated-dependencies: - dependency-name: coverage dependency-version: 7.14.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: python-minor-patch - dependency-name: decorator dependency-version: 5.3.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: python-minor-patch - dependency-name: orjson dependency-version: 3.11.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: python-minor-patch - dependency-name: requests dependency-version: 2.34.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: python-minor-patch - dependency-name: ruff dependency-version: 0.15.14 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: python-minor-patch ... Signed-off-by: dependabot[bot] <support@github.com> |
||
|
|
f5d9b9ef3c |
chore: Integrate Complexipy for complexity analysis (#4942)
## Linked issue Closes #4815 ## Summary This adds [Complexipy](https://github.com/rohaquinlop/complexipy) for detecting complex Python code: - The `check:complexity` Ninja actions use a high threshold (50) for now to avoid failing on existing complex code. - `just complexipy-diff` is intended for linting new code in PR CI and uses 15 as the threshold. See https://rohaquinlop.github.io/complexipy/usage-guide/#ratchet-mode ## How to test - Run `./ninja check:complexity` locally and confirm it passes. - Test diff mode: `just complexipy-diff main`. |
||
|
|
da64f03307 |
chore(deps): consolidated security updates (Dependabot batch) (#4934)
## Summary Consolidates 8 open Dependabot PRs into a single security-focused batch. ### Addressed advisories - GHSA: tar (Cargo) [#296](https://github.com/ankitects/anki/security/dependabot/296) - @tootallnate/once [#295](https://github.com/ankitects/anki/security/dependabot/295) - ws [#293](https://github.com/ankitects/anki/security/dependabot/293) - openssl [#292](https://github.com/ankitects/anki/security/dependabot/292) - idna [#291](https://github.com/ankitects/anki/security/dependabot/291) - devalue [#287](https://github.com/ankitects/anki/security/dependabot/287)/[#239](https://github.com/ankitects/anki/security/dependabot/239)/[#217](https://github.com/ankitects/anki/security/dependabot/217)/[#216](https://github.com/ankitects/anki/security/dependabot/216) - postcss [#275](https://github.com/ankitects/anki/security/dependabot/275) - svelte [#286](https://github.com/ankitects/anki/security/dependabot/286)/[#288](https://github.com/ankitects/anki/security/dependabot/288)/[#289](https://github.com/ankitects/anki/security/dependabot/289) - lodash-es [#258](https://github.com/ankitects/anki/security/dependabot/258)/[#259](https://github.com/ankitects/anki/security/dependabot/259) - @sveltejs/kit [#294](https://github.com/ankitects/anki/security/dependabot/294) ### Sources Merged from PRs: #4914, #4887, #4867, #4866, #4865, #4846, #4744, #4892. ### Not addressed — rand (Cargo) [#268](https://github.com/ankitects/anki/security/dependabot/268) PR #4741 (rand 0.9.4 → 0.10.1) was excluded because `fsrs 5.2.0` still depends on `rand 0.9.4`. The rand 0.10 API changes (`Rng` → `RngExt`) cause a compile error at the `PostSchedulingFn` boundary. This will be unblocked when fsrs is upgraded. ### Not addressed (transitive — follow-up) - urllib3 [#284](https://github.com/ankitects/anki/security/dependabot/284)/[#283](https://github.com/ankitects/anki/security/dependabot/283) - GitPython [#282](https://github.com/ankitects/anki/security/dependabot/282) - ip-address [#276](https://github.com/ankitects/anki/security/dependabot/276) - pytest [#266](https://github.com/ankitects/anki/security/dependabot/266) - Pygments [#256](https://github.com/ankitects/anki/security/dependabot/256) - brace-expansion [#255](https://github.com/ankitects/anki/security/dependabot/255)/[#158](https://github.com/ankitects/anki/security/dependabot/158) - picomatch [#253](https://github.com/ankitects/anki/security/dependabot/253)/[#252](https://github.com/ankitects/anki/security/dependabot/252) - tar (npm) [#238](https://github.com/ankitects/anki/security/dependabot/238)/[#235](https://github.com/ankitects/anki/security/dependabot/235)/[#209](https://github.com/ankitects/anki/security/dependabot/209) - immutable [#231](https://github.com/ankitects/anki/security/dependabot/231) - minimatch [#227](https://github.com/ankitects/anki/security/dependabot/227)/[#226](https://github.com/ankitects/anki/security/dependabot/226)/[#221](https://github.com/ankitects/anki/security/dependabot/221) - fabric [#211](https://github.com/ankitects/anki/security/dependabot/211) These need manual `yarn.lock` resolutions / `uv.lock` overrides. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
0073124811 |
chore: Bump anki-audio to 0.2.1 (#4947)
## Linked issue #4918 #4949 ## Summary Bump anki-audio to 0.2.1 for the macOS hotfix. ## Steps to reproduce (before) Audio playback/recording on macOS was broken (see issue). ## How to test (after) Confirm audio is working now. |
||
|
|
935cabbcf6 |
chore: Updates just recipes and add AGENTS.md (#4943)
## Linked issue Closes #4836 ## Summary/motivation Three related housekeeping changes to improve AI-agent and developer ergonomics: 1. **justfile**: Expose `./run`, `./run.bat` (Windows), `./tools/web-watch`, `./tools/rebuild-web`, and `./tools/clean` as `just` recipes (`run`, `run-optimized`, `web-watch`, `rebuild-web`, `clean`), consistent with the Project convention that all commands go through `just`. 2. **CLAUDE.md**: Add a "Running Anki" section documenting `just run` and `just web-watch`; tighten the opening note to explicitly mention `./run`. 3. **AGENTS.md**: Add a symlink to `CLAUDE.md` so that OpenAI Codex and other Agents that look for `AGENTS.md` pick up the same project instructions. ## How to test - `just run` launches Anki in dev mode (same as `./run`) - `just run-optimized` launches with `RELEASE=1` - `just web-watch` starts the file-watcher (macOS/Linux) - `just clean` removes build outputs - `AGENTS.md` resolves to the same content as `CLAUDE.md` |
||
|
|
27f8e8c263 |
fix: custom mpv.rb formula not being used (#4950)
## Linked issue Closes #4949 ## Summary It turned out that our mpv.rb formula was never used because of the `bottle do` statement, which was telling brew to use the upstream version. ## Steps to reproduce (before) 1. Download and extract anki-audio==0.2.1: https://pypi.org/project/anki-audio/0.2.1/ 2. Run `./mpv --version` and confirm you see the error in the linked issue. ## How to test (after) 1. Extract the signed artifacts built from this PR: https://github.com/ankitects/anki/actions/runs/26877282940 2. Run `./mpv --version` and confirm no library errors. You might see Gatekeeper warnings here as the binary is not notarized. |
||
|
|
a62e6f7370 |
docs: expand contributing guide with PR process and test requirements (#4946)
## Linked issue Closes #4945 ## Summary / motivation Two small clarifications to the contributing guide: - Added a **Pull Request Description** section pointing contributors to the PR template (`.github/pull_request_template.md`), so they know upfront what fields are required before opening a PR. - Strengthened the test coverage requirement from "please consider" to a clear rule, with explicit exceptions (version bumps, docs, translations, dependency updates, chore). |
||
|
|
c71c13b56e |
fix: prevent duplicate "missing linked issue" comments on PR edits (#4937)
Fixes #4936 ## Problem The `check-linked-issue` workflow runs on every `opened` and `edited` PR event. When a PR had no linked issue, each edit triggered a new bot comment, resulting in duplicates (e.g. #4934). ## Solution Before posting the comment, list the existing PR comments and skip posting if the bot has already left one with the same message. The `missing-issue` label re-application is harmless since GitHub deduplicates labels automatically. |
||
|
|
fc5103bc33 |
chore(ci):Use commit SHAs for github actions (#4916)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) <!-- Fixes #123 / Closes #123 / Refs #123 --> closes #4722 ## Summary / motivation (required) <!-- What this PR does and why. For larger changes, add enough context for reviewers. --> I used this nice script I found: https://gist.github.com/onnimonni/3462f958c7d235417863651974514525 For the reasons behind this change see: - #4722 ## Steps to reproduce (required, use N/A if not applicable) <!-- Steps to reproduce: how to trigger the bug in the broken state (the "before"). - Mainly for bugfixes; - For bugs: numbered steps before the fix. For non-bugs: write N/A. - use N/A for features, refactors, docs, chore, etc. --> (N/A) ## How to test (required) <!--- How to test: how you verified the change (checks, unit tests, manual steps, edge cases — the "after" or general validation). ---> See it run in my repo here: https://github.com/Luc-Mcgrady/anki/actions/runs/26718877866 ### Checklist (minimum) - [X] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> ## Before / after behavior (optional) <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <!-- Screenshot or short video --> ## Scope - [X] This PR is focused on one change (no unrelated edits). |
||
|
|
398b51b2ed |
fix: wrong path of mpv libs in anki-audio wheel (#4919)
## Linked issue Closes #4918 ## Summary The anki-audio wheel build script was accidentally using `lib` instead of `libs` for copied mpv libraries. ## Steps to reproduce (before) Follow reproduction steps in the forum report and confirm you see the issue. ## How to test (after) - Build the wheel: `./qt/audio/build.sh`. - Confirm `qt/audio/anki_audio/libs` is created. - Extract `out/wheels/anki_audio-0.2.0-*.whl` and confirm it has the correct structure. - Run mpv in the extracted wheel: `./mpv` and confirm no library errors. |
||
|
|
2f3cff1b38 |
chore: Exclude github-actions[bot] from contributor check (#4923)
Closes #4922 |
||
|
|
743b6bbb0d |
fix: Use Powershell to run just commands on Windows (#4921)
## Linked issue Closes #4920 ## Summary Default to PowerShell 7+ to run just commands on Windows for more consistent argument quoting rules. ## Steps to reproduce (before) - Trigger the release workflow: `just release::build --ref main`. - Inspect the logs of the `prepare` step on GitHub and notice that the version has literal double quotes. ## How to test (after) Repeat the same steps and confirm quotes are not passed literally. |
||
|
|
1822a7c76c |
feat: Bump anki-audio package (#4913)
## Linked issue Closes #4699 ## Summary This bumps `anki-audio` to the newly published 0.2.0 release. ## How to test Confirm audio recording & playback is working by using the record button in the editor. |
||
|
|
60dcc5f3c5 |
fix: Update GitHub environments (#4912)
## Linked issue Closes #4911 ## Summary Update release/publish workflows to use the new environments. |
||
|
|
4702443f31 |
ci: enforce linked issue requirement on PRs (#4910)
## Linked issue Closes #4816 ## Summary / motivation Adds two workflows to enforce the rule that every PR must be linked to an existing issue: - **check-linked-issue**: triggers on PR open/edit, applies the `missing-issue` label and notifies the author if no linked issue is found. Removes the label if the author later links one. - **auto-close-missing-issue**: runs daily and closes any PR that has had the `missing-issue` label for more than 4 days. Hotfixes (title contains `hotfix`) and Dependabot PRs are exempt. ## How to test 1. Open a PR without a linked issue, the `missing-issue` label should be applied and a comment posted. 2. Edit the PR description to add `Closes #<number>`, the label should be removed. 3. Trigger the auto-close workflow manually via Actions → `Auto-close PRs without linked issue` → Run workflow, and verify it closes PRs that have had the label for over 4 days. |
||
|
|
e5ea3fb40a |
feat: Allow MSI installer downgrades (#4909)
## Linked issue
Closes #4908
## Summary / motivation
Update the Wix template to allow users to install older versions of the
app, overwriting an existing newer version. See changes in the template:
|
||
|
|
5e46fc4494 |
fix: Validate add-on's zip entries (#4901)
This validates add-on's zip paths to skip things such as UNC paths |
||
|
|
56d93bb3da |
fix: Parameterize inputs of prop:cd* queries (#4905)
It was possible to construct invalid SQLite queries for browser searches in some cases, for example by searching for `prop:cds:foo=';`. |
||
|
|
9c72a8b828 |
feat: render sync server messages as rich text (#4560)
## Summary
- Pass `type="rich"` to `showText()` when displaying the sync server
message, enabling HTML rendering via `QTextBrowser.setHtml()`
- Plain-text messages continue to render identically — `setHtml()`
handles plain strings the same as `setPlainText()`
- Allows self-hosted sync servers to send formatted post-sync messages
(e.g. styled statistics, notices with links, tables)
## Context
The `/sync/meta` response includes a `msg` field that is displayed to
the user after sync. The display widget is already a `QTextBrowser`
(which supports Qt rich text/HTML), but `showText()` is called with the
default `type="text"`, routing through `setPlainText()`.
The `showText` helper already has full HTML support — it just needs
`type="rich"`:
```python
# qt/aqt/utils.py
text = QTextBrowser()
text.setOpenExternalLinks(True)
if type == "text":
text.setPlainText(txt) # current path
else:
text.setHtml(txt) # proposed path
```
**Security:** `QTextBrowser` does not execute JavaScript — only static
HTML/CSS. The sync server is explicitly configured and trusted by the
user.
|
||
|
|
5d1266eb8e |
fix: Strip HTML from note type names in Empty Cards (#4902)
Strip HTML from note type and template names in the Empty Cards screen. ## How to test ``` cargo test -p anki --lib notetype::emptycards ``` --------- Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com> |
||
|
|
6f332d3a6b |
refactor: import some modules lazily (#4831)
## Linked issue A slight improvement related to #4314 ## Summary Import some modules like `jsonschema`, `bs4` and `aqt.mediasrv` lazily to speed up startup a bit. ## Steps to reproduce Run Anki with `-X importtime` passed to Python: ```diff diff --git a/run b/run index 3051345b1..a907b2925 100755 --- a/run +++ b/run @@ -17,4 +17,4 @@ export ANKI_API_PORT=${ANKI_API_PORT-40000} export ANKI_API_HOST=${ANKI_API_HOST-127.0.0.1} ./ninja pylib qt -${PYENV}/bin/python tools/run.py $* +${PYENV}/bin/python -X importtime tools/run.py 2> importtime.txt $* diff --git a/run.bat b/run.bat index aecbf2491..69a721641 100755 --- a/run.bat +++ b/run.bat @@ -12,5 +12,5 @@ set ANKI_API_HOST=127.0.0.1 @if not defined PYENV set PYENV=out\pyenv call tools\ninja pylib qt || exit /b 1 -%PYENV%\Scripts\python tools\run.py %* || exit /b 1 +%PYENV%\Scripts\python -X importtime tools\run.py %* 2> importtime.txt || exit /b 1 popd ``` Then import `importtime.txt` to [https://github.com/kmichel/python-importtime-graph](https://github.com/kmichel/python-importtime-graph) to visualize timings. You should see `jsonschema` and `bs4` are loaded at startup. ## How to test Run profiling again and confirm `jsonschema` and `bs4` are not loaded at startup. `aqt.mediasrv` will still be loaded at startup (because it's immediately used in the main screen) but at a later stage. --------- Co-authored-by: user1823 <92206575+user1823@users.noreply.github.com> |
||
|
|
88ef75f363 |
fix: Limit taskbar pinning fix to launcher builds (#4849)
This just limits the fix added in
|
||
|
|
6d42e37b72 |
fix: app unresponsive after clicking on Help button in modal dialogs (#4897)
## Linked issue Closes #4896 ## Summary On macOS, clicking the Help button in error dialogs shown on top of modal dialogs such as the Filtered deck screen was causing the app to become unresponsive after the recent Qt upgrade. This was fixed by: 1. Setting a parent widget for `QMessageBox`. 2. Limiting the `.disconnect()` calls to the `clicked` signal. ## Steps to reproduce (before) I was not able to reproduce the issue in a dev environment. I had to build and run the Briefcase package. Follow the steps in the [forums](https://forums.ankiweb.net/t/anki-26-05-beta-1/69707/43?u=abdo) and confirm you can reproduce the issue. ## How to test (after) Run the Briefcase package with the changes and follow reproduction steps and confirm the issue is fixed. |
||
|
|
892aa9c7a9 |
fix: Avoid broad warnings filter (#4900)
This replaces a broad `warnings.filterwarnings("ignore")` call triggered
when `ANKI_NOVERIFYSSL` is set.
|
||
|
|
e05a7aace7 |
feat: Install required system dependencies in install.sh (#4895)
## Linked issue Closes #4834 ## Summary This installs required Linux system dependencies in the install.sh script for Debian-based distributions. ## Steps to reproduce (before) No system dependencies are installed automatically. Users have to refer to the [manual](https://docs.ankiweb.net/platform/linux/installing.html#requirements) to find a (partial) list of required packages. ## How to test (after) Build the installer and run install.sh in any supported distro and confirm dependencies are installed. |
||
|
|
3f6378aee7 |
ci(coverage): fail PR if line coverage regresses (#4876)
## Linked issue Closes #4874 ## Summary / motivation Adds `tools/coverage/check-coverage-regression.py` to compare line coverage percentages from the current PR against the baseline saved from main (introduced in #4875). If any stack regresses beyond the configured tolerance (0.10%), the CI fails with a clear message showing the delta. Stacks checked: Rust, python-pylib, python-qt, TypeScript. ## How to test Try to add some new code without any tests. The Ci must fail. ## Before / after behavior Before: no signal when a PR reduces coverage below the current main level. After: CI fails on `Check coverage regression` with output like: ``` [rust] REGRESSION: 62.64% -> 61.00% (delta: -1.64%, tolerance: 0.10%) 1 stack(s) with coverage regression: rust ``` |
||
|
|
e9830169b7 |
feat(check-media): case-insensitively dedupe media filenames (#4852)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) - #4433 - #4716 ## Summary / motivation (required) This PR modifies `Check Media` to dedupe filenames case-insensitively so as to avoid files that were added on case-sensitive filesystems potentially being overwritten on case-insensitive ones ## Steps to reproduce (required, use N/A if not applicable) N/A ## How to test (required) Given a.jpg (hash 1), A.JPG (hash 2) and a.JPG (hash 1) as existing media files on a case-sensitive fs, see that `Check Media` renames A.JPG to a-2.jpg and a.JPG to a.jpg ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
57e67f8408 |
fix(check-media): case-sensitivity in unused/missing check (#4861)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) - #4716 ## Summary / motivation (required) Currently, on filesystems where the media folder is treated as case-insensitive, `[sound:BLAH.mp3]` and `[sound:blah.mp3]` point to the same file on disk (if any), but one of the two would be considered as a ref pointing to a missing file by the media checker which assumes case-sensitivity ## Steps to reproduce (required, use N/A if not applicable) See linked pr ## How to test (required) On windows/macos, add `blah.mp3`, rename `blah.mp3` to `Blah.mp3` in the ref, run `Check Media` and see that `Blah.mp3` isn't considered missing ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
e13092ef74 |
Replace print() logging in pylib with Python logging (#4666)
Use Python logging facilities instead of printing directly to stdout with print(). This prevents library consumers from being spammed with unwanted debug logs and stack traces. Closes #4665 --- My approach to the log levels is `warning` for any deprecation warning and `debug` for the "blocked main thread" messages. The pylib is used in the qt parts of the anki code. To the best of my understanding, logging is already correctly set up there and no adjustments are needed. The [issue I created](https://github.com/ankitects/anki/issues/4665) for this has a reproducer. With this change applied, the messages are gone when configuring the anki logger accordingly. ```python3 from anki.collection import Collection import logging logging.basicConfig(level=logging.DEBUG) logging.getLogger("anki").setLevel(logging.INFO) col = Collection("collection.anki2") auth = col.sync_login( username=r"<username>", password=r"<password>", endpoint="https://sync.ankiweb.net/", ) col.close() ``` setting the anki logger back to `DEBUG` makes the message appear again. Note that the format is only slightly different then previously. ```txt DEBUG:anki._backend:blocked main thread for 309ms Stack (most recent call last): File "/home/david/coding_stuff/anki/repro.py", line 8, in <module> auth = col.sync_login( File "/home/david/coding_stuff/anki/.venv/lib/python3.14/site-packages/anki/collection.py", line 1141, in sync_login return self._backend.sync_login( File "/home/david/coding_stuff/anki/.venv/lib/python3.14/site-packages/anki/_backend_generated.py", line 83, in sync_login raw_bytes = self._run_command(1, 3, message.SerializeToString()) File "/home/david/coding_stuff/anki/.venv/lib/python3.14/site-packages/anki/_backend.py", line 168, in _run_command logger.debug( ``` |
||
|
|
a754a9c847 |
feat: Bundle Fcitx plugin (#4886)
## Linked issue Closes #4873 ## Summary Build and package the fcitx5-qt6 plugin. Latest release CI run: https://github.com/ankitects/anki/actions/runs/26294296416 ## How to test 1. Run installer build on Linux: `./ninja installer:build`. 2. Go to the Qt build directory (`out/installer/build/anki/linux/zip/anki/app_packages/PyQt6/Qt6`) and confirm you see the following files: 1. `plugins/platforminputcontexts/libfcitx5platforminputcontextplugin.so` 2. `plugins/dbusaddons/libFcitx5Qt6DBusAddons.so*` |
||
|
|
3ca006dd47 |
chore(CI): cache coverage baseline from main for regression checks (#4875)
## Linked issue Refs #4874 ## Summary / motivation Stores the coverage results from every push to `main` in a GitHub Actions cache (`coverage-baseline-linux-{sha}`). This is the foundation for a follow-up PR that will compare PR coverage against this baseline and fail if any stack regresses. No behavior change for PRs yet — the baseline is only saved, not used. ## Before / after behavior Before: no coverage data persisted between CI runs. After: each push to `main` saves `out/coverage/` as a cache entry, keyed by commit SHA, retrievable by prefix `coverage-baseline-linux-`. |
||
|
|
a140d39329 |
chore(e2e): add Playwright end-to-end test infrastructure (#4864)
## Linked issue Closes #4863 ## Summary / motivation Adds Playwright as the e2e test framework so contributors can write browser-based tests against a real headless Anki instance. There was no automated way to exercise mediasrv pages, SvelteKit routes, or the `/_anki/` RPC surface from a browser, this PR establishes that harness. Key pieces: - `qt/tests/launch_anki_for_e2e.py` — spawns a throwaway Anki instance (temp `ANKI_BASE`, `QT_QPA_PLATFORM=offscreen`). Pre-seeds `prefs21.db` so Anki skips the language picker and profile chooser and goes straight to serving mediasrv. - `playwright.config.ts` — points `webServer` at the launcher; polls `/favicon.ico` as the readiness probe. - `ts/tests/e2e/` — `fixtures.ts` base and a sanity spec that verifies mediasrv is reachable and a SvelteKit page hydrates. - `justfile` — `just test-e2e` recipe; Chromium installed to `out/playwright-browsers/`. - CI — e2e step in `check-linux`; failed-run artifacts uploaded for 7 days. - `docs/e2e-testing.md` — contributor guide covering setup, managed vs reuse-server modes, and writing new tests. ## How to test Build the project once, then run the e2e suite in managed mode (no separate `./run` needed — the launcher is started automatically): ```shell just build just test-e2e ``` ## Before / after behavior (optional) Before: no browser-level test harness existed. After: `just test-e2e` drives a real headless Anki instance via Playwright. ## Risk / compatibility / migration No production code changed. New dev-only files and CI step only. Chromium is installed to `out/playwright-browsers/` (gitignored) and does not affect the regular build. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
1394540217 |
test: Add tests for build_installer.py (#4868)
## Linked issue Closes #4859 ## Summary Add tests for the build_installer.py script with 100% coverage. ## How to test Run `just test-py --coverage --html` and browse coverage data. |
||
|
|
0519275682 |
fix: border color of browser cells in macOS (#4872)
## Linked issue Closes #4870 ## Summary This fixes the border color of browser cells in macOS not following Anki's theme after Qt 6.10+ ## Steps to reproduce (before) 1. Set Anki's theme from _Anki (`python` in dev environment) > Preferences > Theme_ to be the opposite of your system theme. 2. Open the Browse screen and notice the cell borders have the opposite color of your Anki theme, matching the system theme. ## How to test (after) Notice cell borders are more subtle now. ### Details ## UI evidence Before: <img width="628" height="346" alt="image" src="https://github.com/user-attachments/assets/3b46c9fe-5eb8-4e03-ac93-5429d1768344" /> After: <img width="628" height="346" alt="image" src="https://github.com/user-attachments/assets/aeea6867-ebfe-46cc-8b4a-6f7440da16f4" /> |
||
|
|
c1b824258e |
feat: add test coverage docs (#4844)
## Linked issue Refs #4838 #4839 #4840 ## Summary / motivation Adds a contributor-facing guide for the test coverage setup introduced across the three coverage PRs, and updates CLAUDE.md to reflect that `just` is now the single entry point for all build, test, lint, and format commands. ## How to test - Read `docs/testing-coverage.md` — verify it covers all three stacks, thresholds, and the known gaps section. - Run `just docs` and open `out/docs/html/index.html` to confirm `testing-coverage` appears in the sidebar under Contributing. - Read `CLAUDE.md` — verify `./ninja` / `./tools` references are gone and `just test-rust`, `just test-py`, `just test-ts` are mentioned. ### Details - `docs/testing-coverage.md`: documents tools, thresholds, per-stack entry points, and known gaps for all three coverage stacks. - `docs/index.md`: wired `testing-coverage` into the Sphinx toctree after `contributing`. - `CLAUDE.md`: replaced raw `./ninja` / `./tools` invocations with `just` equivalents; added top-level note directing contributors to `just --list`; added `just test-rust`, `just test-py`, `just test-ts` to the Quick iteration section. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
bb13a2bb69 |
fix: Avoid loading unused cacert.pem (#4858)
## Linked issue See https://github.com/ankitects/anki/issues/4314#issuecomment-3289709713 ## Summary We got reports that certifi's cacert.pem generates a lot of IO events at startup. This file is no longer directly used by Anki, as we use truststore to force libraries such as requests to use system stores, but it's apparently being loaded by requests in any case. ## How to test Run tests: `./ninja check:pytest` |
||
|
|
dfbd7d2399 |
fix(import): force lowercasing before adding hash suffix as well (#4860)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) - #4851 ## Summary / motivation (required) I made a mistake in #4851 by not lowercasing in the case where a file with the same name but different contents already exists, leading to inconsistent behaviour across platforms ## Steps to reproduce (required, use N/A if not applicable) See linked pr ## How to test (required) Run ./check on linux and windows and see that the same lowercasing behaviour occurs on both ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
3479499569 |
fix(import): avoid case-folding already existing media filenames (#4851)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) Fixes #4716 ## Summary / motivation (required) #4435 made it so that all new added media would have lowercased names, but this was bugged and led to media refs pointing to inexistent files on case-insensitive filesystems The fix proposed is to try adding new files with lowercased names only if they don't already exist, using the existing file otherwise ## Steps to reproduce (required, use N/A if not applicable) See linked issue ## How to test (required) Try copy-pasting a media file from the Edit window of an existing note to the Add window and see that the filename in the resulting media ref isn't forced to be lowercased When pasting a new file, see that the filename is now lowercased ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
f9a5b36c82 |
feat: add TS test coverage (#4843)
## Linked issue Closes #4840 ## Summary / motivation Adds Vitest V8 coverage for TypeScript/Svelte tests via `@vitest/coverage-v8`. Introduces `just test-ts --coverage` and `just test-ts --coverage --html`, and wires TypeScript into the `just test --coverage` umbrella — completing coverage support across all three stacks (Python, Rust, TypeScript). The threshold is set to 5% — intentionally low because the Vitest test count is small relative to the TypeScript/Svelte source surface. It is meant to be raised as more tests are added. ## How to test ```sh # Existing behavior unchanged just test-ts # Terminal summary + enforces 5% line coverage threshold just test-ts --coverage # Terminal summary + HTML report under out/coverage/typescript/ just test-ts --coverage --html # Full umbrella — all three stacks just test --coverage just test --coverage --html ``` ### Checklist - [x] I ran `./ninja check` or an equivalent relevant check locally. ### Details - `@vitest/coverage-v8` pinned at `3.2.4` in `package.json`. - Reports are written to `out/coverage/typescript/` via `--coverage.reportsDirectory=../out/coverage/typescript` (relative to the `ts/` working directory where vitest runs). - V8 provider is preferred over Istanbul: faster and requires no Babel transform for TypeScript projects. - Coverage measures only code reachable through Vitest's module graph — Svelte component rendering is not covered. - The `yarn` justfile variable is added for platform-aware yarn invocation (Windows vs Unix). ## Before / after behavior Before: no `just test-ts`, no TypeScript coverage. After: `just test-ts` runs Vitest via ninja; `just test-ts --coverage` runs with V8 instrumentation. `just test --coverage` now spans all three stacks. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
c9cd85dd97 |
feat: Distribute compiled sources in Briefcase bundle (#4856)
## Linked issue #4855 ## Summary Compile .pyc files and package them in the Briefcase bundle instead of the .py sources. ## How to test You can run this Powershell script to do a basic benchmark of startup performance on Windows (Requires [py-spy](https://github.com/benfred/py-spy)): ```powershell function Remove-Build { Remove-Item -LiteralPath "./out/installer" -Force -Recurse } function Start-Anki { param ( [Parameter()] [string] $OutputPath ) Start-Process -FilePath "py-spy" -ArgumentList "record --output $OutputPath -- ./out/installer/build/anki/windows/app/src/Anki.exe --safemode" Start-Sleep -Seconds 10 Stop-Process -Name Anki } if ($null -eq (Get-Command "py-spy" -ErrorAction SilentlyContinue)) { Write-Error "py-spy not found. See https://github.com/benfred/py-spy" Exit 1 } git checkout main Remove-Build ./tools/ninja installer:build Start-Anki -OutputPath "main.svg" git checkout briefcase-compile-pyc Remove-Build ./tools/ninja installer:build Start-Anki -OutputPath "pyc.svg" ``` Output is written to `main.svg` and `pyc.svg`. Here's an example run (using default 100 sampling rate): <img width="950" height="559" alt="image" src="https://github.com/user-attachments/assets/5da6a06a-3393-4f0e-80fe-ced735d50c2c" /> <img width="830" height="352" alt="image" src="https://github.com/user-attachments/assets/ca9e5d8d-c3d4-4a0b-bd86-7aa2d6c5cee2" /> |
||
|
|
f76fcec48f |
feat: add Rust test coverage (#4842)
## Linked issue Closes #4839 ## Summary / motivation Adds `cargo-llvm-cov`-based test coverage for the full Rust workspace. Introduces `just test-rust --coverage` and `just test-rust --coverage --html`, and wires Rust into the `just test --coverage` umbrella. `cargo-llvm-cov` is installed on demand into `out/bin/` to avoid polluting the global cargo install. The `llvm-tools-preview` rustup component is now installed in CI so the tool can instrument binaries. ## How to test (required) ```sh # Existing behavior unchanged just test-rust # Terminal summary just test-rust --coverage # Terminal summary + HTML report under out/coverage/rust/html/ just test-rust --coverage --html # Umbrella (Rust + Python) just test --coverage just test --coverage --html ``` Note: first run of `--coverage` will install `cargo-llvm-cov` into `out/bin/` (~30s). Subsequent runs skip the install step. ### Checklist - [x] I ran `./ninja check` or an equivalent relevant check locally. ### Details - `cargo-llvm-cov` pinned at `0.8.4`, installed into `out/bin/` via `cargo install --root out`. - `--workspace --locked` measures all crates and respects the lockfile. - `llvm-tools-preview` added to `setup-anki` action so CI can instrument Rust binaries. - Coverage runs are slower than plain `just test-rust` because `cargo-llvm-cov` rebuilds with instrumentation — this is expected. ## Before / after behavior Before: no `just test-rust`, no Rust coverage support. After: `just test-rust` runs Rust tests via ninja; `just test-rust --coverage` runs them with `cargo-llvm-cov` --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
03b9fc4814 |
ci: Fix Windows ARM packaging failing (#4857)
Fixes a CI failure introduced in #4822 See failing run: https://github.com/ankitects/anki/actions/runs/26009152225/job/76447663427 |
||
|
|
82eeda9d4f |
fix(export): preserve browser focus after note export (#4845)
## Linked issue (required) Fixes #4833 ## Summary / motivation (required) Keep the Browser window focused after exporting selected notes. The export dialog was opened from the Browser, but the background export progress and completion tooltip were still parented to the main window. That could leave the main screen focused after the export completed. This change carries the dialog parent through the export options and uses it for progress, errors, and the completion tooltip. ## Steps to reproduce (required, use N/A if not applicable) 1. Open the Browser. 2. Right-click a note and choose Notes > Export Notes. 3. Click Export, choose a save location, and save. 4. Observe that the main screen receives focus after export completion. ## How to test (required) ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details - Ran `./ninja check` successfully. - Tested behavior on macOS, however I currently don't have a Windows or Linux environment set up to test on right now as I'm on vacation. The change is limited to dialog parenting, so I expect it to work the same across platforms. Would appreciate testing on other platforms if possible. ## Before / after behavior (optional) Before: exporting selected notes from the Browser could focus the main window after completion. After: export progress and completion UI remain parented to the Browser, so focus is returned to the Browser. ## Risk / compatibility / migration (optional) Low risk. The change is limited to export UI parenting and falls back to the main window when no dialog parent is available. ## UI evidence (required for visual changes; otherwise N/A) N/A ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
4b01f78aa3 |
fix: Prevent Windows elevation errors when running ninja_gen's update binaries (#4848)
## Linked issue Closes #4847 ## Summary Prevent Windows elevation errors when running ninja_gen's update binaries by embedding a manifest with `asInvoker`. ## How to test Run `./tools/ninja check` or `cargo run --bin update_node` and confirm no elevation errors. |
||
|
|
2ea8e5731a |
feat: add Python test coverage (#4841)
## Linked issue Closes #4838 ## Summary/motivation Adds `coverage.py`-based test coverage for both Python test suites (`pylib` and `qt`). Introduces `just test-py --coverage` and `just test-py --coverage --html`, plus the `just test --coverage`. Coverage reports are written to `out/coverage/`. ## How to test ```sh # Existing behavior unchanged just test-py # Terminal summary + enforces thresholds just test-py --coverage # Terminal summary + HTML reports under out/coverage/ just test-py --coverage --html # Umbrella (Python only for now) just test --coverage just test --coverage --html ``` ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. ### Details - `coverage` dependency pinned to >=7.13.5 in pyproject.toml. - The `coverage` umbrella recipe currently delegates to Python only for now ## Before / after behavior Before: no `just test-py`, no coverage support. After: `just test-py` runs Python tests via ninja; `just test-py --coverage` runs them with `coverage.py` and enforces minimum line coverage. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
1482fb0937 |
fix: atomic_rename now works with single component relative paths (#4773)
## Linked issue (required) [[<!-- Fixes #123 / Closes #123 / Refs #123 -->](https://forums.ankiweb.net/t/anki-collection-collection-export-anki-package-crashes-if-given-a-relative-path-with-one-component/69562)](https://forums.ankiweb.net/t/anki-collection-collection-export-anki-package-crashes-if-given-a-relative-path-with-one-component/69562) ## Summary / motivation (required) See discussion about this on [the forum](https://forums.ankiweb.net/t/anki-collection-collection-export-anki-package-crashes-if-given-a-relative-path-with-one-component/69562) ## Steps to reproduce (required, use N/A if not applicable) `demo.py`: ```python import tempfile from pathlib import Path import anki.collection with tempfile.TemporaryDirectory() as tempdir: tempdir = Path(tempdir) col = anki.collection.Collection(str(tempdir / "temp.anki2")) col.export_anki_package( out_path="output.apkg", options=anki.collection.ExportAnkiPackageOptions(), limit=None, ) ``` ```console $ python demo.py Traceback (most recent call last): [... some noise elided here ...] File "/nix/store/1w7swjzmjp7171yspih1q07a9vgacjzb-dev-env/lib/python3.14/site-packages/anki/_backend_generated.py", line 2037, in export_anki_package raw_bytes = self._run_command(37, 4, message.SerializeToString()) File "/nix/store/1w7swjzmjp7171yspih1q07a9vgacjzb-dev-env/lib/python3.14/site-packages/anki/_backend.py", line 171, in _run_command raise backend_exception_to_pylib(err) anki.errors.BackendIOError: Failed to open '': No such file or directory (os error 2) ``` ## How to test (required) I added a unit test. It passes. ### Checklist (minimum) - [ ] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> ## Before / after behavior (optional) <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <!-- Screenshot or short video --> ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
a2262809c4 |
fix: regex error fix (#4837)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) Fixes #4835 ## Summary / motivation (required) <!-- What this PR does and why. For larger changes, add enough context for reviewers. --> Fixes the issue #4835 with a minor change in InvalidRegex error. ## Steps to reproduce (required, use N/A if not applicable) <!-- Steps to reproduce: how to trigger the bug in the broken state (the "before"). - Mainly for bugfixes; - For bugs: numbered steps before the fix. For non-bugs: write N/A. - use N/A for features, refactors, docs, chore, etc. --> 1. Open the browser and do a find & replace. 2. Put b[ in “Find”. 3. Enable the regex option. 4. Confirm. ## How to test (required) <!--- How to test: how you verified the change (checks, unit tests, manual steps, edge cases — the "after" or general validation). ---> Reproduce the fix and verify the regex error is not within the `<pre>` tag. ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details Regex error was return with `<pre>` tags which are removed now so that the text in the error box is displayed correctly. ## Before / after behavior (optional) <img width="372" height="211" alt="image" src="https://github.com/user-attachments/assets/91f53745-301b-4679-b1a5-53fafd628de7" /> <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <img width="360" height="226" alt="image" src="https://github.com/user-attachments/assets/3b7b3f23-9f35-423e-9b10-62834e0a0dd6" /> <!-- Screenshot or short video --> ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
cc1605aab3 |
fix: beta/rc suffix handling in int_version() (#4828)
## Linked issue #4827 ## Summary Strip beta/rc numbers from the version before conversion so they map to the same number as the stable version. ## Steps to reproduce See the linked issue ## How to test Run Python tests: `./ninja check:pytest` |
||
|
|
1f0fc05f93 |
chore(deps): bump the python-minor-patch group across 1 directory with 16 updates (#4829)
Bumps the python-minor-patch group with 16 updates in the / directory: | Package | From | To | | --- | --- | --- | | [pre-commit](https://github.com/pre-commit/pre-commit) | `4.5.1` | `4.6.0` | | [mypy](https://github.com/python/mypy) | `1.16.1` | `1.17.1` | | [ruff](https://github.com/astral-sh/ruff) | `0.12.1` | `0.13.3` | | [wheel](https://github.com/pypa/wheel) | `0.46.3` | `0.47.0` | | [hatchling](https://github.com/pypa/hatch) | `1.27.0` | `1.29.0` | | [types-requests](https://github.com/python/typeshed) | `2.32.4.20250611` | `2.33.0.20260503` | | [types-markdown](https://github.com/python/typeshed) | `3.8.0.20250415` | `3.10.2.20260408` | | [sphinx-book-theme](https://github.com/executablebooks/sphinx-book-theme) | `1.1.4` | `1.2.0` | | [sphinx-autoapi](https://github.com/readthedocs/sphinx-autoapi) | `3.6.0` | `3.8.0` | | [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid) | `2.0.1` | `2.0.2` | | [markdown](https://github.com/Python-Markdown/markdown) | `3.8.2` | `3.10.2` | | [orjson](https://github.com/ijl/orjson) | `3.10.18` | `3.11.8` | | [typing-extensions](https://github.com/python/typing_extensions) | `4.14.0` | `4.15.0` | | [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) | `4.13.4` | `4.14.3` | | [flask-cors](https://github.com/corydolphin/flask-cors) | `6.0.1` | `6.0.2` | | [jsonschema](https://github.com/python-jsonschema/jsonschema) | `4.24.0` | `4.26.0` | Updates `pre-commit` from 4.5.1 to 4.6.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/pre-commit/pre-commit/releases">pre-commit's releases</a>.</em></p> <blockquote> <h2>pre-commit v4.6.0</h2> <h3>Features</h3> <ul> <li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to be missing to enable easier usage with <code>git</code> 2.54+ git hooks. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> <h3>Fixes</h3> <ul> <li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is required. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md">pre-commit's changelog</a>.</em></p> <blockquote> <h1>4.6.0 - 2026-04-21</h1> <h3>Features</h3> <ul> <li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to be missing to enable easier usage with <code>git</code> 2.54+ git hooks. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> <h3>Fixes</h3> <ul> <li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is required. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
81abe9e0ad |
chore(deps): bump pip from 26.0.1 to 26.1 (#4783)
Bumps [pip](https://github.com/pypa/pip) from 26.0.1 to 26.1. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pypa/pip/blob/main/NEWS.rst">pip's changelog</a>.</em></p> <blockquote> <h1>26.1 (2026-04-26)</h1> <h2>Deprecations and Removals</h2> <ul> <li>Drop support for Python 3.9. (<code>[#13795](https://github.com/pypa/pip/issues/13795) <https://github.com/pypa/pip/issues/13795></code>_)</li> </ul> <h2>Features</h2> <ul> <li>Add experimental support to read requirements from standardized pylock.toml files (<code>-r pylock.toml</code>). (<code>[#13876](https://github.com/pypa/pip/issues/13876) <https://github.com/pypa/pip/issues/13876></code>_)</li> <li>Allow <code>--uploaded-prior-to</code> to accept a duration in days (e.g., <code>P3D</code> for 3 days ago). (<code>[#13674](https://github.com/pypa/pip/issues/13674) <https://github.com/pypa/pip/issues/13674></code>_)</li> </ul> <h2>Enhancements</h2> <ul> <li>Speed up dependency resolution when there are complex conflicts. (<code>[#13859](https://github.com/pypa/pip/issues/13859) <https://github.com/pypa/pip/issues/13859></code>_)</li> <li>Reduce memory usage when resolving large dependency trees. (<code>[#13843](https://github.com/pypa/pip/issues/13843) <https://github.com/pypa/pip/issues/13843></code>_)</li> <li>Emit a deprecation warning when pip imports an unexpected module after installation of a distribution has started. (<code>[#13912](https://github.com/pypa/pip/issues/13912) <https://github.com/pypa/pip/issues/13912></code>_)</li> <li>Allow URL constraints to apply to requirements with extras. (<code>[#12018](https://github.com/pypa/pip/issues/12018) <https://github.com/pypa/pip/issues/12018></code>_)</li> <li>Allow unpinned requirements to use hashes from constraints. Constraints like <code>{name}=={version} --hash=...</code> feeds into hash verification for a corresponding requirement. (<code>[#9243](https://github.com/pypa/pip/issues/9243) <https://github.com/pypa/pip/issues/9243></code>_)</li> <li>Improve conflict reports that involve direct URLs. (<code>[#13932](https://github.com/pypa/pip/issues/13932) <https://github.com/pypa/pip/issues/13932></code>_)</li> <li>Show all errors instead of first error for faulty <code>dependency_groups</code> definitions. (<code>[#13917](https://github.com/pypa/pip/issues/13917) <https://github.com/pypa/pip/issues/13917></code>_)</li> </ul> <h2>Bug Fixes</h2> <ul> <li>Fix recovery hint for missing RECORD file to use <code>--ignore-installed</code> instead of <code>--force-reinstall</code>. (<code>[#12645](https://github.com/pypa/pip/issues/12645) <https://github.com/pypa/pip/issues/12645></code>_)</li> <li>Fix misleading error message when a constraint file cannot be opened. (<code>[#13226](https://github.com/pypa/pip/issues/13226) <https://github.com/pypa/pip/issues/13226></code>_)</li> <li>Show the filename rather than the full URL when downloading files from non-PyPI indexes in non-verbose mode. (<code>[#13494](https://github.com/pypa/pip/issues/13494) <https://github.com/pypa/pip/issues/13494></code>_)</li> <li>Remove the adjacent <code>__pycache__</code> directory when a .py file is removed. (<code>[#13725](https://github.com/pypa/pip/issues/13725) <https://github.com/pypa/pip/issues/13725></code>_)</li> <li>Force UTF-8 encoding for :pep:<code>723</code> metadata. (<code>[#13861](https://github.com/pypa/pip/issues/13861) <https://github.com/pypa/pip/issues/13861></code>_)</li> <li>Minor performance improvement when filtering candidates during resolution. (<code>[#13916](https://github.com/pypa/pip/issues/13916) <https://github.com/pypa/pip/issues/13916></code>_)</li> <li>Fix a hang on Windows when stdout is closed during verbose output. (<code>[#13927](https://github.com/pypa/pip/issues/13927) <https://github.com/pypa/pip/issues/13927></code>_)</li> <li>Common path prefixes are determined by path segment, not character by character. (<code>[#13847](https://github.com/pypa/pip/issues/13847) <https://github.com/pypa/pip/issues/13847></code>_)</li> <li>Fix installing <code>.tar.gz</code> source distributions that look like a zip file. (<code>[#13867](https://github.com/pypa/pip/issues/13867) <https://github.com/pypa/pip/issues/13867></code>_)</li> </ul> <h2>Vendored Libraries</h2> <ul> <li>Upgrade certifi to 2026.2.25</li> <li>Upgrade packaging to 26.2</li> <li>Upgrade requests to 2.33.1</li> <li>Upgrade tomli to 2.3.1</li> <li>Upgrade urllib3 to 2.6.3</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |