-
Notifications
You must be signed in to change notification settings - Fork 49
Description
virtualenv 1.10.1, at least the way we use it, creates the VE's bin directory with a python file and two symbolic links, python2 and python2.7, pointing to the python file. (Assuming one is using a 2.7 python.)
virtualenv-tools --reinitialize invokes virtualenv with -p /some/absolute/path/bin/python2.7
Amongst other fiddling, virtualenv copies the -p python to ve/bin/python2.7, apparently writing through the link, and replacing ve/bin/python. Then it decides to fix ve/bin/python and ve/bin/python2 by deleting them if they exist, and linking them to python2.7 (relative, so in ve/bin/). It starts with python, so now we have two symlinks pointing to one another. It then goes for python2, but since the target of that link doesn't exist as a file, os.path.exists says that ve/bin/python2 doesn't exist, so it skips unlinking it and goes right for the os.symlink call, which raises file exists, because there is something (the old link) at ve/bin/python2.
Granted, the virtualenv code is pretty weak, but it probably isn't maintained with the idea that it will be updating existing VEs. (Or if it is, that deserves a separate bug report.) But virtualenv-tools could be more defensive. One possibility is to hide (rename or move, for example) the existing ve/bin/python* files and links, discarding them if virtualenv successfully creates their replacements, and otherwise moving them back.