ducktools-pythonfinder 0.7.3__tar.gz → 0.7.4__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 (42) hide show
  1. {ducktools_pythonfinder-0.7.3/src/ducktools_pythonfinder.egg-info → ducktools_pythonfinder-0.7.4}/PKG-INFO +1 -1
  2. ducktools_pythonfinder-0.7.4/src/ducktools/pythonfinder/_version.py +2 -0
  3. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/venv.py +40 -10
  4. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4/src/ducktools_pythonfinder.egg-info}/PKG-INFO +1 -1
  5. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/conftest.py +13 -2
  6. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_venv_finder.py +1 -1
  7. ducktools_pythonfinder-0.7.3/src/ducktools/pythonfinder/_version.py +0 -2
  8. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/.gitignore +0 -0
  9. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/LICENSE +0 -0
  10. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/MANIFEST.in +0 -0
  11. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/README.md +0 -0
  12. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/pyproject.toml +0 -0
  13. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/scripts/build_zipapp.py +0 -0
  14. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/scripts/detail_this_python.py +0 -0
  15. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/scripts/list_python_venvs.py +0 -0
  16. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/scripts/print_python_versions.py +0 -0
  17. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/setup.cfg +0 -0
  18. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/__init__.py +0 -0
  19. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/__main__.py +0 -0
  20. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/darwin/__init__.py +0 -0
  21. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/details_script.py +0 -0
  22. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/linux/__init__.py +0 -0
  23. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/linux/pyenv_search.py +0 -0
  24. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/pythonorg_search.py +0 -0
  25. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/shared.py +0 -0
  26. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/win32/__init__.py +0 -0
  27. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/win32/pyenv_search.py +0 -0
  28. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools/pythonfinder/win32/registry_search.py +0 -0
  29. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools_pythonfinder.egg-info/SOURCES.txt +0 -0
  30. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools_pythonfinder.egg-info/dependency_links.txt +0 -0
  31. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools_pythonfinder.egg-info/entry_points.txt +0 -0
  32. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools_pythonfinder.egg-info/requires.txt +0 -0
  33. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/src/ducktools_pythonfinder.egg-info/top_level.txt +0 -0
  34. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/sources/python_versions.txt +0 -0
  35. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/sources/release.json +0 -0
  36. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/sources/release_file.json +0 -0
  37. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_details_script.py +0 -0
  38. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_foldersearch.py +0 -0
  39. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_orgsearch.py +0 -0
  40. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_pyenv.py +0 -0
  41. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_shared.py +0 -0
  42. {ducktools_pythonfinder-0.7.3 → ducktools_pythonfinder-0.7.4}/tests/test_uv_finder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ducktools-pythonfinder
3
- Version: 0.7.3
3
+ Version: 0.7.4
4
4
  Summary: Cross platform tool to find available python installations
5
5
  Author: David C Ellis
6
6
  Project-URL: Homepage, https://github.com/davidcellis/ducktools-pythonfinder
@@ -0,0 +1,2 @@
1
+ __version__ = "0.7.4"
2
+ __version_tuple__ = (0, 7, 4)
@@ -31,7 +31,7 @@ import os
31
31
  import sys
32
32
 
33
33
 
34
- from ducktools.classbuilder.prefab import Prefab
34
+ from ducktools.classbuilder.prefab import Prefab, attribute
35
35
  from ducktools.lazyimporter import LazyImporter, FromImport, ModuleImport
36
36
 
37
37
  from .shared import (
@@ -46,6 +46,7 @@ _laz = LazyImporter(
46
46
  [
47
47
  ModuleImport("re"),
48
48
  ModuleImport("json"),
49
+ ModuleImport("subprocess"),
49
50
  FromImport("pathlib", "Path"),
50
51
  FromImport("subprocess", "run"),
51
52
  ]
@@ -74,6 +75,7 @@ class PythonVEnv(Prefab):
74
75
  executable: str
75
76
  version: tuple[int, int, int, str, int]
76
77
  parent_path: str
78
+ _parent_executable: str | None = attribute(default=None, repr=False)
77
79
 
78
80
  @property
79
81
  def version_str(self) -> str:
@@ -81,10 +83,34 @@ class PythonVEnv(Prefab):
81
83
 
82
84
  @property
83
85
  def parent_executable(self) -> str:
84
- if sys.platform == "win32":
85
- return os.path.join(self.parent_path, "python.exe")
86
- else:
87
- return os.path.join(self.parent_path, "python")
86
+ if self._parent_executable is None:
87
+ # Guess the parent executable file
88
+ if sys.platform == "win32":
89
+ parent_exe = os.path.join(self.parent_path, "python.exe")
90
+ else:
91
+ parent_exe = os.path.join(self.parent_path, "python")
92
+
93
+ if not os.path.exists(parent_exe):
94
+ try:
95
+ pyout = _laz.run(
96
+ [
97
+ self.executable,
98
+ "-c",
99
+ "from sysconfig import get_config_var; print(get_config_var('EXENAME'))",
100
+ ],
101
+ capture_output=True,
102
+ text=True,
103
+ check=True,
104
+ )
105
+ except _laz.subprocess.CalledProcessError:
106
+ pass
107
+ else:
108
+ if out_exe := pyout.stdout.strip():
109
+ parent_exe = os.path.join(self.parent_path, os.path.basename(out_exe))
110
+
111
+ self._parent_executable = parent_exe
112
+
113
+ return self._parent_executable
88
114
 
89
115
  @property
90
116
  def parent_exists(self) -> bool:
@@ -150,7 +176,7 @@ class PythonVEnv(Prefab):
150
176
  :param cfg_path: Path to a virtualenv config file
151
177
  :return: PythonVEnv with details relative to that config file
152
178
  """
153
- parent_path, version_str = None, None
179
+ parent_path, version_str, parent_exe = None, None, None
154
180
  venv_base = os.path.dirname(cfg_path)
155
181
 
156
182
  with open(cfg_path, 'r') as f:
@@ -162,12 +188,15 @@ class PythonVEnv(Prefab):
162
188
  elif key in {"version", "version_info"}:
163
189
  # venv and uv use different key names :)
164
190
  version_str = value
191
+ elif key == "executable":
192
+ parent_exe = value
165
193
 
166
- if parent_path and version_str:
194
+ if parent_path and version_str and parent_exe:
167
195
  break
168
- else:
169
- # Not a valid venv, ignore
170
- raise InvalidVEnvError(f"Path and version not defined in {cfg_path}")
196
+
197
+ if parent_path is None or version_str is None:
198
+ # Not a valid venv
199
+ raise InvalidVEnvError(f"Path or version not defined in {cfg_path}")
171
200
 
172
201
  if sys.platform == "win32":
173
202
  venv_exe = os.path.join(venv_base, "Scripts", "python.exe")
@@ -198,6 +227,7 @@ class PythonVEnv(Prefab):
198
227
  executable=venv_exe,
199
228
  version=version_tuple,
200
229
  parent_path=parent_path,
230
+ _parent_executable=parent_exe,
201
231
  )
202
232
 
203
233
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ducktools-pythonfinder
3
- Version: 0.7.3
3
+ Version: 0.7.4
4
4
  Summary: Cross platform tool to find available python installations
5
5
  Author: David C Ellis
6
6
  Project-URL: Homepage, https://github.com/davidcellis/ducktools-pythonfinder
@@ -20,7 +20,9 @@
20
20
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
21
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  # SOFTWARE.
23
+ import os.path
23
24
  import sys
25
+ import sysconfig
24
26
 
25
27
  from pathlib import Path
26
28
 
@@ -42,10 +44,19 @@ def uses_details_script(fs):
42
44
 
43
45
  @pytest.fixture(scope="session")
44
46
  def this_python():
47
+ config_exe = sysconfig.get_config_var("EXENAME")
48
+
49
+ if config_exe:
50
+ exename = os.path.basename(sysconfig.get_config_var("EXENAME"))
51
+ elif sys.platform == "win32":
52
+ exename = "python.exe"
53
+ else:
54
+ exename = "python"
55
+
45
56
  if sys.platform == "win32":
46
- py_exe = Path(sys.base_prefix) / "python.exe"
57
+ py_exe = Path(sys.base_prefix) / exename
47
58
  else:
48
- py_exe = Path(sys.base_prefix) / "bin" / "python"
59
+ py_exe = Path(sys.base_prefix) / "bin" / exename
49
60
 
50
61
  return get_install_details(str(py_exe))
51
62
 
@@ -125,7 +125,7 @@ def test_found_parent(with_venvs, this_python, this_venv):
125
125
 
126
126
  # We found the base env that created this python, all details match
127
127
  parent = venv_ex.get_parent_install()
128
- assert parent == this_python
128
+ assert os.path.dirname(parent.executable) == os.path.dirname(this_python.executable)
129
129
 
130
130
  # venv version str works same as parent
131
131
  assert venv_ex.version_str == parent.version_str
@@ -1,2 +0,0 @@
1
- __version__ = "0.7.3"
2
- __version_tuple__ = (0, 7, 3)