I want to find the Python virtual environments ("venvs" for short) in my file system, and for this I need to know what set of files constitutes a venv.
Some tools - when they want to make sure a directory is a venv - check for the pyvenv.cfg file, but older virtual environments and environments created by Pipenv do not have this file. - Furthermore pyvenv.cfg does not seem to be necessary for activating the venv either.
So what is the minimal set of files to define a working virtual environment? And what is an easy way to check for this in Python?
Clarification:
With "working virtual environment" I mean:
A way to use a specific version of Python executable defined in that environment (and possibly different to the default system Python)
A way to use specific packages (usually installed via pip, bit that's not a requirement).
The Python executable in the venv should be aware of being run inside a venv (see
sys.base_prefix and sys.prefix in the Python documentation.)
Related
I need to make a fully self-contained Python environment for Mac, which can be transferred between different Macs running OSX and function independently of any other Python installations (or lack thereof).
In the enviroments I have created (using venv), I find that the /bin/python file and others are in fact aliases. When I replace these aliases with the original executables, the enviroment still does not work on other computers due references to files within a Python installation, such as
Library not loaded: /Library/Frameworks/Python.framework/Versions/3.9/Python
Is there a way to make the environment fully self-contained?
I would guess so, since tools such as pyinstaller and cx_freeze exist to make executables out of Python applications. So these must contain standalone environments somehow. But for my purposes, it is the enviroment that I need. Not an executable as these tools provide.
You can try using a virtual environment. Python comes with venv which allows you to create virtual environments. You could consider them self-contained, since all the necessary scripts for running Python are in the virtual environment. This goes with the package dependencies as well. You can have a variety of packages installed on your computer, but the virtual environment will have none of them installed (unless, of course, you install them yourself).
To create a virtual environment, run:
$ py -3.9 -m venv virtualenv
You can replace 3.9 with whichever Python version you are using and you can replace virtualenv with whatever you want to name your virtual environment.
To activate the virtual environment, you would run:
$ source virtualenv/Scripts/activate
And to deactivate it, you would run:
$ deactivate
When we want to do anything with our python virtual environment in terminal/command prompt/shell, we have to activate it by navigating to the scripts folder. But, what does this activation do?
I can access the contents of the virtualenv folder in file explorer without activating it.
At its core, the main purpose of Python virtual environments is to create an isolated environment for Python projects. This means that each project can have its own dependencies, regardless of what dependencies every other project has.
More interesting are the activate scripts in the bin directory. These scripts are used to set up your shell to use the environment’s Python executable and its site-packages by default.
After activating the environment, we’re now getting a different path for the python executable because, in an active environment, the $PATH environment variable is slightly modified.
I wanted to replace Python 3.8 32-bit with the 64-bit version to install the face_recognition module, so I deleted the previous version and tried to re-route the project to the new Python version by going to File > Settings > Project Interpreter > Show all > Show Paths for Selected Interpreter, and adding all the Python files from the new folder and getting rid of the old ones.
However, it's still showing me this error when I try to install the module:
(Will2.0) C:\Users\solei\PycharmProjects\Will>pip install face_recognition
No Python at 'C:\Users\solei\AppData\Local\Programs\Python\Python38-32\python.exe'
I've also tried going to the Windows System Properties and changing everything that says "Python38-32" there, but it's still not working. It does work when I make a new environment, though, so at least I know that Python installed properly. It's just this one environment that is tripping me up (I'd prefer not to make a new project for this, btw. I've already installed a lot of modules in it.).
Your selected interpreter is not the system interpreter you've replaced with the 64-bit version, but your project's virtual environment interpreter. The virtual environment's files weren't changed in that process and need to be updated before you can use that environment again.
The system interpreter is your Python interpreter installed using the installation executable. In your case it is located in C:\Users\solei\AppData\Local\Programs\Python\Python38\. You can have multiple system interpreters installed, such as having Python 2.7, Python 3.7 and Python 3.8 side-by-side.
The virtual environment interpreter is a copy of another interpreter created using the venv package from the Python standard library. You can have many virtual environments interpreters in the system (one or more for every project, for example)
The base interpreter is the interpreter that was used as a template for the venv package. Every virtual environment interpreter has its base interpreter (usually a system interpreter) that it requires to run. Changing or upgrading the base interpreter requires updating the virtual environment.
If we take a quick look at the documentation, a virtual environment is described as
a self-contained directory tree that contains a Python installation for a particular version of Python, plus a number of additional packages.
That means you can setup an individual environment for every project, which will contain its own packages. The environment is a very efficient way of managing project packages, that's why PyCharm suggests a creation of such environment over the system interpreter by default. In short, it allows you to have two different versions of the same package used by two different projects, without the packages conflicting with each other.
This also explains why your virtual environment files weren't affected by your upgrade.
Now, I am unfortunately no Python expert. I had to spend some time examining how Python handles virtual environments on Windows and Ubuntu. It seems the environment always requires the base system interpreter present in the system. If you remove or change the location of the base interpreter, the environment will fail to function.
As I mentioned before editing this answer, you can in theory simply edit the pyenv.cfg file located in the root folder of the virtual environment. In practice, that will only work in simple cases and it is not the intended way of updating virtual environments.
You need to upgrade your virtual environment's files to work with your new system interpreter. That can mean the 64-bit version over the 32-bit version, or even a newer version of Python - such us upgrading from 3.7 to 3.8.
Close PyCharm
Check if the system interpreter you want to upgrade to is on the system Path
You can quickly check by running
python -c "import platform; print(platform.architecture())"
For you, the output should look like this
('64bit', 'WindowsPE')
If your output is different, you'll need to prefix the absolute path to the Python executable in step 4).
Navigate to the virtual environment's directory
The directory you're looking for contains the Include, Lib and Scripts directories and the pyenv.cfg file. From your screenshots, it seems this directory is your project's root directory, so in your case:
cd C:\Users\solei\PycharmProjects\Will2.0\
Upgrade the virtual environment
python -m venv --upgrade .
... or if Python is not on your path
C:\Users\solei\AppData\Local\Programs\Python\Python38\python.exe -m venv --upgrade .
The . in the commands refers to the current directory.
Open PyCharm and verify your environment is working correctly
... or simply try to run pip directly from the command line. Note you need to first activate the virtual environment by running the Scripts\activate.bat batch file.
If the above-mentioned method doesn't work, you might have to create a new virtual environment. You can create one easily without making a new PyCharm project. See this PyCharm documentation for reference. However, you'll still need to redownload all the required packages again.
For the simplicity, I recommend creating the new virtual environment in a .venv folder located in the project's root.
Disclaimer
I tested only the Python's behavior alone on a fresh Windows installation inside the Windows Sandbox. I was able to install the 32-bit Python, create a virtual environment, replace Python with the 64-bit version and upgrade the virtual environment to have it launch correctly again.
I'm a huge beginner so I'm not very informed about how packages really work. I know that you should create a virtualenv in your project folder to avoid version conflicts etc, and you're not supposed to put your actual project files in the virtual env. So if your project files are in your project directory on the same level as the virtualenv, can your project files "access" the things installed in the virtualenv? Can files outside of your directory access packages in your virtual env?
Yes, it all depends on the context. Your virtualenv can exist anywhere, be it in your project directory, or somewhere else.
When you want to use the virtualenv, you just have to call source command on it. Then whatever python command you execute on whichever file, will have access to the virtualenv. For example, if you store your virtualenv in /home/user/project/virtualenv, then you would do
source /home/user/project/virtualenv/bin/activate
Then whatever you with the python, it would be the version installed in virtualenv.
You can double check if you're using the global python or the virtualenv python by doing which python. It will either point to the global python path which is usually under /usr/bin/python or /home/user/project/virtualenv/bin/python.
So normally, you first do the source command, then you can do pip install on whatever packages you need already. It will be installed in the virtualenv and it will not conflict with other projects.
Using Python 3.7.0 on Mac. Trying to use venv module that was added post python 3.4.
I setup my virtual env using python3 venv -m path/to/my/dir - my question is do I need to activate this virtual env to use?
The documentation seem to imply I don't need to?
You don’t specifically need to activate an environment; activation just prepends the virtual environment’s binary directory to your path, so that “python” invokes the virtual environment’s Python interpreter and you can run installed scripts without having to use their full path. However, all scripts installed in a virtual environment should be runnable without activating it, and run with the virtual environment’s Python automatically.
If I don't have to activate, what is the benefit of prepending venv to binary directory? Wouldn't this have to happen regardless for a venv to work?
Activating the virtualenv gives you convenience. It is never required.
Even for scripts that are configured to run with #!/usr/bin/env python, (which looks up the python executable on your path), you could manually update the PATH environment variable:
$ PATH="/path/to/venv/bin" some_script
Activating makes the PATH update stick until you deactivate again, and that can be convenient.
For example, I regularly have several virtualenvs in use at any one time. Some of them are there only to install some command-line tools I have symlinked into my ~/bin/ directory, another is home to a Jupyter notebook, and 2 more are used to quickly verify code snippets in different Python versions with access to 3rd-party libraries. I don't activate any of those.
When you don’t activate a virtualenv, all that happens is that your terminal PATH variable is not updated to put the bin directory of the virtualenv first, so when you enter python or pip or other script without any path into the terminal, the shell will find a different Python binary to run. You can always use any of the commands in the virtualenv bin/ directory by giving the full path to that command.