Everything below runs in virtual environment. I have a script that performs an import to the netifaces module. the package appears in pip list When I run it in interactive mode, it does the import without problems, but when I run it as a script, it fails.
Simple version of the script:
import socket # Import socket module
import netifaces
print("Hello")
Capturing messages in the terminal:
Package Version
--------------------------------- -------
backports.entry-points-selectable 1.1.1
distlib 0.3.3
filelock 3.3.2
ipaddress 1.0.23
netaddr 0.8.0
netifaces 0.11.0
pip 21.3.1
platformdirs 2.4.0
pyasn1 0.4.8
pysmb 1.2.7
setuptools 58.5.3
virtualenv 20.10.0
wheel 0.36.2
(venv) C:\Temp_C_10\Proyectos\PruebasSMB>py
Python 3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> import netifaces
>>> print("hello")
hello
>>> quit()
(venv) C:\Temp_C_10\Proyectos\PruebasSMB>py test.py
Traceback (most recent call last):
File "C:\Temp_C_10\Proyectos\PruebasSMB\test.py", line 10, in <module>
import netifaces
ModuleNotFoundError: No module named 'netifaces'
(venv) C:\Temp_C_10\Proyectos\PruebasSMB>
What am I doing wrong? What am I missing? What don't I just understand?
I edit and add information, as recommended:
It seems that I have found the cause, although I do not fully understand it. If anyone can give me more information I would appreciate it.
I have added to the program, which prints sys.path. Launching the script as py test.py, sys.path doesn't pick up the virtual environment, which it does when launching it as python test.py.
A virtual environment is nothing more than a folder that contains a python interpreter, an executable
pip
, the basic libraries for python to work, and any additional libraries you've installed withpip
that environment.Once you have created the environment (for example by typing
python -m venv prueba
) you will see that a folder with that name appears (prueba
) and if you enter it you will see an entire Python installation, made up of folders such asbin
,lib
,include
, etc...In particular, it is inside the folder
bin
(prueba/bin
in the example) where the interpreterpython
and the executablepip
are, among other things.Normally the next step is to "activate" the virtual environment, but this is really just an optional step to make it more comfortable to handle.
Even without activating it, it can be used if whenever you run python you make sure you are running the one in the environment (ie
prueba/bin/python
) and if whenever you want to install new packages you make sure to use thepip
one in that environment (ieprueba/bin/pip
).On launch, the python executable finds out what path (folder) it is saved in, and prepares
sys.path
accordingly. So if you run the python inside the virtual environment itsys.path
will contain paths to that environment, but if you run thepython
one outside (the system python), it won't.All the script does
activate
is modify your environment variablePATH
to add the path in frontprueba/bin
of it and that way you can just writepython
and it will run the one inprueba/bin
without specifying the full path to it.I suspect that in your case use
py
causes the "system" python to run instead of the virtual environment python. This is because there is no command inside the virtual environmentprueba/bin/py
, so it will jump to the next element in the PATH until it finds it.If you have doubts about what exactly is the python that is going to be executed by putting
python
"plain" (or puttingpy
opip
or any other command), you can use the commandwhich python
in linux (in windows I think it would bewhere python
) that prints the path to the executable to be used.