views:

897

answers:

2

I am messing around with the combination of buildout and virtualenv to setup an isolated development environment in python that allows to do reproducible builds.

There is a recipe for buildout that let's you integrate virtualenv into buildout:

 tl.buildout_virtual_python

With this my buildout.cfg looks like this:

[buildout]
develop = .
parts = script
        virtualpython


[virtualpython]
recipe = tl.buildout_virtual_python
headers = true
executable-name = vp
site-packages = false

[script]
recipe = zc.recipe.egg:scripts
eggs = foo
python = virtualpython

This will deploy to executables into ./bin/:

vp
script

When I execute vp, I get an interactive, isolated python dialog, as expected (can't load any packages from the system). What I would expect now, is that if I run

./bin/script

that the isolated python interpreter is used. But it doesn't, it's not isolated as "vp" is (meaning I can import libraries from system level). However I can run:

./bin/vp ./bin/script

Which will run the script in an isolated environment as I wished. But there must be a way to specify this to do so without chaining commands otherwise buildout only solves half of the problems I hoped :)

Thanks for your help! Patrick

A: 

I've never used that recipe before, but the first thing I would try is this:

[buildout]
develop = .
parts = script
        virtualpython


[virtualpython]
recipe = tl.buildout_virtual_python
headers = true
executable-name = vp
site-packages = false

[script]
recipe = zc.recipe.egg:scripts
eggs = foo
python = virtualpython
interpreter = vp

If that doesn't work, you can usually open up the scripts (in this case vp and script) in a text editor and see the Python paths that they're using. If you're on windows there will usually be a file called <script_name>-script.py. In this case, that would be vp-script.py and script-script.py.

Jason Baker
I also thought about using the "interpreter" option. If I do so, the code will break:djungle:buildout-test pbonzli$ ./bin/vp ./bin/vp: line 3: import: command not found./bin/vp: line 5: sys.path[0:0]: command not found etc... Perhaps a bug in the script, I don't know...
Patrick
+3  A: 

You don't need virtualenv: buildout already provides an isolated environment, just like virtualenv.

As an example, look at files buildout generates in the bin directory. They'll have something like:

import sys
sys.path[0:0] = [
     '/some/thing1.egg',
     # and other things
     ]

So the sys.path gets completely replaced with what buildout wants to have on the path: the same isolation method as virtualenv.

Reinout van Rees
The nice thing about virtualenv is it modifies the PATH so scripts can have "#!/usr/bin/env python" just like they're supposed to and they will use the buildout version. Is it possible to do this without virtualenv?
Xentac
virtualenv modifies the path, but that also means you should not *forget* to enable virtualenv every time you want to use the script. Buildout has a more permanent solution in that regard. And buildout points your script's "#!..." line at the real python your buildout was run with, so it is correct for your machine.Without virtualenv? You could write a shell script that sets the PYTHONPATH to something specific and get *some* of virtualenv's functionality. But not all, especially not when installing.
Reinout van Rees
Quick correction: `sys.path[0:0] = [...]` doesn't completely replace sys.path, it just inserts more items into the beginning of it.
Mu Mind
You're right. By default, buildout adds the things it wants on the path right at the front of the sys.path, but the existing path stays intact otherwise. So in that sense, virtualenv provides more isolation. Note that buildout 1.5 allows you to switch to a pure-isolation model.
Reinout van Rees