pasted set_lk_detect line in wrong spot in previous commit. fixed. passes tests...
[python.git] / Lib / site.py
blobc44c3937ecf74eabb2de812aaba721d660e82bc0
1 """Append module search paths for third-party packages to sys.path.
3 ****************************************************************
4 * This module is automatically imported during initialization. *
5 ****************************************************************
7 In earlier versions of Python (up to 1.5a3), scripts or modules that
8 needed to use site-specific modules would place ``import site''
9 somewhere near the top of their code. Because of the automatic
10 import, this is no longer necessary (but code that does it still
11 works).
13 This will append site-specific paths to the module search path. On
14 Unix, it starts with sys.prefix and sys.exec_prefix (if different) and
15 appends lib/python<version>/site-packages as well as lib/site-python.
16 On other platforms (mainly Mac and Windows), it uses just sys.prefix
17 (and sys.exec_prefix, if different, but this is unlikely). The
18 resulting directories, if they exist, are appended to sys.path, and
19 also inspected for path configuration files.
21 A path configuration file is a file whose name has the form
22 <package>.pth; its contents are additional directories (one per line)
23 to be added to sys.path. Non-existing directories (or
24 non-directories) are never added to sys.path; no directory is added to
25 sys.path more than once. Blank lines and lines beginning with
26 '#' are skipped. Lines starting with 'import' are executed.
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 with three subdirectories, foo, bar and spam, and two path
31 configuration files, foo.pth and bar.pth. Assume foo.pth contains the
32 following:
34 # foo package configuration
35 foo
36 bar
37 bletch
39 and bar.pth contains:
41 # bar package configuration
42 bar
44 Then the following directories are added to sys.path, in this order:
46 /usr/local/lib/python1.5/site-packages/bar
47 /usr/local/lib/python1.5/site-packages/foo
49 Note that bletch is omitted because it doesn't exist; bar precedes foo
50 because bar.pth comes alphabetically before foo.pth; and spam is
51 omitted because it is not mentioned in either path configuration file.
53 After these path manipulations, an attempt is made to import a module
54 named sitecustomize, which can perform arbitrary additional
55 site-specific customizations. If this import fails with an
56 ImportError exception, it is silently ignored.
58 """
60 import sys
61 import os
62 import __builtin__
65 def makepath(*paths):
66 dir = os.path.abspath(os.path.join(*paths))
67 return dir, os.path.normcase(dir)
69 def abs__file__():
70 """Set all module' __file__ attribute to an absolute path"""
71 for m in sys.modules.values():
72 if hasattr(m, '__loader__'):
73 continue # don't mess with a PEP 302-supplied __file__
74 try:
75 m.__file__ = os.path.abspath(m.__file__)
76 except AttributeError:
77 continue
79 def removeduppaths():
80 """ Remove duplicate entries from sys.path along with making them
81 absolute"""
82 # This ensures that the initial path provided by the interpreter contains
83 # only absolute pathnames, even if we're running from the build directory.
84 L = []
85 known_paths = set()
86 for dir in sys.path:
87 # Filter out duplicate paths (on case-insensitive file systems also
88 # if they only differ in case); turn relative paths into absolute
89 # paths.
90 dir, dircase = makepath(dir)
91 if not dircase in known_paths:
92 L.append(dir)
93 known_paths.add(dircase)
94 sys.path[:] = L
95 return known_paths
97 # XXX This should not be part of site.py, since it is needed even when
98 # using the -S option for Python. See http://www.python.org/sf/586680
99 def addbuilddir():
100 """Append ./build/lib.<platform> in case we're running in the build dir
101 (especially for Guido :-)"""
102 from distutils.util import get_platform
103 s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
104 s = os.path.join(os.path.dirname(sys.path[-1]), s)
105 sys.path.append(s)
107 def _init_pathinfo():
108 """Return a set containing all existing directory entries from sys.path"""
109 d = set()
110 for dir in sys.path:
111 try:
112 if os.path.isdir(dir):
113 dir, dircase = makepath(dir)
114 d.add(dircase)
115 except TypeError:
116 continue
117 return d
119 def addpackage(sitedir, name, known_paths):
120 """Add a new path to known_paths by combining sitedir and 'name' or execute
121 sitedir if it starts with 'import'"""
122 if known_paths is None:
123 _init_pathinfo()
124 reset = 1
125 else:
126 reset = 0
127 fullname = os.path.join(sitedir, name)
128 try:
129 f = open(fullname, "rU")
130 except IOError:
131 return
132 try:
133 for line in f:
134 if line.startswith("#"):
135 continue
136 if line.startswith("import"):
137 exec line
138 continue
139 line = line.rstrip()
140 dir, dircase = makepath(sitedir, line)
141 if not dircase in known_paths and os.path.exists(dir):
142 sys.path.append(dir)
143 known_paths.add(dircase)
144 finally:
145 f.close()
146 if reset:
147 known_paths = None
148 return known_paths
150 def addsitedir(sitedir, known_paths=None):
151 """Add 'sitedir' argument to sys.path if missing and handle .pth files in
152 'sitedir'"""
153 if known_paths is None:
154 known_paths = _init_pathinfo()
155 reset = 1
156 else:
157 reset = 0
158 sitedir, sitedircase = makepath(sitedir)
159 if not sitedircase in known_paths:
160 sys.path.append(sitedir) # Add path component
161 try:
162 names = os.listdir(sitedir)
163 except os.error:
164 return
165 names.sort()
166 for name in names:
167 if name.endswith(os.extsep + "pth"):
168 addpackage(sitedir, name, known_paths)
169 if reset:
170 known_paths = None
171 return known_paths
173 def addsitepackages(known_paths):
174 """Add site-packages (and possibly site-python) to sys.path"""
175 prefixes = [sys.prefix]
176 if sys.exec_prefix != sys.prefix:
177 prefixes.append(sys.exec_prefix)
178 for prefix in prefixes:
179 if prefix:
180 if sys.platform in ('os2emx', 'riscos'):
181 sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
182 elif os.sep == '/':
183 sitedirs = [os.path.join(prefix,
184 "lib",
185 "python" + sys.version[:3],
186 "site-packages"),
187 os.path.join(prefix, "lib", "site-python")]
188 else:
189 sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]
190 if sys.platform == 'darwin':
191 # for framework builds *only* we add the standard Apple
192 # locations. Currently only per-user, but /Library and
193 # /Network/Library could be added too
194 if 'Python.framework' in prefix:
195 home = os.environ.get('HOME')
196 if home:
197 sitedirs.append(
198 os.path.join(home,
199 'Library',
200 'Python',
201 sys.version[:3],
202 'site-packages'))
203 for sitedir in sitedirs:
204 if os.path.isdir(sitedir):
205 addsitedir(sitedir, known_paths)
206 return None
209 def setBEGINLIBPATH():
210 """The OS/2 EMX port has optional extension modules that do double duty
211 as DLLs (and must use the .DLL file extension) for other extensions.
212 The library search path needs to be amended so these will be found
213 during module import. Use BEGINLIBPATH so that these are at the start
214 of the library search path.
217 dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")
218 libpath = os.environ['BEGINLIBPATH'].split(';')
219 if libpath[-1]:
220 libpath.append(dllpath)
221 else:
222 libpath[-1] = dllpath
223 os.environ['BEGINLIBPATH'] = ';'.join(libpath)
226 def setquit():
227 """Define new built-ins 'quit' and 'exit'.
228 These are simply strings that display a hint on how to exit.
231 if os.sep == ':':
232 eof = 'Cmd-Q'
233 elif os.sep == '\\':
234 eof = 'Ctrl-Z plus Return'
235 else:
236 eof = 'Ctrl-D (i.e. EOF)'
238 class Quitter(object):
239 def __init__(self, name):
240 self.name = name
241 def __repr__(self):
242 return 'Use %s() or %s to exit' % (self.name, eof)
243 def __call__(self, code=None):
244 raise SystemExit(code)
245 __builtin__.quit = Quitter('quit')
246 __builtin__.exit = Quitter('exit')
249 class _Printer(object):
250 """interactive prompt objects for printing the license text, a list of
251 contributors and the copyright notice."""
253 MAXLINES = 23
255 def __init__(self, name, data, files=(), dirs=()):
256 self.__name = name
257 self.__data = data
258 self.__files = files
259 self.__dirs = dirs
260 self.__lines = None
262 def __setup(self):
263 if self.__lines:
264 return
265 data = None
266 for dir in self.__dirs:
267 for filename in self.__files:
268 filename = os.path.join(dir, filename)
269 try:
270 fp = file(filename, "rU")
271 data = fp.read()
272 fp.close()
273 break
274 except IOError:
275 pass
276 if data:
277 break
278 if not data:
279 data = self.__data
280 self.__lines = data.split('\n')
281 self.__linecnt = len(self.__lines)
283 def __repr__(self):
284 self.__setup()
285 if len(self.__lines) <= self.MAXLINES:
286 return "\n".join(self.__lines)
287 else:
288 return "Type %s() to see the full %s text" % ((self.__name,)*2)
290 def __call__(self):
291 self.__setup()
292 prompt = 'Hit Return for more, or q (and Return) to quit: '
293 lineno = 0
294 while 1:
295 try:
296 for i in range(lineno, lineno + self.MAXLINES):
297 print self.__lines[i]
298 except IndexError:
299 break
300 else:
301 lineno += self.MAXLINES
302 key = None
303 while key is None:
304 key = raw_input(prompt)
305 if key not in ('', 'q'):
306 key = None
307 if key == 'q':
308 break
310 def setcopyright():
311 """Set 'copyright' and 'credits' in __builtin__"""
312 __builtin__.copyright = _Printer("copyright", sys.copyright)
313 if sys.platform[:4] == 'java':
314 __builtin__.credits = _Printer(
315 "credits",
316 "Jython is maintained by the Jython developers (www.jython.org).")
317 else:
318 __builtin__.credits = _Printer("credits", """\
319 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
320 for supporting Python development. See www.python.org for more information.""")
321 here = os.path.dirname(os.__file__)
322 __builtin__.license = _Printer(
323 "license", "See http://www.python.org/%.3s/license.html" % sys.version,
324 ["LICENSE.txt", "LICENSE"],
325 [os.path.join(here, os.pardir), here, os.curdir])
328 class _Helper(object):
329 """Define the built-in 'help'.
330 This is a wrapper around pydoc.help (with a twist).
334 def __repr__(self):
335 return "Type help() for interactive help, " \
336 "or help(object) for help about object."
337 def __call__(self, *args, **kwds):
338 import pydoc
339 return pydoc.help(*args, **kwds)
341 def sethelper():
342 __builtin__.help = _Helper()
344 def aliasmbcs():
345 """On Windows, some default encodings are not provided by Python,
346 while they are always available as "mbcs" in each locale. Make
347 them usable by aliasing to "mbcs" in such a case."""
348 if sys.platform == 'win32':
349 import locale, codecs
350 enc = locale.getdefaultlocale()[1]
351 if enc.startswith('cp'): # "cp***" ?
352 try:
353 codecs.lookup(enc)
354 except LookupError:
355 import encodings
356 encodings._cache[enc] = encodings._unknown
357 encodings.aliases.aliases[enc] = 'mbcs'
359 def setencoding():
360 """Set the string encoding used by the Unicode implementation. The
361 default is 'ascii', but if you're willing to experiment, you can
362 change this."""
363 encoding = "ascii" # Default value set by _PyUnicode_Init()
364 if 0:
365 # Enable to support locale aware default string encodings.
366 import locale
367 loc = locale.getdefaultlocale()
368 if loc[1]:
369 encoding = loc[1]
370 if 0:
371 # Enable to switch off string to Unicode coercion and implicit
372 # Unicode to string conversion.
373 encoding = "undefined"
374 if encoding != "ascii":
375 # On Non-Unicode builds this will raise an AttributeError...
376 sys.setdefaultencoding(encoding) # Needs Python Unicode build !
379 def execsitecustomize():
380 """Run custom site specific code, if available."""
381 try:
382 import sitecustomize
383 except ImportError:
384 pass
387 def main():
388 abs__file__()
389 paths_in_sys = removeduppaths()
390 if (os.name == "posix" and sys.path and
391 os.path.basename(sys.path[-1]) == "Modules"):
392 addbuilddir()
393 paths_in_sys = addsitepackages(paths_in_sys)
394 if sys.platform == 'os2emx':
395 setBEGINLIBPATH()
396 setquit()
397 setcopyright()
398 sethelper()
399 aliasmbcs()
400 setencoding()
401 execsitecustomize()
402 # Remove sys.setdefaultencoding() so that users cannot change the
403 # encoding after initialization. The test for presence is needed when
404 # this module is run as a script, because this code is executed twice.
405 if hasattr(sys, "setdefaultencoding"):
406 del sys.setdefaultencoding
408 main()
410 def _test():
411 print "sys.path = ["
412 for dir in sys.path:
413 print " %r," % (dir,)
414 print "]"
416 if __name__ == '__main__':
417 _test()