pythonfinder icon indicating copy to clipboard operation
pythonfinder copied to clipboard

Executing from a venv does not find the venv's Python

Open TBBle opened this issue 1 year ago • 0 comments

Reproduction on Windows: No Python versions in PATH, running under PowerShell 7.4.1. All testing is pythonfinder 2.1.0

> py -3 -m venv pythonfinder
> cd pythonfinder
> .\Scripts\Activate.ps1
> python -m pip install --upgrade pip
# pip output...
> pip install --quiet --upgrade "pythonfinder[cli]" && pyfinder --findall
ERROR: No valid python versions found! Check your path and try again.
Please provide a command

A quick check shows this is not CLI-related (as I had originally thought, hence the investigation order):

> python
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pythonfinder import Finder
>>> finder = Finder(ignore_unsupported=True)
>>> finder.find_all_python_versions()
[]
>>> import os
>>> os.environ["PATH"]
'C:\\Users\\paulh\\ttt\\pythonfinder\\Scripts;<...>'
>>> finder.which("python")
PathEntry(is_root=False, name='python.exe', path=WindowsPath('C:/Users/paulh/ttt/pythonfinder/Scripts/python.exe'), children_ref={}, only_python=False, py_version_ref=PythonVersion(major=3, minor=10, patch=11, is_prerelease=False, is_postrelease=False, is_devrelease=False, is_debug=False, version=<Version('3.10.11')>, architecture=None, comes_from=..., executable='C:\\Users\\paulh\\ttt\\pythonfinder\\Scripts\\python.exe', company=None, name='python.exe'), pythons_ref=defaultdict(<function PathEntry.<lambda>.<locals>.<lambda> at 0x00000209067B8820>, {}), is_dir_ref=False, is_executable_ref=True, is_python_ref=True)
>>> ^Z

Critically, C:\Users\paulh\ttt\pythonfinder\Scripts does contain python.exe and pythonw.exe, and finder.which can see the venv's python.exe, so it's odd that finder.find_all_python_versions does not report it.

This behaviour differs from py, which does prefer the Python version in the venv:

> py
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.prefix
'C:\\Users\\paulh\\ttt\\pythonfinder'
>>> sys.base_prefix
'C:\\Program Files\\Python310'
>>> ^Z

The same behaviour is observed if I don't activate the venv, but directly execute python.exe or pythonfinder.exe from the venv in a new shell.

> .\Scripts\python.exe
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.prefix
'C:\\Users\\paulh\\ttt\\pythonfinder'
>>> sys.base_prefix
'C:\\Program Files\\Python310'
>>> from pythonfinder import Finder
>>> finder = Finder(ignore_unsupported=True)
>>> finder.find_all_python_versions()
[]
>>> finder.which("python")
>>> ^Z
> .\Scripts\pyfinder.exe --findall
ERROR: No valid python versions found! Check your path and try again.
Please provide a command

However, in this case, even finder.which doesn't find python.exe, which suggests that venv are not being handled correctly. And indeed, a quick code-check shows that venv handling relies on an env-var check but that only works for explicitly activated venvs, not implicitly activated venvs.

See https://docs.python.org/3/library/venv.html#how-venvs-work with more details including Python older than 3.3 at https://stackoverflow.com/a/1883251/166389.


Quick test of the initial repro on my at-hand WSL install:

paulh@KEITARO:~/ttt$ python3 -m venv pythonfinder
paulh@KEITARO:~/ttt$ cd pythonfinder/
paulh@KEITARO:~/ttt/pythonfinder$ source bin/activate
(pythonfinder) paulh@KEITARO:~/ttt/pythonfinder$ pip3 install --quiet --upgrade "pythonfinder[cli]" && pyfinder --findall
ERROR: No valid python versions found! Check your path and try again.
Please provide a command
(pythonfinder) paulh@KEITARO:~/ttt/pythonfinder$ python
Python 3.8.10 (default, Nov 22 2023, 10:22:35)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pythonfinder import Finder
>>> finder = Finder(ignore_unsupported=True)
>>> finder.find_all_python_versions()
[]
>>> import os
>>> os.environ["PATH"]
'/home/paulh/ttt/pythonfinder/bin:<...>'
>>> finder.which("python")
PathEntry(is_root=False, name='python', path=PosixPath('/home/paulh/ttt/pythonfinder/bin/python'), children_ref={}, only_python=False, py_version_ref=PythonVersion(major=3, minor=8, patch=10, is_prerelease=False, is_postrelease=False, is_devrelease=False, is_debug=False, version=<Version('3.8.10')>, architecture=None, comes_from=..., executable='/home/paulh/ttt/pythonfinder/bin/python', company=None, name='python'), pythons_ref=defaultdict(<function PathEntry.<lambda>.<locals>.<lambda> at 0x7fb5c37fa3a0>, {}), is_dir_ref=False, is_executable_ref=True, is_python_ref=True)
>>> finder.which("python3")
PathEntry(is_root=False, name='python3', path=PosixPath('/home/paulh/ttt/pythonfinder/bin/python3'), children_ref={}, only_python=False, py_version_ref=PythonVersion(major=3, minor=8, patch=10, is_prerelease=False, is_postrelease=False, is_devrelease=False, is_debug=False, version=<Version('3.8.10')>, architecture=None, comes_from=..., executable='/home/paulh/ttt/pythonfinder/bin/python3', company=None, name='python3'), pythons_ref=defaultdict(<function PathEntry.<lambda>.<locals>.<lambda> at 0x7fb5c3886940>, {}), is_dir_ref=False, is_executable_ref=True, is_python_ref=True)
>>>

so this ones's not actually Windows-specific, and even fails to pick up the system-installed Python? (I tried passing system=True to the Finder constructor, but it still outputs nothing...)

TBBle avatar Apr 01 '24 02:04 TBBle