Welcome, guest | Sign In | My Account | Store | Cart

Distutil's bdist_wininst installers offer uninstallation support for Python extensions, many developers however only distribute sources in zip or tar.gz format. The typical steps to install such a distribution are: - download the file - unpack with winzip into a temporary directory - open a command prompt and type 'python setup.py install' - remove the temporary directory

This script unpacks a source distribution into a temporary directory, builds a windows installer on the fly, executes it, and cleans everything up afterward.

Python, 71 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""This script unpacks a source distribution into a temporary
directory, builds a windows installer on the fly, executes it, and
cleans everything up afterward.

You could create a shortcut to this script on the desktop by simply
dragging it there, then you can drag'n drop zip or tar.gz files onto
it."""

import sys, os, zipfile, tempfile
from distutils.dir_util import mkpath, remove_tree

try:
    # Use Lars Gustaebel's tarfile module, if available:
    # http://www.gustaebel.de/lars/tarfile/
    # Needs version 0.3.3 (or higher?)
    import tarfile
    tarfile.is_tarfile
    tarfile.TarFileCompat
except (ImportError, AttributeError):
    tarfile = None

def create_file(pathname, data):
    mkpath(os.path.dirname(pathname))
    file = open(pathname, "wb")
    file.write(data)
    file.close()

def extract(distro):
    dir = tempfile.mktemp()
    if zipfile.is_zipfile(distro):
        file = zipfile.ZipFile(distro)
    elif tarfile and tarfile.is_tarfile(distro):
        file = tarfile.TarFileCompat(distro, "r", tarfile.TAR_GZIPPED)
    else:
        if tarfile:
            raise TypeError, "%r does not seem to be a zipfile or tarfile" % distro
        else:
            raise TypeError, "%r does not seem to be a zipfile" % distro
    os.mkdir(dir)
    for info in file.infolist():
        if info.filename[-1] != '/':
            data = file.read(info.filename)
            create_file(os.path.join(dir, info.filename), data)
    return dir

def install():
    if len(sys.argv) != 2:
        raise Exception, "Usage: python install.py <zip-or-tar.gz file>"
    distro = sys.argv[1]
    dir = extract(distro)
    print "Extracted to", dir
    import glob
    setup_files = glob.glob(os.path.join(dir, "*", "setup.py"))
    if len(setup_files) != 1:
        raise Exception, "Could not determine setup script to use"
    setup_file = setup_files[0]
    os.chdir(os.path.dirname(setup_file))
    print "Building windows installer..."
    os.system("%s %s -q bdist_wininst" % (sys.executable, setup_file))
    print "Running windows installer..."
    exe_file = glob.glob("dist/*.exe")[0]
    os.system(exe_file)
    print "Removing", dir
    remove_tree(dir)

if __name__ == '__main__':
    try:
        install()
    except Exception, detail:
        print detail
    raw_input("Press return to exit...")

You should probably create a shortcut to this script on your desktop, then you can simply install source distributions by dragging and dropping them to the shortcut.

Version 1.1: I've cleaned up the code somewhat, and corrected the link pointing to the tarfile module. Version 1.3: The tarfile-module's api changed, so currently there are some problems. Version 1.4: Lars provided a compatible interface in his tarfile module, which I now use. Many thanks to him!