ducktools-pythonfinder 0.10.4__tar.gz → 0.10.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {ducktools_pythonfinder-0.10.4/src/ducktools_pythonfinder.egg-info → ducktools_pythonfinder-0.10.6}/PKG-INFO +1 -1
  2. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/pyproject.toml +2 -0
  3. ducktools_pythonfinder-0.10.6/src/ducktools/pythonfinder/_version.py +2 -0
  4. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/linux/__init__.py +8 -5
  5. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/shared.py +8 -9
  6. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6/src/ducktools_pythonfinder.egg-info}/PKG-INFO +1 -1
  7. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_uv_finder.py +0 -11
  8. ducktools_pythonfinder-0.10.6/uv.lock +522 -0
  9. ducktools_pythonfinder-0.10.4/src/ducktools/pythonfinder/_version.py +0 -2
  10. ducktools_pythonfinder-0.10.4/uv.lock +0 -376
  11. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/.gitignore +0 -0
  12. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/LICENSE +0 -0
  13. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/MANIFEST.in +0 -0
  14. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/README.md +0 -0
  15. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/scripts/build_zipapp.py +0 -0
  16. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/scripts/detail_this_python.py +0 -0
  17. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/scripts/list_python_venvs.py +0 -0
  18. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/scripts/print_python_versions.py +0 -0
  19. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/setup.cfg +0 -0
  20. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/__init__.py +0 -0
  21. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/__main__.py +0 -0
  22. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/darwin/__init__.py +0 -0
  23. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/details_script.py +0 -0
  24. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/linux/pyenv_search.py +0 -0
  25. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/package_list_script.py +0 -0
  26. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/py.typed +0 -0
  27. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/pythonorg_search.py +0 -0
  28. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/venv.py +0 -0
  29. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/win32/__init__.py +0 -0
  30. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/win32/pyenv_search.py +0 -0
  31. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools/pythonfinder/win32/registry_search.py +0 -0
  32. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools_pythonfinder.egg-info/SOURCES.txt +0 -0
  33. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools_pythonfinder.egg-info/dependency_links.txt +0 -0
  34. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools_pythonfinder.egg-info/entry_points.txt +0 -0
  35. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools_pythonfinder.egg-info/requires.txt +0 -0
  36. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/src/ducktools_pythonfinder.egg-info/top_level.txt +0 -0
  37. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/conftest.py +0 -0
  38. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/sources/python_versions.txt +0 -0
  39. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/sources/release.json +0 -0
  40. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/sources/release_file.json +0 -0
  41. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_cache.py +0 -0
  42. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_details_script.py +0 -0
  43. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_foldersearch.py +0 -0
  44. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_orgsearch.py +0 -0
  45. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_pyenv.py +0 -0
  46. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_shared.py +0 -0
  47. {ducktools_pythonfinder-0.10.4 → ducktools_pythonfinder-0.10.6}/tests/test_venv_finder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ducktools-pythonfinder
3
- Version: 0.10.4
3
+ Version: 0.10.6
4
4
  Summary: Cross platform tool to find available python installations
5
5
  Author: David C Ellis
6
6
  License-Expression: MIT
@@ -46,6 +46,8 @@ dev = [
46
46
  "mypy>=1.16",
47
47
  ]
48
48
 
49
+ zipapp = ["pip>=26.0"]
50
+
49
51
  [tool.setuptools.packages.find]
50
52
  where = ["src"]
51
53
 
@@ -0,0 +1,2 @@
1
+ __version__ = "0.10.6"
2
+ __version_tuple__ = (0, 10, 6)
@@ -80,12 +80,15 @@ def get_path_pythons(
80
80
  if not os.path.exists(fld):
81
81
  continue
82
82
 
83
- for install in get_folder_pythons(fld, finder=finder):
84
- for path, manager in known_paths.items():
85
- if os.path.commonpath((path, install.executable)) == path:
86
- install.managed_by = manager
87
- break
83
+ # Do the search like this to get subfolders
84
+ for path, manager in known_paths.items():
85
+ if os.path.commonpath((path, fld)) == path:
86
+ managed_by = manager
87
+ break
88
+ else:
89
+ managed_by = None
88
90
 
91
+ for install in get_folder_pythons(fld, finder=finder, managed_by=managed_by):
89
92
  name = os.path.basename(install.executable)
90
93
  if name in exe_names:
91
94
  install.shadowed = True
@@ -51,13 +51,6 @@ _laz = LazyImporter(
51
51
 
52
52
  FULL_PY_VER_RE = r"(?P<major>\d+)\.(?P<minor>\d+)\.?(?P<micro>\d*)-?(?P<releaselevel>a|b|c|rc)?(?P<serial>\d*)?"
53
53
 
54
- UV_PYTHON_RE = (
55
- r"(?P<implementation>[a-zA-Z]+)"
56
- r"-(?P<version>\d+\.\d+\.\d*[a-zA-Z]*\d*)\+?(?P<extra>.*?)?"
57
- r"-(?P<platform>\w*)"
58
- r"-(?P<arch>\w*)"
59
- r"-.*"
60
- )
61
54
 
62
55
  # Cache for runtime details
63
56
  # Code to work out where to store data
@@ -298,16 +291,21 @@ class DetailFinder(Prefab):
298
291
  exe_path = os.path.abspath(exe_path)
299
292
  mtime = os.stat(exe_path).st_mtime
300
293
 
294
+ # If the mtime of the file has been set to 0
295
+ # it is not possible to reliably cache install details
296
+ cacheable_install = (mtime != 0)
297
+
301
298
  install = None
302
299
  if cached_details := self.raw_cache.get(exe_path):
303
- if cached_details["mtime"] == mtime:
300
+ if cacheable_install and cached_details["mtime"] == mtime:
304
301
  install = PythonInstall.from_json(**cached_details["install"])
305
302
  else:
306
303
  self.raw_cache.pop(exe_path)
304
+ self._dirty_cache = True
307
305
 
308
306
  if install is None:
309
307
  install = self.query_install(exe_path, managed_by, metadata)
310
- if install:
308
+ if install and cacheable_install:
311
309
  self.raw_cache[exe_path] = {
312
310
  "mtime": mtime,
313
311
  "install": as_dict(install)
@@ -574,6 +572,7 @@ def get_uv_pythons(finder=None) -> Iterator[PythonInstall]:
574
572
  for f in fld:
575
573
  if (
576
574
  f.is_dir()
575
+ and not f.is_symlink()
577
576
  and (install := _implementation_from_uv_dir(f, finder=finder))
578
577
  ):
579
578
  yield install
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ducktools-pythonfinder
3
- Version: 0.10.4
3
+ Version: 0.10.6
4
4
  Summary: Cross platform tool to find available python installations
5
5
  Author: David C Ellis
6
6
  License-Expression: MIT
@@ -33,7 +33,6 @@ import unittest.mock as mock
33
33
  import pytest
34
34
 
35
35
  from ducktools.pythonfinder.shared import (
36
- UV_PYTHON_RE,
37
36
  get_uv_python_path,
38
37
  get_uv_pythons,
39
38
  )
@@ -153,13 +152,3 @@ class TestUVReal:
153
152
  assert pythons[0].implementation == "pypy"
154
153
  assert pythons[0].implementation_version >= (7, 3, 17)
155
154
  assert pythons[0].managed_by == "Astral"
156
-
157
-
158
- def test_regex_matches():
159
- example_312 = "cpython-3.12.7-windows-x86_64-none"
160
- match = re.match(UV_PYTHON_RE, example_312)
161
- assert match.groups() == ("cpython", "3.12.7", "", "windows", "x86_64")
162
-
163
- example_313t = "cpython-3.13.0+freethreaded-windows-x86_64-none"
164
- match = re.match(UV_PYTHON_RE, example_313t)
165
- assert match.groups() == ("cpython", "3.13.0", "freethreaded", "windows", "x86_64")