Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

completely self-contained virtual environment

I create a python3 virtual environment (explicitly avoiding symlinks, with --copies):

» python3 -m venv --without-pip --copies venv

This is my complete virtual environment now:

» tree venv/
venv/
├── bin
│   ├── activate
│   ├── activate.csh
│   ├── activate.fish
│   ├── python
│   └── python3
├── include
├── lib
│   └── python3.4
│       └── site-packages
├── lib64 -> lib
└── pyvenv.cfg

I disable the PYTHONPATH, to make sure nothing is leaking from outside:

» PYTHONPATH=""

Activate the venv:

» source venv/bin/activate

Verify that activate has not polluted my PYTHONPATH:

» echo $PYTHONPATH

(blank, as expected)

I am using the right python:

» which python
/foo/bar/venv/bin/python

But the system modules are still being accessed:

» python 
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import unittest
>>> print(unittest)
<module 'unittest' from '/usr/lib/python3.4/unittest/__init__.py'>
>>> 

I would expect the import unittest statement to fail, since the virtual environment has no such module.

I would like to know:

  • Why are system packages accessed when in a virtualenv?
  • How can I create a completely self-contained virtual environment?
like image 598
blueFast Avatar asked Jan 27 '16 10:01

blueFast


1 Answers

If I recall correctly the core system packages are symlinked, so they are the same files (partly to keep the size of the virtualenv down).

The default is not to include the site-packages directory, so it won't access 3rd party libraries that have been installed.

If you want to truly isolated and self-contained virtual environment, you might be better off looking at docker.

Virtualenv is really more of a lightweight way of managing different 3rd party installed packages for different apps.

EDIT:

It looks like --always-copy doesn't actually always copy all files:

virtualenv doesn't copy all .py files from the lib/python directory

Digging into the source and it looks like there's a smallish set of modules that are deemed to be "required" and these are the ones that are copied:

https://github.com/pypa/virtualenv/blob/ac4ea65b14270caeac56b1e1e64c56928037ebe2/virtualenv.py#L116

Edit 2:

You can see that the old python directories still appear in the sys.path, but after the directories for the virtualenv itself:

>>> import sys
>>> sys.path
['', '/home/john/venv/lib/python2.7', 
'/home/john/venv/lib/python2.7/plat-linux2', 
'/home/john/venv/lib/python2.7/lib-tk',
'/home/john/venv/lib/python2.7/lib-old', 
'/home/john/venv/lib/python2.7/lib-dynload', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/home/john/venv/local/lib/python2.7/site-packages',
'/home/john/venv/lib/python2.7/site-packages']
like image 153
John Montgomery Avatar answered Sep 22 '22 12:09

John Montgomery