fredrik
fredrik

Reputation: 10281

Creating virtualenv without symlinks

I'd like to create a virtualenv which does not use symlinks to the local system, as I wish to bundle the virtualenv (including third party packages) with my application. Is this possible - and if so, how?

For example, on my Mac OS X 10.10.2, any virtualenv I create contains the symlink:

.Python -> /System/Library/Frameworks/Python.framework/Versions/2.7/Python

If I create my virtualenv directly on a network server share with --always-copy I get an error:

$ virtualenv --always-copy python2.7.9_win7-64_stalker0.2.13
New python executable in python2.7.9_win7-64_stalker0.2.13/bin/python
Traceback (most recent call last):
  File "/usr/local/bin/virtualenv", line 11, in <module>
    sys.exit(main())
  File "/Library/Python/2.7/site-packages/virtualenv.py", line 825, in main
    symlink=options.symlink)
  File "/Library/Python/2.7/site-packages/virtualenv.py", line 985, in create_environment
    site_packages=site_packages, clear=clear, symlink=symlink))
  File "/Library/Python/2.7/site-packages/virtualenv.py", line 1374, in install_python
    symlink)
  File "/Library/Python/2.7/site-packages/virtualenv.py", line 482, in copyfile
    copyfileordir(src, dest, symlink)
  File "/Library/Python/2.7/site-packages/virtualenv.py", line 456, in copyfileordir
    shutil.copy2(src, dest)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 131, in copy2
    copystat(src, dst)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 103, in copystat
    os.chflags(dst, st.st_flags)
OSError: [Errno 22] Invalid argument: 'python2.7.9_win7-64_stalker0.2.13/.Python'

Upvotes: 11

Views: 14271

Answers (2)

Andrey Semakin
Andrey Semakin

Reputation: 2775

With Python 3 and venv module, one can create a "thick" virtual environment without symlinks using --copies flag:

$ python -m venv --copies thick_venv
$ ls -l thick_venv/bin/
total 36836
-rw-r--r--. 1 br0ke br0ke     2230 May 19 17:54 activate
-rw-r--r--. 1 br0ke br0ke     1282 May 19 17:54 activate.csh
-rw-r--r--. 1 br0ke br0ke     2434 May 19 17:54 activate.fish
-rw-r--r--. 1 br0ke br0ke     8832 May 19 17:54 Activate.ps1
-rwxr-xr-x. 1 br0ke br0ke      266 May 19 17:54 easy_install*
-rwxr-xr-x. 1 br0ke br0ke      266 May 19 17:54 easy_install-3.8*
-rwxr-xr-x. 1 br0ke br0ke      248 May 19 17:54 pip*
-rwxr-xr-x. 1 br0ke br0ke      248 May 19 17:54 pip3*
-rwxr-xr-x. 1 br0ke br0ke      248 May 19 17:54 pip3.8*
-rwxr-xr-x. 1 br0ke br0ke 18833904 May 19 17:54 python*
-rwxr-xr-x. 1 br0ke br0ke 18833904 May 19 17:54 python3*

As you can see, it copies the interpreter into the virtual environment (twice). And here is an example of usual virtual environment with symlinks:

$ python -m venv thin_venv
$ ls -l thin_venv/bin/
total 44
-rw-r--r--. 1 br0ke br0ke 2227 May 19 17:54 activate
-rw-r--r--. 1 br0ke br0ke 1279 May 19 17:54 activate.csh
-rw-r--r--. 1 br0ke br0ke 2431 May 19 17:54 activate.fish
-rw-r--r--. 1 br0ke br0ke 8832 May 19 17:54 Activate.ps1
-rwxr-xr-x. 1 br0ke br0ke  265 May 19 17:54 easy_install*
-rwxr-xr-x. 1 br0ke br0ke  265 May 19 17:54 easy_install-3.8*
-rwxr-xr-x. 1 br0ke br0ke  247 May 19 17:54 pip*
-rwxr-xr-x. 1 br0ke br0ke  247 May 19 17:54 pip3*
-rwxr-xr-x. 1 br0ke br0ke  247 May 19 17:54 pip3.8*
lrwxrwxrwx. 1 br0ke br0ke   50 May 19 17:54 python -> /home/br0ke/.asdf/installs/python/3.8.3/bin/python*
lrwxrwxrwx. 1 br0ke br0ke    6 May 19 17:54 python3 -> python*

Upvotes: 20

Mekk
Mekk

Reputation: 1459

Mayhaps try solving bigger problem (of sensibly packaging) instead of tweaking virtualenv internals?

For example take a look at http://platter.pocoo.org/ or mayhaps at http://cx-freeze.sourceforge.net/ (I am not sure which scenario you mean).

Upvotes: -1

Related Questions