vim-virtualenv icon indicating copy to clipboard operation
vim-virtualenv copied to clipboard

sys.path entries get erased by :VirtualEnvDeactivate in particular scenario

Open solovyevn opened this issue 9 years ago • 5 comments

Note: I use pyvenv for virtual environments, I don't know if the same problem occurs for virtualenv users.

The issues is probably related to how the sys.path is handled for activation and deactivation of virtual environment. The vim-virtualenv plugin is not always run/initialized first relative to other plugins (that may also modify sys.path), but it looks like :VirtualEnvDeactivate command's code assumes, that the venv's site-packages entry is the first in sys.path. This leads to some entries being erased from the path, when the command is run. See example and actions to repeat the issue below.

Scenario 1 (starting vim when venv is already active, the path gets erased):

  1. I activate virtual environment in bash;
  2. Run vim somefile.py;
  3. In vim I check sys.path by running :python import sys; print(sys.path);
  4. The path is a long list, WITH directories for YouCompleteMe and my virtual environment site-packages somewhere in the middle;
  5. Then, in vim I run :VirtualEnvDeactivate;
  6. And I check sys.path again by running :python import sys; print(sys.path);
  7. The path is a very short list WITHOUT directories for YouCompleteMe, and, of course, without the directory for venv's site-packages;
  8. If I run :VirtualEnvActivate venv_name, and check sys.path again there're no directories for YouCompleteMe, and the directory for venv's site-packages is the first in the list.

Scenario 2 (manual virtual environment activation in vim, works as expected):

  1. No virtual environment is active, and I run vim somefile.py;
  2. In vim I check sys.path by running :python import sys; print(sys.path);
  3. The path is a long list WITH directories for YouCompleteMe, and, of course, without the directory for venv's site-packages;
  4. I run :VirtualEnvActivate venv_name, and check sys.path again;
  5. The path is a long list WITH directories for YouCompleteMe, and the directory for venv's site-packages is the first in the list;
  6. Then, in vim I run :VirtualEnvDeactivate, and check sys.path again;
  7. The path is a long list WITH directories for YouCompleteMe, and, of course, without the directory for venv's site-packages.

solovyevn avatar May 13 '16 16:05 solovyevn

The reason is that sys.path is saved prior to modification, and restored after deactivation. If another plugin or script uses the same strategy or modifies it, those changes would get lost. I'm open to suggestions on how this can be handled better.

jmcantrell avatar May 16 '16 00:05 jmcantrell

What about this. The plugin can save the site-packages path that gets added during activation. On deactivation, remove the matching path from sys.path with something like remove(index(sys_path, site_pkg))

jmcantrell avatar May 16 '16 00:05 jmcantrell

I'm sorry, I didn't have time to look through the code, so I just posted it as an issue I came across, and not the pull request. Your proposed solution looks like a good idea, it will work for any posistion in the sys.path and doesn't affect any other plugins. Guess it can be simplified to sys.path.remove(site_pkg).

solovyevn avatar May 16 '16 07:05 solovyevn

Nice one. Thanks!

jmcantrell avatar May 19 '16 02:05 jmcantrell

No problem! )

solovyevn avatar May 19 '16 07:05 solovyevn