I am writing a small app to list the packages available in pip. Mostly it is to learn some new code but also to build a tool to help me “diff” between the global and venv list of packages.
I have been looking around for a safe way to determine if my code is running inside a venv or not.
Is it safe enough to test to see of os.environ has a ‘VIRTUAL_ENV’ key? The other idea I had was to test to see if the path in pip --version was a relative of any of the paths in the sys.paths.
There is a lot of tips online about using sys.base_prefix but that only works if the python version is different in the venv. If it isn’t then you are SOL with that technique
The most important effect of a venv is to change sys.path, so you should be able to look for that. I’m not sure how to be 100% sure of whether it’s a venv or something else, but the path entries themselves are probably the most important thing in looking for your list of packages anyway.
You could also possibly check sys.executable but I’d be inclined to use sys.path for preference.
If I were you I would study the corresponding specification, or the PEP which is the next best thing: PEP 405 – Python Virtual Environments. Also I think this question has already been asked more than once, but it is true that chances are high that the answers are less than optimal. And in that spirit I will try my luck with my version of a probably less than optimal answer…
I think I would get the value of sys.executable and check:
If a pyvenv.cfg file is found either adjacent to the Python executable or one directory above it […], this file is scanned for lines of the form key = value. If a home key is found, this signifies that the Python binary belongs to a virtual environment […].
I did a search before posting and didn’t find anything directly related but that is the peril of search terms I guess.
I have been looking through the docs but mostly wanted to check to see if there was just something obvious I was missing.
My current plan is to get the results from pip -V and then check the path there against the sys.path entries but I want to cover all the bases in terms of possible venv locations and names.