-
-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hatch doesn’t find Python versions other than its own and …/python{,3}
on Linux
#1395
Comments
When I run I wonder why Hatch downloads Python 3.12 when |
Is this issue present on master? |
yes, Hatch 1.9.2.dev93 (8648544) throws the same error (I didn’t check if the APIs return the same values as in 1.9.2) |
Please show me: from virtualenv.discovery.builtin import propose_interpreters
from virtualenv.discovery.py_spec import PythonSpec
def main():
for data in propose_interpreters(PythonSpec.from_string_spec('3.12'), (), None):
interpreter = data[0]
version = '.'.join(map(str, interpreter.version_info[:3]))
print(f'{version} -> {interpreter.executable}')
if __name__ == '__main__':
main() |
|
That conflicts with what happened in the opening description. Is this a new terminal session? Has PATH been updated since the first one which is why originally there was no 3.12? |
OK, I have now slept and executed it with the correct interpreter lol. Edited above with the correct output. For context on why your script output differs from the So |
Can you please then show the output of the empty string change? |
When replacing
I think the problem is that it doesn’t find all binaries on the $PATH: $ ls /usr/bin/python* | where name =~ '\d$'
╭───┬─────────────────────┬─────────┬─────────┬───────────────╮
│ # │ name │ type │ size │ modified │
├───┼─────────────────────┼─────────┼─────────┼───────────────┤
│ 0 │ /usr/bin/python3 │ symlink │ 10 B │ 2 months ago │
│ 1 │ /usr/bin/python3.10 │ file │ 14.3 KB │ 3 weeks ago │
│ 2 │ /usr/bin/python3.11 │ file │ 14.4 KB │ 2 months ago │
│ 3 │ /usr/bin/python3.12 │ file │ 14.2 KB │ 2 months ago │
│ 4 │ /usr/bin/python3.7 │ file │ 14.2 KB │ 10 months ago │
│ 5 │ /usr/bin/python3.8 │ file │ 14.3 KB │ 3 weeks ago │
│ 6 │ /usr/bin/python3.9 │ file │ 14.3 KB │ 3 weeks ago │
╰───┴─────────────────────┴─────────┴─────────┴───────────────╯ |
That's very interesting, I interpreted empty string as the way to get everything, which I suppose does work on Windows because there is never a version suffix! Oh my |
what happens when you try just |
Still only 3.11 found |
@gaborbernat is started to extract this from |
Yes @gaborbernat what is the magic first argument spec I must pass to from virtualenv.discovery.builtin import propose_interpreters
from virtualenv.discovery.py_spec import PythonSpec
def main():
for data in propose_interpreters(PythonSpec.from_string_spec('3'), (), None):
interpreter = data[0]
version = '.'.join(map(str, interpreter.version_info[:3]))
print(f'{version} -> {interpreter.executable}')
if __name__ == '__main__':
main() |
I don’t think there is any.
So these are searched in the PATH. Seems like |
…/python{,3}
on Linux
I don't know from the top of my head 😔 |
Well, I checked the code, there doesn‘t seem to be any functionality to find @gaborbernat is there interest to support that? Then I think I can come up with an algorithm that works. A more robust version of: import os
import re
from collections.abc import Generator, MutableMapping
from pathlib import Path
from virtualenv.discovery.builtin import get_paths, PathPythonInfo
def find_candidates(
spec: str,
env: MutableMapping[str, str] | None = None,
) -> Generator[Path, None, None]:
env = os.environ if env is None else env
maj, min = spec.split(":") if ":" in spec else (spec, r"\d+")
maj = maj or r"\d+"
regex = f"python|(python)?{maj}(\.{min}+)?"
regex = re.compile(f"({regex}).exe" if sys.platform == "win32" else regex)
tested_exes = set()
for found in (found for path in get_paths(env) for found in Path(path).iterdir()):
if not regex.fullmatch(found.name) or not found.is_file():
continue
exe = found.resolve()
if exe in tested_exes:
continue
tested_exes.add(exe)
got = PathPythonInfo.from_exe(exe, raise_on_error=False, env=env)
if got is not None:
yield got, True # TODO: what is the bool here?
if __name__ == "__main__":
import sys
for path, match in find_candidates(sys.argv[1] if len(sys.argv) > 1 else ''):
print(path, match) |
In Fedora Linux, we can’t upgrade our Now that we finally managed to package Since I’m not intimately familiar with Hatch’s expected behavior in different environments and situations, I haven’t been able to figure out a simple, straightforward test I can run in a Fedora Rawhide chroot to try to reproduce this bug. That would help me figure out the answer for myself, so any suggestions in that direction are appreciated as well. |
I don't have time to check but please note that you actually would require both of these because the first introduced another regression: |
Hmm, I had ignored the second PR because it fixed a problem “on Windows,” but reading the description, it sounds like “Addresses another issue found during debugging which is that the PR that introduced the regression took out a check to make sure that executables exist before trying to gather data about the interpreter” might still apply to us. |
If I configure a project with
requires_python '>=3.12'
, on my system I see this error:hatch/src/hatch/env/virtual.py
Line 258 in 8648544
I don’t understand what the code is supposed to do. It requires either an env variable or one of two functions to not return
None
:_get_available_distribution
seems to callhatch.python.resolve.get_compatible_distributions
, and then it removes the “installed distribution”hatch/src/hatch/env/virtual.py
Lines 374 to 376 in 8648544
get_compatible_distributions()
returns everything hatch can download:In my case
self.python_manager.get_installed().keys() == {'3.12'}
, so_get_available_distribution
returnsNone
_find_existing_interpreter
callsvirtualenv.discovery.builtin.propose_interpreters
, which yields this on my system:so that function also returns
None
.I can work around this using
but this should still be fixed. I’d be happy to help, but I don’t know what the intended semantics of
_get_available_distribution
and_find_existing_interpreter
are: Which one of these is supposed to return/usr/bin/python3.12
?The text was updated successfully, but these errors were encountered: