site.py 8.57 KB
Newer Older
1
"""Append module search paths for third-party packages to sys.path.
2

3 4 5
****************************************************************
* This module is automatically imported during initialization. *
****************************************************************
6

7 8 9 10 11
In earlier versions of Python (up to 1.5a3), scripts or modules that
needed to use site-specific modules would place ``import site''
somewhere near the top of their code.  Because of the automatic
import, this is no longer necessary (but code that does it still
works).
12

13 14 15 16 17
This will append site-specific paths to to the module search path.  On
Unix, it starts with sys.prefix and sys.exec_prefix (if different) and
appends lib/python<version>/site-packages as well as lib/site-python.
On other platforms (mainly Mac and Windows), it uses just sys.prefix
(and sys.exec_prefix, if different, but this is unlikely).  The
18 19
resulting directories, if they exist, are appended to sys.path, and
also inspected for path configuration files.
20

21 22 23 24 25
A path configuration file is a file whose name has the form
<package>.pth; its contents are additional directories (one per line)
to be added to sys.path.  Non-existing directories (or
non-directories) are never added to sys.path; no directory is added to
sys.path more than once.  Blank lines and lines beginning with
26
\code{#} are skipped. Lines starting with \code{import} are executed.
27

28
For example, suppose sys.prefix and sys.exec_prefix are set to
29
/usr/local and there is a directory /usr/local/lib/python1.5/site-packages
30 31 32
with three subdirectories, foo, bar and spam, and two path
configuration files, foo.pth and bar.pth.  Assume foo.pth contains the
following:
33 34 35 36 37 38 39 40 41 42 43 44 45

  # foo package configuration
  foo
  bar
  bletch

and bar.pth contains:

  # bar package configuration
  bar

Then the following directories are added to sys.path, in this order:

46 47
  /usr/local/lib/python1.5/site-packages/bar
  /usr/local/lib/python1.5/site-packages/foo
48 49 50 51

Note that bletch is omitted because it doesn't exist; bar precedes foo
because bar.pth comes alphabetically before foo.pth; and spam is
omitted because it is not mentioned in either path configuration file.
52 53

After these path manipulations, an attempt is made to import a module
54 55 56
named sitecustomize, which can perform arbitrary additional
site-specific customizations.  If this import fails with an
ImportError exception, it is silently ignored.
57 58 59 60 61

"""

import sys, os

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
def makepath(*paths):
    dir = os.path.join(*paths)
    return os.path.normcase(os.path.abspath(dir))

L = sys.modules.values()
for m in L:
    if hasattr(m, "__file__"):
        m.__file__ = makepath(m.__file__)
del m, L

# This ensures that the initial path provided by the interpreter contains
# only absolute pathnames, even if we're running from the build directory.
L = []
for dir in sys.path:
    dir = makepath(dir)
    if dir not in L:
        L.append(dir)
sys.path[:] = L
del dir, L

82 83 84 85 86 87 88 89 90
# Append ./build/lib.<platform> in case we're running in the build dir
# (especially for Guido :-)
if os.name == "posix" and os.path.basename(sys.path[-1]) == "Modules":
    from distutils.util import get_platform
    s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
    s = os.path.join(os.path.dirname(sys.path[-1]), s)
    sys.path.append(s)
    del get_platform, s

91
def addsitedir(sitedir):
92
    sitedir = makepath(sitedir)
93
    if sitedir not in sys.path:
94
        sys.path.append(sitedir)        # Add path component
95
    try:
96
        names = os.listdir(sitedir)
97
    except os.error:
98
        return
99 100 101
    names = map(os.path.normcase, names)
    names.sort()
    for name in names:
102 103
        if name[-4:] == ".pth":
            addpackage(sitedir, name)
104 105 106 107

def addpackage(sitedir, name):
    fullname = os.path.join(sitedir, name)
    try:
108
        f = open(fullname)
109
    except IOError:
110
        return
111
    while 1:
112 113 114 115 116
        dir = f.readline()
        if not dir:
            break
        if dir[0] == '#':
            continue
117 118 119
        if dir.startswith("import"):
            exec dir
            continue
120 121
        if dir[-1] == '\n':
            dir = dir[:-1]
122
        dir = makepath(sitedir, dir)
123 124
        if dir not in sys.path and os.path.exists(dir):
            sys.path.append(dir)
125 126 127 128 129

prefixes = [sys.prefix]
if sys.exec_prefix != sys.prefix:
    prefixes.append(sys.exec_prefix)
for prefix in prefixes:
130
    if prefix:
131
        if os.sep == '/':
132 133 134 135 136
            sitedirs = [makepath(prefix,
                                 "lib",
                                 "python" + sys.version[:3],
                                 "site-packages"),
                        makepath(prefix, "lib", "site-python")]
137 138
        elif os.sep == ':':
            sitedirs = [makepath(prefix, "lib", "site-packages")]
139 140 141 142 143
        else:
            sitedirs = [prefix]
        for sitedir in sitedirs:
            if os.path.isdir(sitedir):
                addsitedir(sitedir)
144

145 146 147 148 149 150 151 152 153 154 155 156
# Define new built-ins 'quit' and 'exit'.
# These are simply strings that display a hint on how to exit.
if os.sep == ':':
    exit = 'Use Cmd-Q to quit.'
elif os.sep == '\\':
    exit = 'Use Ctrl-Z plus Return to exit.'
else:
    exit = 'Use Ctrl-D (i.e. EOF) to exit.'
import __builtin__
__builtin__.quit = __builtin__.exit = exit
del exit

157 158 159 160 161
# interactive prompt objects for printing the license text, a list of
# contributors and the copyright notice.
class _Printer:
    MAXLINES = 23

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    def __init__(self, name, data, files=(), dirs=()):
        self.__name = name
        self.__data = data
        self.__files = files
        self.__dirs = dirs
        self.__lines = None

    def __setup(self):
        if self.__lines:
            return
        data = None
        for dir in self.__dirs:
            for file in self.__files:
                file = os.path.join(dir, file)
                try:
                    fp = open(file)
                    data = fp.read()
                    fp.close()
                    break
                except IOError:
                    pass
            if data:
                break
        if not data:
            data = self.__data
        self.__lines = data.split('\n')
188 189 190
        self.__linecnt = len(self.__lines)

    def __repr__(self):
191 192 193 194 195 196 197 198
        self.__setup()
        if len(self.__lines) <= self.MAXLINES:
            return "\n".join(self.__lines)
        else:
            return "Type %s() to see the full %s text" % ((self.__name,)*2)

    def __call__(self):
        self.__setup()
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        prompt = 'Hit Return for more, or q (and Return) to quit: '
        lineno = 0
        while 1:
            try:
                for i in range(lineno, lineno + self.MAXLINES):
                    print self.__lines[i]
            except IndexError:
                break
            else:
                lineno += self.MAXLINES
                key = None
                while key is None:
                    key = raw_input(prompt)
                    if key not in ('', 'q'):
                        key = None
                if key == 'q':
                    break

217
__builtin__.copyright = _Printer("copyright", sys.copyright)
218 219 220 221 222 223 224 225
if sys.platform[:4] == 'java':
    __builtin__.credits = _Printer(
        "credits",
        "Jython is maintained by the Jython developers (www.jython.org).")
else:
    __builtin__.credits = _Printer("credits", """\
Thanks to CWI, CNRI, BeOpen.com, Digital Creations and a cast of thousands
for supporting Python development.  See www.python.org for more information.""")
226
here = os.path.dirname(os.__file__)
227 228 229 230
__builtin__.license = _Printer(
    "license", "See http://www.pythonlabs.com/products/python2.0/license.html",
    ["LICENSE.txt", "LICENSE"],
    [here, os.path.join(here, os.pardir), os.curdir])
231 232


233 234 235
# Set the string encoding used by the Unicode implementation.  The
# default is 'ascii', but if you're willing to experiment, you can
# change this.
236

237
encoding = "ascii" # Default value set by _PyUnicode_Init()
238 239

if 0:
240
    # Enable to support locale aware default string encodings.
241 242 243 244 245 246
    import locale
    loc = locale.getdefaultlocale()
    if loc[1]:
        encoding = loc[1]

if 0:
247 248
    # Enable to switch off string to Unicode coercion and implicit
    # Unicode to string conversion.
249 250
    encoding = "undefined"

251 252
if encoding != "ascii":
    sys.setdefaultencoding(encoding)
253 254 255 256

#
# Run custom site specific code, if available.
#
257
try:
258
    import sitecustomize
259
except ImportError:
260 261 262 263
    pass

#
# Remove sys.setdefaultencoding() so that users cannot change the
264
# encoding after initialization.  The test for presence is needed when
265
# this module is run as a script, because this code is executed twice.
266
#
267 268
if hasattr(sys, "setdefaultencoding"):
    del sys.setdefaultencoding
269 270 271 272

def _test():
    print "sys.path = ["
    for dir in sys.path:
273
        print "    %s," % `dir`
274 275 276 277
    print "]"

if __name__ == '__main__':
    _test()