pypa / virtualenv

Virtual Python Environment builder
https://virtualenv.pypa.io
MIT License
4.78k stars 1.02k forks source link

Allow builtin interpreter discovery to find specific Python versions given a general spec #2709

Closed flying-sheep closed 4 months ago

flying-sheep commented 4 months ago

Thanks for contributing, make sure you address all the checklists (for details on how see development documentation)

Fixes https://github.com/pypa/virtualenv/issues/2708, fixes https://github.com/pypa/hatch/issues/1395

This PR fixes the discovery in virtualenv.discovery.builtin.

It works by removing the method PythonSpec.generate_names and replacing it with generate_re:

A static name list can’t represent all Python executables that are compatible with a given spec, i.e. PythonSpec.from_string_spec('3') should match a executable called /usr/bin/python3.12. I therefore inverted the way candidates are found. Instead of generating all possible candidates, we simply loop and use a regex to find candidates.

Pro:

Con:

How to review

The main commits are

flying-sheep commented 4 months ago

On it! It’s a draft so you can look at it if you want while I check those last boxes!

flying-sheep commented 4 months ago

Now I’m done!

Seems like this change snuck into one of the tests:

-    pyvenv_cfg = Path(sys.executable).parents[1] / "pyvenv.cfg"
-    if pyvenv_cfg.exists():
-        (target / pyvenv_cfg.name).write_bytes(pyvenv_cfg.read_bytes())

that fragment doesn’t seem to be necessary to run the test locally?

gaborbernat commented 4 months ago

Seems you've upset the CI 😅

flying-sheep commented 4 months ago

I guess I need to try this on macOS. No idea what to do if I can’t placate windows though …

Seems like it works in practice though!

  1. create project requiring Python 3.12 on a system where /usr/bin/python is 3.11:

    $ cd some-project
    $ rg requires-python pyproject.toml 
    4:requires-python = ">=3.12"
  2. try finding an interpreter with hatch:

    $ pipx install hatch
    $ hatch env create
    Environment `default` is incompatible: no compatible Python distribution available
  3. try my patch (no clue why virtualenv doesn’s:

    $ ~/.local/pipx/venvs/hatch/bin/python -m pip install 'virtualenv@ git+https://github.com/flying-sheep/virtualenv.git@discover-more'
    […]
    Successfully installed virtualenv-20.25.4.dev11+g66d9408
    $ hatch env create

    no output means success!

gaborbernat commented 4 months ago

Huh, tests run fine locally … let’s see.

I cannot merge the pull request until the CI is green so it doesn't really matter that "it works on my machine" 😅. Sorry but the CI gods are absolute. 😭

flying-sheep commented 4 months ago

Haha I’m a believer, don’t worry. It’s great that you test on windows and macOS too, as clearly with finnicky path stuff like this, that’s an issue. I’ll see what I can do.

flying-sheep commented 4 months ago

Ah, the regex always needs to be case insensitive to get the intended effect. I tested locally on macOS and Linux now, so I hope windows doesn’t throw a wrench.

flying-sheep commented 4 months ago

OK, as feared everything passes except for on windows. I can only speculate that the pyvenv.cfg stuff was load bearing on windows?

If that’s not it, someone with a windows machine needs to help.

/edit: e.g. @ofek, who just offered

flying-sheep commented 4 months ago

Looks good! I don’t think this timeout is caused by my code

flying-sheep commented 4 months ago

OK, pypy on windows fails with

125251 get interpreter info via cmd: 'C:\Users\runneradmin\AppData\Local\Temp\pytest-of-unknown\pytest-0\test_discovery_via_path_specif0\Scripts\somethingVeryCryptic3.10.exe' 'D:\a\virtualenv\virtualenv\.tox\pypy310\lib\site-packages\virtualenv\discovery\py_info.py' 2o7zKhwQ7RmUZlP1L7qYsRzWDWJd2Uc0 266eD4ebldJtJex0LCwbXGC040ZIuScj [DEBUG cached_py_info:112]
125280 failed to query C:\Users\runneradmin\AppData\Local\Temp\pytest-of-unknown\pytest-0\test_discovery_via_path_specif0\Scripts\somethingVeryCryptic3.10.exe with code 3221225781 [INFO cached_py_info:34]

I have absolutely no idea what “125280 failed to query …exe with code 3221225781” means, so I don’t think I can proceed here.