Prody
Prody

Reputation: 5298

How to find a module in a virtualenv without activating said virtualenv?

Suppose I have the following setup:

mkdir test && cd test
virtualenv .venv
source .venv/bin/activate
pip install django
mkdir mod1
touch mod1/__init__.py
echo "a = 1" > mod1/mod2.py

Which gives me:

test/.venv
test/mod1/__init__.py
test/mod1/mod2.py

How would I write this function:

def get_module(module_name, root_path, virtualenv_path=None)

In order for this to work:

project_root_path = "./test"
project_virtualenv_path = "./test/.venv"

get_module("mod1.mod2", project_root_path, project_virtualenv_path)
get_module("django.contrib.auth", project_root_path, project_virtualenv_path)

Assuming I don't have ./test/.venv activated.

The reason I want to do this, is because I'm working on a vim plugin which would implement gf functionality in a python file on an import statement. I'm trying to support virtualenvs as well.

EDIT:

Also, the script should not alter the current runtime, by adding or appending to sys.path. This should run inside vim, via the vim python bindings, and I don't think altering the vim python runtime would be a good idea.

get_module could either return a module object, or the path to the module, which is what I'm basically looking for.

Upvotes: 3

Views: 260

Answers (2)

Prody
Prody

Reputation: 5298

The only practical solution I could find here is to run the virtualenv's activate_this.py script, look for what I need, then remove it's changes from sys.path.

import sys
import os

old_sys_path = list(sys.path)

virtualenv_path = "/path/to/venv"
activate_this_path = os.path.join(virtualenv_path, "bin", "activate_this.py")

execfile(activate_this_path, dict(__file__=activate_this_path))

# get my module here

# restore sys.path
sys.path = old_sys_path

If you have a better answer, please add it, and I'll change the accepted answer gladly.

Upvotes: 0

iblazevic
iblazevic

Reputation: 2733

You can add your virtualenv on python path like:

import site 
site.addsitedir('/home/user/.virtualenvs/myapp1/lib/python2.7/site-packages')

and then import should work

Upvotes: 3

Related Questions