diff -pruN 0.6.2-1/.gitignore 0.7.0-1/.gitignore
--- 0.6.2-1/.gitignore	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/.gitignore	2025-08-10 00:19:08.000000000 +0000
@@ -2,6 +2,7 @@
 *.py[cod]
 __pycache__/
 venv/
+.venv/
 .tox/
 .vscode/
 /build/
diff -pruN 0.6.2-1/.pre-commit-config.yaml 0.7.0-1/.pre-commit-config.yaml
--- 0.6.2-1/.pre-commit-config.yaml	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/.pre-commit-config.yaml	2025-08-10 00:19:08.000000000 +0000
@@ -14,13 +14,13 @@ exclude: >
 
 repos:
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: 'v0.0.276'
+    rev: 'v0.9.7'
     hooks:
       - id: ruff
         args: [--fix, --exit-non-zero-on-fix, --show-fixes]
 
   - repo: https://github.com/ambv/black
-    rev: 23.3.0
+    rev: 24.8.0
     hooks:
       - id: black
 
diff -pruN 0.6.2-1/Makefile 0.7.0-1/Makefile
--- 0.6.2-1/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ 0.7.0-1/Makefile	2025-08-10 00:19:08.000000000 +0000
@@ -0,0 +1,55 @@
+checkfiles = src/ tests/
+
+help:
+	@echo  "FindPython development makefile"
+	@echo
+	@echo  "Usage: make <target>"
+	@echo  "Targets:"
+	@echo  "    up      Updates dev/test dependencies"
+	@echo  "    deps    Ensure dev/test dependencies are installed"
+	@echo  "    check   Checks that build is sane"
+	@echo  "    test    Runs all tests"
+	@echo  "    style   Auto-formats the code"
+	@echo  "    lint    Auto-formats the code and check type hints"
+
+up:
+	pdm update --verbose
+
+deps:
+ifeq ($(wildcard .venv),)
+	pdm install --verbose
+else
+	pdm install
+endif
+
+_check:
+	pdm run ruff format --check $(checkfiles)
+	pdm run ruff check $(checkfiles)
+	pdm run mypy $(checkfiles)
+check: deps _build _check
+
+_style:
+	pdm run ruff format $(checkfiles)
+	pdm run ruff check --fix $(checkfiles)
+style: deps _style
+
+_lint:
+	pdm run ruff format $(checkfiles)
+	pdm run ruff check --fix $(checkfiles)
+	pdm run mypy $(checkfiles)
+lint: deps _build _lint
+
+_test:
+	pdm run pytest -s tests
+test: deps _test
+
+_build:
+	rm -fR dist/
+	pdm build
+build: deps _build
+
+# Usage::
+#   make venv version=3.12
+venv:
+	pdm venv create $(version)
+	pdm run pip install --upgrade pip
diff -pruN 0.6.2-1/README.md 0.7.0-1/README.md
--- 0.6.2-1/README.md	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/README.md	2025-08-10 00:19:08.000000000 +0000
@@ -82,6 +82,7 @@ FindPython finds Python from the followi
 -   pyenv install root
 -   asdf python install root
 -   [rye](https://rye-up.com) toolchain install root
+-   [uv](https://docs.astral.sh/uv/) toolchain install root
 -   `/Library/Frameworks/Python.framework/Versions` (MacOS)
 -   Windows registry (Windows only)
 
diff -pruN 0.6.2-1/debian/changelog 0.7.0-1/debian/changelog
--- 0.6.2-1/debian/changelog	2024-11-01 00:36:30.000000000 +0000
+++ 0.7.0-1/debian/changelog	2025-08-10 00:20:22.000000000 +0000
@@ -1,3 +1,9 @@
+findpython (0.7.0-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Boyuan Yang <byang@debian.org>  Sat, 09 Aug 2025 20:20:22 -0400
+
 findpython (0.6.2-1) unstable; urgency=medium
 
   * New upstream release.
diff -pruN 0.6.2-1/debian/control 0.7.0-1/debian/control
--- 0.6.2-1/debian/control	2024-11-01 00:36:30.000000000 +0000
+++ 0.7.0-1/debian/control	2025-08-10 00:20:22.000000000 +0000
@@ -11,8 +11,9 @@ Build-Depends:
  python3,
  python3-packaging,
  python3-pdm-backend,
+ python3-platformdirs (>= 4.3.6),
  python3-pytest <!nocheck>,
-Standards-Version: 4.7.0
+Standards-Version: 4.7.2
 Testsuite: autopkgtest-pkg-pybuild
 Homepage: https://github.com/frostming/findpython
 Vcs-Git: https://salsa.debian.org/python-team/packages/findpython.git
diff -pruN 0.6.2-1/pdm.lock 0.7.0-1/pdm.lock
--- 0.6.2-1/pdm.lock	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/pdm.lock	2025-08-10 00:19:08.000000000 +0000
@@ -3,149 +3,138 @@
 
 [metadata]
 groups = ["default", "tests"]
-strategy = ["cross_platform", "inherit_metadata"]
-lock_version = "4.4.1"
-content_hash = "sha256:6eb2efcbb7606a63e2aac268217a24edd3c8b7d908d0a537d3f896fc525b0a03"
+strategy = ["inherit_metadata"]
+lock_version = "4.5.0"
+content_hash = "sha256:60018977405b138cb5c36085fd2c174a69daac54e96e46d77fe5449078691223"
 
-[[package]]
-name = "attrs"
-version = "22.1.0"
-requires_python = ">=3.5"
-summary = "Classes Without Boilerplate"
-groups = ["tests"]
-files = [
-    {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
-    {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
-]
+[[metadata.targets]]
+requires_python = ">=3.8"
 
 [[package]]
 name = "colorama"
-version = "0.4.5"
-requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+version = "0.4.6"
+requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
 summary = "Cross-platform colored terminal text."
 groups = ["tests"]
 marker = "sys_platform == \"win32\""
 files = [
-    {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
-    {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
 ]
 
 [[package]]
 name = "exceptiongroup"
-version = "1.1.0"
+version = "1.2.2"
 requires_python = ">=3.7"
 summary = "Backport of PEP 654 (exception groups)"
 groups = ["tests"]
 marker = "python_version < \"3.11\""
 files = [
-    {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"},
-    {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"},
+    {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
+    {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
 ]
 
 [[package]]
-name = "importlib-metadata"
-version = "4.12.0"
+name = "iniconfig"
+version = "2.0.0"
 requires_python = ">=3.7"
-summary = "Read metadata from Python packages"
+summary = "brain-dead simple config-ini parsing"
 groups = ["tests"]
-marker = "python_version < \"3.8\""
-dependencies = [
-    "typing-extensions>=3.6.4; python_version < \"3.8\"",
-    "zipp>=0.5",
-]
 files = [
-    {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"},
-    {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"},
+    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
 ]
 
 [[package]]
-name = "iniconfig"
-version = "1.1.1"
-summary = "iniconfig: brain-dead simple config-ini parsing"
-groups = ["tests"]
+name = "packaging"
+version = "24.2"
+requires_python = ">=3.8"
+summary = "Core utilities for Python packages"
+groups = ["default", "tests"]
 files = [
-    {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
-    {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
+    {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
+    {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
 ]
 
 [[package]]
-name = "packaging"
-version = "23.0"
-requires_python = ">=3.7"
-summary = "Core utilities for Python packages"
-groups = ["default", "tests"]
+name = "platformdirs"
+version = "4.3.6"
+requires_python = ">=3.8"
+summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
+groups = ["default"]
 files = [
-    {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
-    {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+    {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
+    {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
 ]
 
 [[package]]
 name = "pluggy"
-version = "1.0.0"
-requires_python = ">=3.6"
+version = "1.5.0"
+requires_python = ">=3.8"
 summary = "plugin and hook calling mechanisms for python"
 groups = ["tests"]
-dependencies = [
-    "importlib-metadata>=0.12; python_version < \"3.8\"",
-]
 files = [
-    {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
-    {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
+    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
 ]
 
 [[package]]
 name = "pytest"
-version = "7.2.1"
-requires_python = ">=3.7"
+version = "8.3.4"
+requires_python = ">=3.8"
 summary = "pytest: simple powerful testing with Python"
 groups = ["tests"]
 dependencies = [
-    "attrs>=19.2.0",
     "colorama; sys_platform == \"win32\"",
     "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"",
-    "importlib-metadata>=0.12; python_version < \"3.8\"",
     "iniconfig",
     "packaging",
-    "pluggy<2.0,>=0.12",
-    "tomli>=1.0.0; python_version < \"3.11\"",
+    "pluggy<2,>=1.5",
+    "tomli>=1; python_version < \"3.11\"",
 ]
 files = [
-    {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"},
-    {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"},
+    {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
+    {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
 ]
 
 [[package]]
 name = "tomli"
-version = "2.0.1"
-requires_python = ">=3.7"
+version = "2.2.1"
+requires_python = ">=3.8"
 summary = "A lil' TOML parser"
 groups = ["tests"]
 marker = "python_version < \"3.11\""
 files = [
-    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
-    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.3.0"
-requires_python = ">=3.7"
-summary = "Backported and Experimental Type Hints for Python 3.7+"
-groups = ["tests"]
-marker = "python_version < \"3.8\""
-files = [
-    {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
-    {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
-]
-
-[[package]]
-name = "zipp"
-version = "3.8.1"
-requires_python = ">=3.7"
-summary = "Backport of pathlib-compatible object wrapper for zip files"
-groups = ["tests"]
-marker = "python_version < \"3.8\""
-files = [
-    {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"},
-    {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+    {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+    {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+    {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+    {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+    {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+    {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+    {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+    {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
 ]
diff -pruN 0.6.2-1/pyproject.toml 0.7.0-1/pyproject.toml
--- 0.6.2-1/pyproject.toml	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/pyproject.toml	2025-08-10 00:19:08.000000000 +0000
@@ -6,6 +6,7 @@ authors = [
 ]
 dependencies = [
     "packaging>=20",
+    "platformdirs>=4.3.6",
 ]
 requires-python = ">=3.8"
 license = {text = "MIT"}
@@ -19,6 +20,7 @@ classifiers = [
     "Programming Language :: Python :: 3.10",
     "Programming Language :: Python :: 3.11",
     "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
 ]
 
 [project.urls]
@@ -38,6 +40,9 @@ package-dir = "src"
 [tool.pdm.dev-dependencies]
 tests = ["pytest"]
 
+[tool.pdm.scripts]
+test = "pytest tests"
+
 [build-system]
 requires = ["pdm-backend"]
 build-backend = "pdm.backend"
@@ -61,6 +66,11 @@ exclude = '''
 
 [tool.ruff]
 line-length = 90
+src = ["src"]
+exclude = ["tests/fixtures"]
+target-version = "py38"
+
+[tool.ruff.lint]
 select = [
   "B",    # flake8-bugbear
   "C4",   # flake8-comprehensions
@@ -72,14 +82,13 @@ select = [
   "YTT",  # flake8-2020
 ]
 extend-ignore = ["B018", "B019"]
-src = ["src"]
-exclude = ["tests/fixtures"]
-target-version = "py37"
 
-[tool.ruff.mccabe]
+[tool.ruff.lint.mccabe]
 max-complexity = 10
 
-[tool.ruff.isort]
+[tool.ruff.lint.isort]
 known-first-party = ["findpython"]
 
-
+[[tool.mypy.overrides]]
+module = "_winreg"
+ignore_missing_imports = true
diff -pruN 0.6.2-1/src/findpython/__init__.py 0.7.0-1/src/findpython/__init__.py
--- 0.6.2-1/src/findpython/__init__.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/__init__.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,8 +1,9 @@
 """
-    FindPython
-    ~~~~~~~~~~
-    A utility to find python versions on your system
+FindPython
+~~~~~~~~~~
+A utility to find python versions on your system
 """
+
 from __future__ import annotations
 
 from typing import TYPE_CHECKING, TypeVar
@@ -59,4 +60,4 @@ def register_provider(provider: P) -> P:
     return provider
 
 
-__all__ = ["Finder", "find", "find_all", "PythonVersion", "register_provider"]
+__all__ = ["Finder", "PythonVersion", "find", "find_all", "register_provider"]
diff -pruN 0.6.2-1/src/findpython/__main__.py 0.7.0-1/src/findpython/__main__.py
--- 0.6.2-1/src/findpython/__main__.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/__main__.py	2025-08-10 00:19:08.000000000 +0000
@@ -37,6 +37,7 @@ def cli(argv: list[str] | None = None) -
     parser.add_argument(
         "-a", "--all", action="store_true", help="Show all matching python versions"
     )
+    parser.add_argument("--path", action="store_true", help="Show the path of the python")
     parser.add_argument(
         "--resolve-symlink", action="store_true", help="Resolve all symlinks"
     )
@@ -79,7 +80,7 @@ def cli(argv: list[str] | None = None) -
         python_versions = [python_versions]
     print("Found matching python versions:", file=sys.stderr)
     for python_version in python_versions:
-        print(python_version)
+        print(python_version.executable if args.path else python_version.display())
     return 0
 
 
diff -pruN 0.6.2-1/src/findpython/finder.py 0.7.0-1/src/findpython/finder.py
--- 0.6.2-1/src/findpython/finder.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/finder.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import dataclasses
 import logging
 import operator
 from typing import Callable, Iterable
@@ -67,6 +68,7 @@ class Finder:
         architecture: str | None = None,
         allow_prereleases: bool = False,
         implementation: str | None = None,
+        freethreaded: bool | None = None,
     ) -> list[PythonVersion]:
         """
         Return all Python versions matching the given version criteria.
@@ -80,6 +82,7 @@ class Finder:
         :param architecture: The architecture of the python.
         :param allow_prereleases: Whether to allow prereleases.
         :param implementation: The implementation of the python. E.g. "cpython", "pypy".
+        :param freethreaded: Whether the python is freethreaded.
         :return: a list of PythonVersion objects
         """
         if allow_prereleases and (pre is False or dev is False):
@@ -104,6 +107,7 @@ class Finder:
                     dev = dev or None
                 architecture = version_dict["architecture"]
                 implementation = version_dict["implementation"]
+                freethreaded = version_dict["freethreaded"]
             else:
                 name, major = major, None
 
@@ -117,6 +121,7 @@ class Finder:
             name,
             architecture,
             implementation,
+            freethreaded,
         )
         # Deduplicate with the python executable path
         matched_python = set(self._find_all_python_versions())
@@ -180,8 +185,6 @@ class Finder:
                 return python_version.interpreter.as_posix()
             if self.no_same_file:
                 return python_version.binary_hash()
-            if self.resolve_symlinks and not python_version.keep_symlink:
-                return python_version.real_path.as_posix()
             return python_version.executable.as_posix()
 
         def sort_key(python_version: PythonVersion) -> tuple[int, int, int]:
@@ -194,6 +197,14 @@ class Finder:
         result: dict[str, PythonVersion] = {}
 
         for python_version in sorted(python_versions, key=sort_key):
+            if (
+                self.resolve_symlinks
+                and not python_version.keep_symlink
+                and python_version.executable.is_symlink()
+            ):
+                python_version = dataclasses.replace(
+                    python_version, executable=python_version.real_path
+                )
             key = dedup_key(python_version)
             if (
                 key not in result
diff -pruN 0.6.2-1/src/findpython/pep514tools/__init__.py 0.7.0-1/src/findpython/pep514tools/__init__.py
--- 0.6.2-1/src/findpython/pep514tools/__init__.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/pep514tools/__init__.py	2025-08-10 00:19:08.000000000 +0000
@@ -10,4 +10,4 @@ __version__ = "0.1.0"
 
 from findpython.pep514tools.environment import find, findall, findone
 
-__all__ = ["findall", "find", "findone"]
+__all__ = ["find", "findall", "findone"]
diff -pruN 0.6.2-1/src/findpython/pep514tools/_registry.py 0.7.0-1/src/findpython/pep514tools/_registry.py
--- 0.6.2-1/src/findpython/pep514tools/_registry.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/pep514tools/_registry.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,3 +1,4 @@
+# mypy: disable-error-code="attr-defined"
 # -------------------------------------------------------------------------
 # Copyright (c) Steve Dower
 # All rights reserved.
@@ -6,10 +7,10 @@
 # -------------------------------------------------------------------------
 
 __all__ = [
-    "open_source",
+    "REGISTRY_SOURCE_CU",
     "REGISTRY_SOURCE_LM",
     "REGISTRY_SOURCE_LM_WOW6432",
-    "REGISTRY_SOURCE_CU",
+    "open_source",
 ]
 
 import re
@@ -18,7 +19,7 @@ from itertools import count
 try:
     import winreg
 except ImportError:
-    import _winreg as winreg
+    import _winreg as winreg  # type:ignore[no-redef]
 
 REGISTRY_SOURCE_LM = 1
 REGISTRY_SOURCE_LM_WOW6432 = 2
diff -pruN 0.6.2-1/src/findpython/pep514tools/environment.py 0.7.0-1/src/findpython/pep514tools/environment.py
--- 0.6.2-1/src/findpython/pep514tools/environment.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/pep514tools/environment.py	2025-08-10 00:19:08.000000000 +0000
@@ -5,7 +5,7 @@
 # Distributed under the terms of the MIT License
 # -------------------------------------------------------------------------
 
-__all__ = ["Environment", "findall", "find", "findone"]
+__all__ = ["Environment", "find", "findall", "findone"]
 
 import sys
 
diff -pruN 0.6.2-1/src/findpython/providers/__init__.py 0.7.0-1/src/findpython/providers/__init__.py
--- 0.6.2-1/src/findpython/providers/__init__.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/__init__.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,6 +1,7 @@
 """
 This package contains all the providers for the pythonfinder module.
 """
+
 from __future__ import annotations
 
 from findpython.providers.asdf import AsdfProvider
@@ -9,6 +10,7 @@ from findpython.providers.macos import M
 from findpython.providers.path import PathProvider
 from findpython.providers.pyenv import PyenvProvider
 from findpython.providers.rye import RyeProvider
+from findpython.providers.uv import UvProvider
 from findpython.providers.winreg import WinregProvider
 
 _providers: list[type[BaseProvider]] = [
@@ -18,6 +20,7 @@ _providers: list[type[BaseProvider]] = [
     AsdfProvider,
     PyenvProvider,
     RyeProvider,
+    UvProvider,
     # Windows only:
     WinregProvider,
     # MacOS only:
diff -pruN 0.6.2-1/src/findpython/providers/asdf.py 0.7.0-1/src/findpython/providers/asdf.py
--- 0.6.2-1/src/findpython/providers/asdf.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/asdf.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,12 +1,21 @@
 from __future__ import annotations
 
 import os
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 class AsdfProvider(BaseProvider):
     """A provider that finds python installed with asdf"""
@@ -15,7 +24,7 @@ class AsdfProvider(BaseProvider):
         self.root = root
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         asdf_root = os.path.expanduser(
             os.path.expandvars(os.getenv("ASDF_DATA_DIR", "~/.asdf"))
         )
@@ -23,7 +32,7 @@ class AsdfProvider(BaseProvider):
             return None
         return cls(Path(asdf_root))
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         python_dir = self.root / "installs/python"
         if not python_dir.exists():
             return
diff -pruN 0.6.2-1/src/findpython/providers/base.py 0.7.0-1/src/findpython/providers/base.py
--- 0.6.2-1/src/findpython/providers/base.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/base.py	2025-08-10 00:19:08.000000000 +0000
@@ -2,19 +2,28 @@ from __future__ import annotations
 
 import abc
 import logging
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.python import PythonVersion
 from findpython.utils import path_is_python, safe_iter_dir
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Callable, Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 logger = logging.getLogger("findpython")
 
 
 class BaseProvider(metaclass=abc.ABCMeta):
     """The base class for python providers"""
 
-    version_maker: t.Callable[..., PythonVersion] = PythonVersion
+    version_maker: Callable[..., PythonVersion] = PythonVersion
 
     @classmethod
     def name(cls) -> str:
@@ -29,19 +38,19 @@ class BaseProvider(metaclass=abc.ABCMeta
 
     @classmethod
     @abc.abstractmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         """Return an instance of the provider or None if it is not available"""
         pass
 
     @abc.abstractmethod
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         """Return the python versions found by the provider"""
         pass
 
     @classmethod
     def find_pythons_from_path(
         cls, path: Path, as_interpreter: bool = False
-    ) -> t.Iterable[PythonVersion]:
+    ) -> Iterable[PythonVersion]:
         """A general helper method to return pythons under a given path.
 
         :param path: The path to search for pythons
diff -pruN 0.6.2-1/src/findpython/providers/macos.py 0.7.0-1/src/findpython/providers/macos.py
--- 0.6.2-1/src/findpython/providers/macos.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/macos.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,11 +1,20 @@
 from __future__ import annotations
 
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 class MacOSProvider(BaseProvider):
     """A provider that finds python from macos typical install base
@@ -15,12 +24,12 @@ class MacOSProvider(BaseProvider):
     INSTALL_BASE = Path("/Library/Frameworks/Python.framework/Versions/")
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         if not cls.INSTALL_BASE.exists():
             return None
         return cls()
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         for version in self.INSTALL_BASE.iterdir():
             if version.is_dir():
                 yield from self.find_pythons_from_path(version / "bin", True)
diff -pruN 0.6.2-1/src/findpython/providers/path.py 0.7.0-1/src/findpython/providers/path.py
--- 0.6.2-1/src/findpython/providers/path.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/path.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,13 +1,22 @@
 from __future__ import annotations
 
 import os
-import typing as t
 from dataclasses import dataclass
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 @dataclass
 class PathProvider(BaseProvider):
@@ -16,10 +25,10 @@ class PathProvider(BaseProvider):
     paths: list[Path]
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         paths = [Path(path) for path in os.getenv("PATH", "").split(os.pathsep) if path]
         return cls(paths)
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         for path in self.paths:
             yield from self.find_pythons_from_path(path)
diff -pruN 0.6.2-1/src/findpython/providers/pyenv.py 0.7.0-1/src/findpython/providers/pyenv.py
--- 0.6.2-1/src/findpython/providers/pyenv.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/pyenv.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,12 +1,21 @@
 from __future__ import annotations
 
 import os
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 class PyenvProvider(BaseProvider):
     """A provider that finds python installed with pyenv"""
@@ -15,7 +24,7 @@ class PyenvProvider(BaseProvider):
         self.root = root
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         pyenv_root = os.path.expanduser(
             os.path.expandvars(os.getenv("PYENV_ROOT", "~/.pyenv"))
         )
@@ -23,7 +32,7 @@ class PyenvProvider(BaseProvider):
             return None
         return cls(Path(pyenv_root))
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         versions_path = self.root.joinpath("versions")
         if versions_path.exists():
             for version in versions_path.iterdir():
diff -pruN 0.6.2-1/src/findpython/providers/rye.py 0.7.0-1/src/findpython/providers/rye.py
--- 0.6.2-1/src/findpython/providers/rye.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/rye.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,24 +1,33 @@
 from __future__ import annotations
 
 import os
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 from findpython.utils import WINDOWS, safe_iter_dir
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 class RyeProvider(BaseProvider):
     def __init__(self, root: Path) -> None:
         self.root = root
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         root = Path(os.getenv("RYE_PY_ROOT", "~/.rye/py")).expanduser()
         return cls(root)
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         if not self.root.exists():
             return
         for child in safe_iter_dir(self.root):
diff -pruN 0.6.2-1/src/findpython/providers/uv.py 0.7.0-1/src/findpython/providers/uv.py
--- 0.6.2-1/src/findpython/providers/uv.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/uv.py	2025-08-10 00:19:08.000000000 +0000
@@ -0,0 +1,21 @@
+from __future__ import annotations
+
+import os
+import typing as t
+from pathlib import Path
+
+import platformdirs
+
+from findpython.providers.rye import RyeProvider
+
+
+class UvProvider(RyeProvider):
+    @classmethod
+    def create(cls) -> t.Self | None:
+        default_root_str = platformdirs.user_data_dir("uv", appauthor=False, roaming=True)
+        root_str = os.getenv("UV_PYTHON_INSTALL_DIR")
+        if root_str is None:
+            root = Path(default_root_str).expanduser() / "python"
+        else:
+            root = Path(root_str).expanduser()
+        return cls(root)
diff -pruN 0.6.2-1/src/findpython/providers/winreg.py 0.7.0-1/src/findpython/providers/winreg.py
--- 0.6.2-1/src/findpython/providers/winreg.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/providers/winreg.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,8 +1,8 @@
 from __future__ import annotations
 
 import platform
-import typing as t
 from pathlib import Path
+from typing import TYPE_CHECKING
 
 from packaging.version import Version
 
@@ -10,6 +10,15 @@ from findpython.providers.base import Ba
 from findpython.python import PythonVersion
 from findpython.utils import WINDOWS
 
+if TYPE_CHECKING:
+    import sys
+    from typing import Iterable
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 SYS_ARCHITECTURE = platform.architecture()[0]
 
 
@@ -17,12 +26,12 @@ class WinregProvider(BaseProvider):
     """A provider that finds Python from the winreg."""
 
     @classmethod
-    def create(cls) -> t.Self | None:
+    def create(cls) -> Self | None:
         if not WINDOWS:
             return None
         return cls()
 
-    def find_pythons(self) -> t.Iterable[PythonVersion]:
+    def find_pythons(self) -> Iterable[PythonVersion]:
         from findpython.pep514tools import findall as pep514_findall
 
         env_versions = pep514_findall()
diff -pruN 0.6.2-1/src/findpython/python.py 0.7.0-1/src/findpython/python.py
--- 0.6.2-1/src/findpython/python.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/python.py	2025-08-10 00:19:08.000000000 +0000
@@ -39,6 +39,7 @@ class PythonVersion:
     _architecture: str | None = None
     _interpreter: Path | None = None
     keep_symlink: bool = False
+    _freethreaded: bool | None = None
 
     def is_valid(self) -> bool:
         """Return True if the python is not broken."""
@@ -66,7 +67,7 @@ class PythonVersion:
     @property
     def implementation(self) -> str:
         """Return the implementation of the python."""
-        script = "import platform; print(platform.python_implementation())"
+        script = "import platform; print(platform.python_implementation().lower())"
         return _run_script(str(self.executable), script).strip()
 
     @property
@@ -118,6 +119,12 @@ class PythonVersion:
             self._architecture = self._get_architecture()
         return self._architecture
 
+    @property
+    def freethreaded(self) -> bool:
+        if self._freethreaded is None:
+            self._freethreaded = self._get_freethreaded()
+        return self._freethreaded
+
     def binary_hash(self) -> str:
         """Return the binary hash of the python."""
         return get_binary_hash(self.real_path)
@@ -132,6 +139,7 @@ class PythonVersion:
         name: str | None = None,
         architecture: str | None = None,
         implementation: str | None = None,
+        freethreaded: bool | None = None,
     ) -> bool:
         """
         Return True if the python matches the provided criteria.
@@ -152,6 +160,8 @@ class PythonVersion:
         :type architecture: str
         :param implementation: The implementation of the python.
         :type implementation: str
+        :param freethreaded: Whether the python is freethreaded.
+        :type freethreaded: bool
         :return: Whether the python matches the provided criteria.
         :rtype: bool
         """
@@ -174,6 +184,8 @@ class PythonVersion:
             and self.implementation.lower() != implementation.lower()
         ):
             return False
+        if freethreaded is not None and self.freethreaded != freethreaded:
+            return False
         return True
 
     def __hash__(self) -> int:
@@ -188,13 +200,21 @@ class PythonVersion:
             "major",
             "minor",
             "patch",
+            "freethreaded",
         )
         return "<PythonVersion {}>".format(
             ", ".join(f"{attr}={getattr(self, attr)!r}" for attr in attrs)
         )
 
+    def display(self) -> str:
+        threaded_flag = "t" if self.freethreaded else ""
+        return (
+            f"{self.implementation:>9}@{self.version}{threaded_flag}: {self.executable}"
+        )
+
     def __str__(self) -> str:
-        return f"{self.implementation:>9}@{self.version}: {self.executable}"
+        threaded_flag = "t" if self.freethreaded else ""
+        return f"{self.implementation}@{self.version}{threaded_flag}"
 
     def _get_version(self) -> Version:
         """Get the version of the python."""
@@ -216,9 +236,22 @@ class PythonVersion:
         script = "import sys; print(sys.executable)"
         return _run_script(str(self.executable), script).strip()
 
+    def _get_freethreaded(self) -> bool:
+        script = (
+            'import sysconfig;print(sysconfig.get_config_var("Py_GIL_DISABLED") or 0)'
+        )
+        return _run_script(str(self.executable), script).strip() == "1"
+
     def __lt__(self, other: PythonVersion) -> bool:
         """Sort by the version, then by length of the executable path."""
-        return (self.version, len(self.executable.as_posix())) < (
+        return (
+            self.version,
+            int(self.architecture.startswith("64bit")),
+            len(self.executable.as_posix()),
+            self.freethreaded,
+        ) < (
             other.version,
+            int(other.architecture.startswith("64bit")),
             len(other.executable.as_posix()),
+            other.freethreaded,
         )
diff -pruN 0.6.2-1/src/findpython/utils.py 0.7.0-1/src/findpython/utils.py
--- 0.6.2-1/src/findpython/utils.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/src/findpython/utils.py	2025-08-10 00:19:08.000000000 +0000
@@ -16,7 +16,7 @@ VERSION_RE = re.compile(
     r"(?:(?P<implementation>\w+)@)?(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>[0-9]+))?)?\.?"
     r"(?:(?P<prerel>[abc]|rc|dev)(?:(?P<prerelversion>\d+(?:\.\d+)*))?)"
     r"?(?P<postdev>(\.post(?P<post>\d+))?(\.dev(?P<dev>\d+))?)?"
-    r"(?:-(?P<architecture>32|64))?"
+    r"(?P<freethreaded>t)?(?:-(?P<architecture>32|64))?"
 )
 WINDOWS = sys.platform == "win32"
 MACOS = sys.platform == "darwin"
@@ -37,7 +37,7 @@ if WINDOWS:
 else:
     KNOWN_EXTS = ("", ".sh", ".bash", ".csh", ".zsh", ".fish", ".py")
 PY_MATCH_STR = (
-    r"((?P<implementation>{0})(?:\d(?:\.?\d\d?[cpm]{{0,3}})?)?"
+    r"((?P<implementation>{0})(?:\d(?:\.?\d\d?(?:[cpm]|td?){{0,3}})?)?"
     r"(?:(?<=\d)-[\d\.]+)*(?!w))(?P<suffix>{1})$".format(
         "|".join(PYTHON_IMPLEMENTATIONS),
         "|".join(KNOWN_EXTS),
@@ -130,6 +130,7 @@ if TYPE_CHECKING:
         patch: int | None
         architecture: str | None
         implementation: str | None
+        freethreaded: bool
 
 
 def parse_major(version: str) -> VersionDict | None:
@@ -140,6 +141,7 @@ def parse_major(version: str) -> Version
     rv = match.groupdict()
     rv["pre"] = bool(rv.pop("prerel"))
     rv["dev"] = bool(rv.pop("dev"))
+    rv["freethreaded"] = bool(rv.pop("freethreaded"))
     for int_values in ("major", "minor", "patch"):
         if rv[int_values] is not None:
             rv[int_values] = int(rv[int_values])
diff -pruN 0.6.2-1/tests/conftest.py 0.7.0-1/tests/conftest.py
--- 0.6.2-1/tests/conftest.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/tests/conftest.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from pathlib import Path
 from unittest.mock import PropertyMock
 
@@ -19,7 +21,8 @@ class _MockRegistry:
         architecture="64bit",
         interpreter=None,
         keep_symlink=False,
-    ):
+        freethreaded=False,
+    ) -> PythonVersion:
         if version is not None:
             version = parse(version)
         executable = Path(executable)
@@ -29,19 +32,19 @@ class _MockRegistry:
         executable.touch(exist_ok=True)
         executable.chmod(0o744)
         py_ver = PythonVersion(
-            executable, version, architecture, interpreter, keep_symlink
+            executable, version, architecture, interpreter, keep_symlink, freethreaded
         )
         if version is not None:
-            py_ver._get_version = lambda: version
+            py_ver._get_version = lambda: version  # type:ignore[method-assign]
         self.versions[executable] = py_ver
         return py_ver
 
-    def version_maker(self, executable, *args, **kwargs):
+    def version_maker(self, executable, *args, **kwargs) -> PythonVersion:
         return self.versions[executable]
 
 
 @pytest.fixture()
-def mocked_python(tmp_path, monkeypatch):
+def mocked_python(tmp_path, monkeypatch) -> _MockRegistry:
     mocked = _MockRegistry()
     for python in [
         (tmp_path / "python3.7", "3.7.0"),
@@ -54,7 +57,7 @@ def mocked_python(tmp_path, monkeypatch)
     )
     monkeypatch.setattr(
         "findpython.python.PythonVersion.implementation",
-        PropertyMock(return_value="CPython"),
+        PropertyMock(return_value="cpython"),
     )
     ALL_PROVIDERS.clear()
     ALL_PROVIDERS["path"] = PathProvider
@@ -63,5 +66,5 @@ def mocked_python(tmp_path, monkeypatch)
 
 
 @pytest.fixture(params=[False, True])
-def switch(request):
+def switch(request) -> bool:
     return request.param
diff -pruN 0.6.2-1/tests/test_cli.py 0.7.0-1/tests/test_cli.py
--- 0.6.2-1/tests/test_cli.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/tests/test_cli.py	2025-08-10 00:19:08.000000000 +0000
@@ -7,7 +7,7 @@ def test_cli_find_pythons(mocked_python,
     out, _ = capsys.readouterr()
     lines = out.strip().splitlines()
     for version, line in zip(("3.9", "3.8", "3.7"), lines):
-        assert line.lstrip().startswith(f"CPython@{version}.0")
+        assert line.lstrip().startswith(f"cpython@{version}.0")
 
 
 def test_cli_find_python_by_version(mocked_python, capsys, tmp_path):
@@ -15,5 +15,24 @@ def test_cli_find_python_by_version(mock
     assert retcode == 0
     out, _ = capsys.readouterr()
     line = out.strip()
-    assert line.startswith("CPython@3.8.0")
+    assert line.startswith("cpython@3.8.0")
     assert line.endswith(str(tmp_path / "python3.8"))
+
+
+def test_cli_find_python_freethreaded(mocked_python, capsys, tmp_path):
+    mocked_python.add_python(tmp_path / "python3.13", "3.13.0")
+    mocked_python.add_python(tmp_path / "python3.13t", "3.13.0", freethreaded=True)
+
+    retcode = cli(["--all", "3.13"])
+    assert retcode == 0
+    out, _ = capsys.readouterr()
+    line = out.strip()
+    assert "\n" not in line
+    assert line.lstrip().split(":")[0] == "cpython@3.13.0"
+
+    retcode = cli(["--all", "3.13t"])
+    assert retcode == 0
+    out, _ = capsys.readouterr()
+    line = out.strip()
+    assert "\n" not in line
+    assert line.lstrip().split(":")[0] == "cpython@3.13.0t"
diff -pruN 0.6.2-1/tests/test_posix.py 0.7.0-1/tests/test_posix.py
--- 0.6.2-1/tests/test_posix.py	2024-10-17 01:13:21.000000000 +0000
+++ 0.7.0-1/tests/test_posix.py	2025-08-10 00:19:08.000000000 +0000
@@ -1,3 +1,4 @@
+import platform
 import stat
 import sys
 from pathlib import Path
@@ -9,6 +10,7 @@ from findpython.finder import Finder
 from findpython.providers.asdf import AsdfProvider
 from findpython.providers.pyenv import PyenvProvider
 from findpython.providers.rye import RyeProvider
+from findpython.providers.uv import UvProvider
 
 if sys.platform == "win32":
     pytest.skip("Skip POSIX tests on Windows", allow_module_level=True)
@@ -93,3 +95,31 @@ def test_find_python_from_rye_provider(m
 
     find_311 = Finder(selected_providers=["rye"]).find_all(3, 11)
     assert python311 in find_311
+
+
+def test_find_python_from_uv_provider(mocked_python, tmp_path, monkeypatch):
+    if platform.system() == "Linux":
+        python_root = tmp_path / ".local/share/uv/python"
+    else:  # macos
+        python_root = tmp_path / "Library/Application Support/uv/python"
+    python310 = mocked_python.add_python(
+        python_root / "cpython@3.10.9/install/bin/python3", "3.10.9"
+    )
+    python311 = mocked_python.add_python(
+        python_root / "cpython@3.11.8/bin/python3", "3.11.8"
+    )
+    monkeypatch.setenv("HOME", str(tmp_path))
+
+    register_provider(UvProvider)
+    find_310 = Finder(selected_providers=["uv"]).find_all(3, 10)
+    assert python310 in find_310
+
+    find_311 = Finder(selected_providers=["uv"]).find_all(3, 11)
+    assert python311 in find_311
+
+    monkeypatch.setenv("UV_PYTHON_INSTALL_DIR", str(tmp_path / "uv_dir"))
+    python311_uv_dir = mocked_python.add_python(
+        tmp_path / "uv_dir/cpython@3.11.8/bin/python3", "3.11.8"
+    )
+    find_311 = Finder(selected_providers=["uv"]).find_all(3, 11)
+    assert python311_uv_dir in find_311
