You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add diff command for tracking compatibility progress over time
- Add ftready diff subcommand to compare two JSON reports
- Refactor CLI from single command to click group with default 'check' subcommand
- Show improved/regressed/added/removed packages with delta counts
- Support text and JSON output for diffs (--format text|json)
- Export DiffSummary, PackageDiff, diff_reports, format_diff from public API
- Update README: PEP 703 link, pure-Python explanation, --cache-ttl/--cache-file docs,
tracking progress section, Python API examples, limitations section, uv install option
- Add 23 new tests for diff module and CLI subcommand (129 total, 93% coverage)
Python 3.13 shipped a **free-threaded build**(`-t` suffix) that disables the GIL — unlocking true multi-core parallelism. But your project is only as ready as its **least-compatible dependency**.
29
+
[PEP 703](https://peps.python.org/pep-0703/) introduced a **free-threaded build**of CPython (3.13t / 3.14t) that disables the GIL — unlocking true multi-core parallelism. But your project is only as ready as its **least-compatible dependency**. See the [CPython free-threading docs](https://docs.python.org/3.14/whatsnew/3.13.html#free-threaded-cpython) for background.
28
30
29
31
`ftready` scans your dependency tree, queries PyPI for `cp313t`/`cp314t` wheels, cross-references [ft-checker.com](https://ft-checker.com) test results, and tells you exactly where you stand:
30
32
@@ -47,7 +49,7 @@ Python 3.13 shipped a **free-threaded build** (`-t` suffix) that disables the GI
47
49
## ⚡ Quickstart
48
50
49
51
```bash
50
-
pip install ftready
52
+
pip install ftready# or: uv tool install ftready
51
53
ftready
52
54
```
53
55
@@ -60,6 +62,7 @@ That's it. Reads your `pyproject.toml` and prints a compatibility report.
60
62
-**Pure-Python detection** — flags packages with no C extensions as likely compatible
4.**Enrich** — optionally fetches [ft-checker.com](https://ft-checker.com) test results (cached 24h)
127
162
5.**Report** — renders results as a styled table, JSON, or CSV with configurable exit codes
128
163
164
+
> **About "Pure Python":** A package is flagged as 🐍 when *all* its published wheels use the `py3-none-any` tag — meaning no compiled C extensions. These packages typically work on free-threaded Python without changes. However, packages using `ctypes`, `cffi`, or calling native code at runtime may still have issues despite being "pure." Treat this as a strong signal, not a guarantee.
| PyPI JSON API | **Primary** — `cp313t`/`cp314t` wheel tag detection | Every package on PyPI |
245
+
| PyPI version endpoint | **Primary** — pinned-version checking from lock files | Every package on PyPI |
246
+
| [ft-checker.com](https://ft-checker.com) | **Enrichment** — actual test results | ~1000 top packages |
170
247
171
248
When both sources report on a package, ft-checker.com takes priority — a package may ship free-threaded wheels but still fail tests.
172
249
250
+
## ⚠️ Limitations
251
+
252
+
- **Latest release only** (without lock files): When no lock file is used, ftready checks the *latest* PyPI release. If you're pinned to an older version, use `--all-deps` with a lock file for exact version checks.
253
+
- **Wheel tags ≠ runtime compatibility**: A package shipping `cp313t` wheels doesn't guarantee it works correctly under free-threaded Python — it only means the maintainer built wheels for that target. ft-checker.com test results provide stronger evidence.
254
+
- **ft-checker.com coverage**: The enrichment source covers ~1000 popular packages. Niche packages may only have PyPI wheel tag data.
255
+
- **No transitive blocker tracing**: The tool reports status per-package but doesn't show dependency chains (e.g., "X depends on Y which depends on Z, and Z is the blocker").
0 commit comments