Search code examples
pythonwindowsvirtualenvsetuptools

Running a python installed script within a virtual environment looks for the global Python installation


I've just set up a new Windows 10 machine with Python and now I'm facing a weird behavior I'm unable to understand and fix (it's always been working fine with other machines).

I have a Python project with the following structure:

fooProject/
├─ foo_package/
│  ├─ __init__.py
│  ├─ mymodule.py
├─ scripts/
│  ├─ myscript.py
setup.py

Here's the content of my setup.py file:

from setuptools import setup, find_packages

setup(
    name="foo",
    version="0.0.1",
    description="Test package and script",
    packages=find_packages(),
    include_package_data=True,
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Topic :: Utilities",
        "License ::",
    ],
    scripts=['scripts/myscript.py']
)

I want to be able to call the script from anywhere on my machine, so I create a virtual environment (virtualenv venv), activate it and install the package (python setup.py install).

This is something I've been used to do for a long time now, but on this machine I have the following error when I run the script myscript.py (from anywhere):

(venv) C:\Users\onedey\PycharmProjects\fooProject>myscript.py Traceback (most recent call last):

File "C:\Users\onedey\PycharmProjects\fooProject\venv\Scripts\myscript.py", line 4, in <module> import('pkg_resources').run_script('foo==0.0.1', 'myscript.py')

File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init_.py", line 3243, in <module> def initialize_master_working_set():

File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init.py", line 3226, in call_aside f(*args, **kwargs)
File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init.py", line 3255, in initialize_master_working_set working_set = WorkingSet.build_master()
File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init.py", line 568, in build_master ws.require(requires)
File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init.py", line 886, in require needed = self.resolve(parse_requirements(requirements))
File "C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages\pkg_resources_init.py", line 772, in resolve raise DistributionNotFound(req, requirers)

pkg_resources.DistributionNotFound: The 'foo==0.0.1' distribution was not found and is required by the application

As you can see, myscript.py is found inside the venv/Scripts folder as expected, but then the package foo is searched in my global installation folder (C:\Users\onedey\AppData\Local\Programs\Python\Python38\lib\site-packages)

I've tried searching for similar issues but found nothing.

At first the .py extension was not associated to a program (therefore it was not launching), so I associated it to the global Python 3.8 installation.

I also tried to configure some environment variables - I think PYTHONHOME and PYTHONPATH - I had very weird results so I removed them.

I also checked that calling python in the virtual env is calling the right python:

(venv) C:\Users\onedey\PycharmProjects\fooProject>python
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.executable
'C:\\Users\\onedey\\PycharmProjects\\fooProject\\venv\\Scripts\\python.exe'

I've tried also the commands provided in this post (Why does subprocess.popen, when run in virtual environment, find the global python executable?) and indeed I get the second behavior:

(venv) C:\Users\onedey\PycharmProjects\fooProject>python
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, os, subprocess
>>> sys.executable
'C:\\Users\\onedey\\PycharmProjects\\fooProject\\venv\\Scripts\\python.exe'
>>> args = ["python", "-c", "import sys; print(sys.executable)"]
>>> p = subprocess.Popen(args, stdout=None, env=os.environ)
>>> C:\Users\onedey\AppData\Local\Programs\Python\Python38\python.exe

Solution

  • After reinstalling and modifying Python38 multiple times (at C:\Python38 directly this time), and trying different solutions, I finally was able to fix the issue somehow.

    Here's a few related issues that might help others with the same issue:

    The last thing I did was:

    1. Setting again assoc .py=Python.File which corresponds to the Python Launcher (it was already like this before, but I had changed it in between with the solution proposed at https://stackoverflow.com/a/67894642/13123426 which did not work for me).

    At this point, this was still not working, the cmd kept asking me which program I wanted to use, then I got a flashing window (script opening then window closing at the end).

    1. Right-click on any python script, then choose "Open with" and select "Python Launcher"

    2. Open cmd again, activate my virtual env, python myscript.py works finally !

    The weird thing is that I always checked "associate .py files" in the Python installer, as well as "install pylauncher"...