Skip to content

Instantly share code, notes, and snippets.

@emptypage
Last active August 29, 2015 14:15
Show Gist options
  • Save emptypage/3864475e514305d5cb38 to your computer and use it in GitHub Desktop.
Save emptypage/3864475e514305d5cb38 to your computer and use it in GitHub Desktop.
Create hard links / junctions to the system-installed packages in a given virtualenv ("site-packages") directory.
#!/usr/bin/env python
#
# Create hard links / junctions to the system-installed packages in
# a given virtualenv ("site-packages") directory.
#
#
# Background
# ==========
#
# Some libraries such as wxPython do not support pip installation yet.
# It makes hard for develpers to develop Python softwares under the
# virtualenv environment. This script may help you with such issues.
#
#
# Example
# =======
#
# C:\work>virtualenv venv
# ...
# C:\work>redirect-package.py venv wx
# ...
# C:\work>venv\Scripts\activate.bat
# (venv) C:\work>python
# ...
# >>> import wx
# >>>
#
# (You can import system-installed wxPython in the virtualenv interpreter.)
#
#
# Requirements
# ============
#
# * Python 2.7 or later
#
# NOTE: It works on POSIX platforms as well as on Windows now.
#
#
# License
# =======
#
# This program is in the public domain.
from __future__ import (absolute_import,
division,
print_function,
unicode_literals)
import argparse
import imp
import os
import subprocess
def virtualenv_sys_version(dir_venv):
if os.name == 'nt':
python = os.path.join(dir_venv, 'Scripts', 'python.exe')
else:
python = os.path.join(dir_venv, 'bin', 'python')
output = subprocess.check_output(
[python, '-c', 'import sys; print(sys.version)']
) # get 'X.Y.Z (...)'
return output
def virtualenv_site_packages_dir(dir_venv):
if os.name == 'nt':
paths = [dir_venv, 'Lib', 'site-packages']
else:
sys_version = virtualenv_sys_version(dir_venv)
pythonXY = 'python%s.%s' % tuple(sys_version.split('.')[:2])
paths = [dir_venv, 'lib', pythonXY, 'site-packages']
site_packages_dir = os.path.join(*paths)
return site_packages_dir
def create_module_link(source, link_name):
if os.name == 'nt':
os.system('mklink /h "%s" "%s"' % (link_name, source))
elif os.name == 'posix':
os.link(source, link_name)
def create_package_link(source, link_name):
if os.name == 'nt':
os.system('mklink /j "%s" "%s"' % (link_name, source))
elif os.name == 'posix':
os.symlink(source, link_name)
def main():
parser = argparse.ArgumentParser(
description='Redirect packages to virtualenv'
)
parser.add_argument('venv')
parser.add_argument('packages', nargs='+')
args = parser.parse_args()
dest = virtualenv_site_packages_dir(args.venv)
for package in args.packages:
fileobj, dirname, desc = imp.find_module(package)
if fileobj:
filename = fileobj.name
link_name = os.path.join(dest, os.path.basename(filename))
create_module_link(filename, link_name)
else:
link_name = os.path.join(dest, os.path.basename(dirname))
create_package_link(dirname, link_name)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment