I'm not understanding how my Python script and library are using the venv. I create the library with python -m venv .venv
, then poetry add
everything, and finally poetry publish
. Therefore the library contains its own .venv
. On the other hand, for my script I do python -m venv .venv
, then pip install <library>
into the script's own .venv
. I don't believe this poetry
vs. pip
difference should be causing my issue, but I'm highlighting it for context.
So I run the script with .venv\Scripts\python.exe my_script.py
. Afaik, that's all that's needed to run my script inside its venv, ie. I don't actually have to run .venv/Scripts/activate
or anything else. This appears to work fine, because I can see my script is using the library installed in its venv. However, the library itself is not using the venv's python.exe
or its libraries.
I've only noticed this now due to an exception that happened today. Please ignore the PermissionError
itself, it's actually expected because today the destination file was open at the time. However, it revealed what I believe is either an issue with my setup or a misunderstanding on my part:
2022-03-07 09:13:36,364 ERROR [Errno 13] Permission denied: '\\\\path\\to\\file\\I\\wanted\\to\\overwrite.pdf' (files.py:36)
Traceback (most recent call last):
File "c:\Users\<user>\<project folder>\.venv\lib\site-packages\<library>\file_system\files.py", line 33, in copy_file
shutil.copyfile(source, destination)
File "C:\Users\<user>\AppData\Local\Programs\Python\Python39\lib\shutil.py", line 266, in copyfile
with open(dst, 'wb') as fdst:
PermissionError: [Errno 13] Permission denied: '\\\\path\\to\\file\\I\\wanted\\to\\overwrite.pdf'
As you can see, my script correctly resorts to the library in the .venv
(in fact this library has never been installed system-wide so it really has no choice). My library uses shutil
to copy the file. However, it is not resorting to the shutil
inside the script's .venv
, but rather the system-wide Python installation, as seen here:
File "C:\Users\<user>\AppData\Local\Programs\Python\Python39\lib\shutil.py", line 266, in copyfile
I suppose that since shutil
is part of Python's standard library, it found the general one before it found the shutil
in the venv? Is there a way to tell my script/library to use the shutil
in the .venv
? Is there even an shutil
in the .venv
?? When I browse .venv\Lib\site-packages
, I don't see any shutil
there, but then again I don't see any of Python's standard modules either (eg. os, logging, etc.) so I'm not surprised. But how do I force my script to use the shutil
in its .venv
instead of the shutil
from the system's Python? Is it a matter of reordering or removing the system Python from PATH?
Thanks
This seems like normal behavior to me. The standard library is not copied in the virtual environment. The python.exe
in the virtual environment needs and uses the standard library of the Python interpreter used to create the virtual environment.
Each virtual environment has its own Python binary (allowing creation of environments with various Python versions) and can have its own independent set of installed Python packages in its site directories, but shares the standard library with the base installed Python.
-- "Abstract" section of PEP 405
See also: