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

This script takes advantage of PEP 370, "Per user site-packages directory". It manages .pth files, which are are non-volatile (unlike manually adding to sys.path). See http://docs.python.org/library/site.html.

Python, 88 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""Adds a directory to sys.path, permanently.

"""

import sys
import os
import site

HEADER = """\
# .pth file created by the pypath script.
# edit at your own risk
"""

SITEDIR = site.getusersitepackages()
PATH = os.path.join(SITEDIR, "pypath.pth")

if not os.path.exists(SITEDIR):
    os.mkdirs(SITEDIR)


def add(path, pth_file=None):
    path = path.strip()
    pth_file = pth_file or PATH
    if not os.path.exists(path):
        raise ValueError("doesn't exist: {}".format(path))
    with open(pth_file, "r") as f:
        for line in f:
            if line.strip(os.linesep) == path:
                # already added
                return
        empty = not f.tell()
    with open(pth_file, "a") as f:
        if empty:
            f.write(HEADER)
        f.write(os.linesep + path)


def remove(path, pth_file=None):
    pth_file = pth_file or PATH
    try:
        with open(pth_file, "r") as f:
            lines = f.read().splitlines()[2:]
    except IOError:
        raise ValueError("not found: {}".format(path))

    try:
        lines.remove(path)
    except ValueError:
        raise ValueError("not found: {}".format(path))

    lines.insert(0, HEADER)
    with open(pth_file, "w") as f:
        f.write(os.linesep.join(lines))


def show(pth_file=None):
    pth_file = pth_file or PATH
    print("current paths ({}):".format(pth_file))
    try:
        f = open(pth_file, "r")
    except IOError:
        return
    with f:
        lines = f.read()
        if not lines.startswith(HEADER):
            raise ValueError(".pth file is invalid: {}".format(pth_file))
        for line in lines.splitlines()[2:]:
            if not line.strip():
                continue
            print(line)


if __name__ == "__main__":
    import argparse
    EPILOG = "If no args are passed, the current contents are shown."
    parser = argparse.ArgumentParser(epilog=EPILOG)
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-a", "--add", metavar="PATH")
    group.add_argument("-r", "--remove", metavar="PATH")
    parser.add_argument("-f", "--file", metavar="<path to .pth file>")
    args = parser.parse_args()

    if args.add:
        add(args.add, args.file)
    elif args.remove:
        remove(args.remove, args.file)
    else:
        show(args.file)
Created by Eric Snow on Thu, 16 Feb 2012 (BSD)
Python recipes (4591)
Eric Snow's recipes (39)

Required Modules

  • (none specified)

Other Information and Tasks