add release date
[python/dscho.git] / Lib / site.py
blob9865cc940e0068ed5460fd55df8ed4df40638eeb
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 (including Mac OSX), it starts with sys.prefix and
15 sys.exec_prefix (if different) and appends
16 lib/python<version>/site-packages as well as lib/site-python.
17 On other platforms (such as Windows), it tries each of the
18 prefixes directly, as well as with lib/site-packages appended. The
19 resulting directories, if they exist, are appended to sys.path, and
20 also inspected for path configuration files.
22 A path configuration file is a file whose name has the form
23 <package>.pth; its contents are additional directories (one per line)
24 to be added to sys.path. Non-existing directories (or
25 non-directories) are never added to sys.path; no directory is added to
26 sys.path more than once. Blank lines and lines beginning with
27 '#' are skipped. Lines starting with 'import' are executed.
29 For example, suppose sys.prefix and sys.exec_prefix are set to
30 /usr/local and there is a directory /usr/local/lib/python2.5/site-packages
31 with three subdirectories, foo, bar and spam, and two path
32 configuration files, foo.pth and bar.pth. Assume foo.pth contains the
33 following:
35 # foo package configuration
36 foo
37 bar
38 bletch
40 and bar.pth contains:
42 # bar package configuration
43 bar
45 Then the following directories are added to sys.path, in this order:
47 /usr/local/lib/python2.5/site-packages/bar
48 /usr/local/lib/python2.5/site-packages/foo
50 Note that bletch is omitted because it doesn't exist; bar precedes foo
51 because bar.pth comes alphabetically before foo.pth; and spam is
52 omitted because it is not mentioned in either path configuration file.
54 After these path manipulations, an attempt is made to import a module
55 named sitecustomize, which can perform arbitrary additional
56 site-specific customizations. If this import fails with an
57 ImportError exception, it is silently ignored.
59 """
61 import sys
62 import os
63 import __builtin__
65 # Prefixes for site-packages; add additional prefixes like /usr/local here
66 PREFIXES = [sys.prefix, sys.exec_prefix]
67 # Enable per user site-packages directory
68 # set it to False to disable the feature or True to force the feature
69 ENABLE_USER_SITE = None
71 # for distutils.commands.install
72 # These values are initialized by the getuserbase() and getusersitepackages()
73 # functions, through the main() function when Python starts.
74 USER_SITE = None
75 USER_BASE = None
78 def makepath(*paths):
79 dir = os.path.abspath(os.path.join(*paths))
80 return dir, os.path.normcase(dir)
83 def abs__file__():
84 """Set all module' __file__ attribute to an absolute path"""
85 for m in sys.modules.values():
86 if hasattr(m, '__loader__'):
87 continue # don't mess with a PEP 302-supplied __file__
88 try:
89 m.__file__ = os.path.abspath(m.__file__)
90 except AttributeError:
91 continue
94 def removeduppaths():
95 """ Remove duplicate entries from sys.path along with making them
96 absolute"""
97 # This ensures that the initial path provided by the interpreter contains
98 # only absolute pathnames, even if we're running from the build directory.
99 L = []
100 known_paths = set()
101 for dir in sys.path:
102 # Filter out duplicate paths (on case-insensitive file systems also
103 # if they only differ in case); turn relative paths into absolute
104 # paths.
105 dir, dircase = makepath(dir)
106 if not dircase in known_paths:
107 L.append(dir)
108 known_paths.add(dircase)
109 sys.path[:] = L
110 return known_paths
112 # XXX This should not be part of site.py, since it is needed even when
113 # using the -S option for Python. See http://www.python.org/sf/586680
114 def addbuilddir():
115 """Append ./build/lib.<platform> in case we're running in the build dir
116 (especially for Guido :-)"""
117 from sysconfig import get_platform
118 s = "build/lib.%s-%.3s" % (get_platform(), sys.version)
119 if hasattr(sys, 'gettotalrefcount'):
120 s += '-pydebug'
121 s = os.path.join(os.path.dirname(sys.path.pop()), s)
122 sys.path.append(s)
125 def _init_pathinfo():
126 """Return a set containing all existing directory entries from sys.path"""
127 d = set()
128 for dir in sys.path:
129 try:
130 if os.path.isdir(dir):
131 dir, dircase = makepath(dir)
132 d.add(dircase)
133 except TypeError:
134 continue
135 return d
138 def addpackage(sitedir, name, known_paths):
139 """Process a .pth file within the site-packages directory:
140 For each line in the file, either combine it with sitedir to a path
141 and add that to known_paths, or execute it if it starts with 'import '.
143 if known_paths is None:
144 _init_pathinfo()
145 reset = 1
146 else:
147 reset = 0
148 fullname = os.path.join(sitedir, name)
149 try:
150 f = open(fullname, "rU")
151 except IOError:
152 return
153 with f:
154 for line in f:
155 if line.startswith("#"):
156 continue
157 if line.startswith(("import ", "import\t")):
158 exec line
159 continue
160 line = line.rstrip()
161 dir, dircase = makepath(sitedir, line)
162 if not dircase in known_paths and os.path.exists(dir):
163 sys.path.append(dir)
164 known_paths.add(dircase)
165 if reset:
166 known_paths = None
167 return known_paths
170 def addsitedir(sitedir, known_paths=None):
171 """Add 'sitedir' argument to sys.path if missing and handle .pth files in
172 'sitedir'"""
173 if known_paths is None:
174 known_paths = _init_pathinfo()
175 reset = 1
176 else:
177 reset = 0
178 sitedir, sitedircase = makepath(sitedir)
179 if not sitedircase in known_paths:
180 sys.path.append(sitedir) # Add path component
181 try:
182 names = os.listdir(sitedir)
183 except os.error:
184 return
185 dotpth = os.extsep + "pth"
186 names = [name for name in names if name.endswith(dotpth)]
187 for name in sorted(names):
188 addpackage(sitedir, name, known_paths)
189 if reset:
190 known_paths = None
191 return known_paths
194 def check_enableusersite():
195 """Check if user site directory is safe for inclusion
197 The function tests for the command line flag (including environment var),
198 process uid/gid equal to effective uid/gid.
200 None: Disabled for security reasons
201 False: Disabled by user (command line option)
202 True: Safe and enabled
204 if sys.flags.no_user_site:
205 return False
207 if hasattr(os, "getuid") and hasattr(os, "geteuid"):
208 # check process uid == effective uid
209 if os.geteuid() != os.getuid():
210 return None
211 if hasattr(os, "getgid") and hasattr(os, "getegid"):
212 # check process gid == effective gid
213 if os.getegid() != os.getgid():
214 return None
216 return True
218 def getuserbase():
219 """Returns the `user base` directory path.
221 The `user base` directory can be used to store data. If the global
222 variable ``USER_BASE`` is not initialized yet, this function will also set
225 global USER_BASE
226 if USER_BASE is not None:
227 return USER_BASE
228 from sysconfig import get_config_var
229 USER_BASE = get_config_var('userbase')
230 return USER_BASE
232 def getusersitepackages():
233 """Returns the user-specific site-packages directory path.
235 If the global variable ``USER_SITE`` is not initialized yet, this
236 function will also set it.
238 global USER_SITE
239 user_base = getuserbase() # this will also set USER_BASE
241 if USER_SITE is not None:
242 return USER_SITE
244 from sysconfig import get_path
245 import os
247 if sys.platform == 'darwin':
248 from sysconfig import get_config_var
249 if get_config_var('PYTHONFRAMEWORK'):
250 USER_SITE = get_path('purelib', 'osx_framework_user')
251 return USER_SITE
253 USER_SITE = get_path('purelib', '%s_user' % os.name)
254 return USER_SITE
256 def addusersitepackages(known_paths):
257 """Add a per user site-package to sys.path
259 Each user has its own python directory with site-packages in the
260 home directory.
262 # get the per user site-package path
263 # this call will also make sure USER_BASE and USER_SITE are set
264 user_site = getusersitepackages()
266 if ENABLE_USER_SITE and os.path.isdir(user_site):
267 addsitedir(user_site, known_paths)
268 return known_paths
270 def getsitepackages():
271 """Returns a list containing all global site-packages directories
272 (and possibly site-python).
274 For each directory present in the global ``PREFIXES``, this function
275 will find its `site-packages` subdirectory depending on the system
276 environment, and will return a list of full paths.
278 sitepackages = []
279 seen = set()
281 for prefix in PREFIXES:
282 if not prefix or prefix in seen:
283 continue
284 seen.add(prefix)
286 if sys.platform in ('os2emx', 'riscos'):
287 sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
288 elif os.sep == '/':
289 sitepackages.append(os.path.join(prefix, "lib",
290 "python" + sys.version[:3],
291 "site-packages"))
292 sitepackages.append(os.path.join(prefix, "lib", "site-python"))
293 else:
294 sitepackages.append(prefix)
295 sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
296 if sys.platform == "darwin":
297 # for framework builds *only* we add the standard Apple
298 # locations.
299 from sysconfig import get_config_var
300 framework = get_config_var("PYTHONFRAMEWORK")
301 if framework and "/%s.framework/"%(framework,) in prefix:
302 sitepackages.append(
303 os.path.join("/Library", framework,
304 sys.version[:3], "site-packages"))
305 return sitepackages
307 def addsitepackages(known_paths):
308 """Add site-packages (and possibly site-python) to sys.path"""
309 for sitedir in getsitepackages():
310 if os.path.isdir(sitedir):
311 addsitedir(sitedir, known_paths)
313 return known_paths
315 def setBEGINLIBPATH():
316 """The OS/2 EMX port has optional extension modules that do double duty
317 as DLLs (and must use the .DLL file extension) for other extensions.
318 The library search path needs to be amended so these will be found
319 during module import. Use BEGINLIBPATH so that these are at the start
320 of the library search path.
323 dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")
324 libpath = os.environ['BEGINLIBPATH'].split(';')
325 if libpath[-1]:
326 libpath.append(dllpath)
327 else:
328 libpath[-1] = dllpath
329 os.environ['BEGINLIBPATH'] = ';'.join(libpath)
332 def setquit():
333 """Define new builtins 'quit' and 'exit'.
335 These are objects which make the interpreter exit when called.
336 The repr of each object contains a hint at how it works.
339 if os.sep == ':':
340 eof = 'Cmd-Q'
341 elif os.sep == '\\':
342 eof = 'Ctrl-Z plus Return'
343 else:
344 eof = 'Ctrl-D (i.e. EOF)'
346 class Quitter(object):
347 def __init__(self, name):
348 self.name = name
349 def __repr__(self):
350 return 'Use %s() or %s to exit' % (self.name, eof)
351 def __call__(self, code=None):
352 # Shells like IDLE catch the SystemExit, but listen when their
353 # stdin wrapper is closed.
354 try:
355 sys.stdin.close()
356 except:
357 pass
358 raise SystemExit(code)
359 __builtin__.quit = Quitter('quit')
360 __builtin__.exit = Quitter('exit')
363 class _Printer(object):
364 """interactive prompt objects for printing the license text, a list of
365 contributors and the copyright notice."""
367 MAXLINES = 23
369 def __init__(self, name, data, files=(), dirs=()):
370 self.__name = name
371 self.__data = data
372 self.__files = files
373 self.__dirs = dirs
374 self.__lines = None
376 def __setup(self):
377 if self.__lines:
378 return
379 data = None
380 for dir in self.__dirs:
381 for filename in self.__files:
382 filename = os.path.join(dir, filename)
383 try:
384 fp = file(filename, "rU")
385 data = fp.read()
386 fp.close()
387 break
388 except IOError:
389 pass
390 if data:
391 break
392 if not data:
393 data = self.__data
394 self.__lines = data.split('\n')
395 self.__linecnt = len(self.__lines)
397 def __repr__(self):
398 self.__setup()
399 if len(self.__lines) <= self.MAXLINES:
400 return "\n".join(self.__lines)
401 else:
402 return "Type %s() to see the full %s text" % ((self.__name,)*2)
404 def __call__(self):
405 self.__setup()
406 prompt = 'Hit Return for more, or q (and Return) to quit: '
407 lineno = 0
408 while 1:
409 try:
410 for i in range(lineno, lineno + self.MAXLINES):
411 print self.__lines[i]
412 except IndexError:
413 break
414 else:
415 lineno += self.MAXLINES
416 key = None
417 while key is None:
418 key = raw_input(prompt)
419 if key not in ('', 'q'):
420 key = None
421 if key == 'q':
422 break
424 def setcopyright():
425 """Set 'copyright' and 'credits' in __builtin__"""
426 __builtin__.copyright = _Printer("copyright", sys.copyright)
427 if sys.platform[:4] == 'java':
428 __builtin__.credits = _Printer(
429 "credits",
430 "Jython is maintained by the Jython developers (www.jython.org).")
431 else:
432 __builtin__.credits = _Printer("credits", """\
433 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
434 for supporting Python development. See www.python.org for more information.""")
435 here = os.path.dirname(os.__file__)
436 __builtin__.license = _Printer(
437 "license", "See http://www.python.org/%.3s/license.html" % sys.version,
438 ["LICENSE.txt", "LICENSE"],
439 [os.path.join(here, os.pardir), here, os.curdir])
442 class _Helper(object):
443 """Define the builtin 'help'.
444 This is a wrapper around pydoc.help (with a twist).
448 def __repr__(self):
449 return "Type help() for interactive help, " \
450 "or help(object) for help about object."
451 def __call__(self, *args, **kwds):
452 import pydoc
453 return pydoc.help(*args, **kwds)
455 def sethelper():
456 __builtin__.help = _Helper()
458 def aliasmbcs():
459 """On Windows, some default encodings are not provided by Python,
460 while they are always available as "mbcs" in each locale. Make
461 them usable by aliasing to "mbcs" in such a case."""
462 if sys.platform == 'win32':
463 import locale, codecs
464 enc = locale.getdefaultlocale()[1]
465 if enc.startswith('cp'): # "cp***" ?
466 try:
467 codecs.lookup(enc)
468 except LookupError:
469 import encodings
470 encodings._cache[enc] = encodings._unknown
471 encodings.aliases.aliases[enc] = 'mbcs'
473 def setencoding():
474 """Set the string encoding used by the Unicode implementation. The
475 default is 'ascii', but if you're willing to experiment, you can
476 change this."""
477 encoding = "ascii" # Default value set by _PyUnicode_Init()
478 if 0:
479 # Enable to support locale aware default string encodings.
480 import locale
481 loc = locale.getdefaultlocale()
482 if loc[1]:
483 encoding = loc[1]
484 if 0:
485 # Enable to switch off string to Unicode coercion and implicit
486 # Unicode to string conversion.
487 encoding = "undefined"
488 if encoding != "ascii":
489 # On Non-Unicode builds this will raise an AttributeError...
490 sys.setdefaultencoding(encoding) # Needs Python Unicode build !
493 def execsitecustomize():
494 """Run custom site specific code, if available."""
495 try:
496 import sitecustomize
497 except ImportError:
498 pass
499 except Exception:
500 if sys.flags.verbose:
501 sys.excepthook(*sys.exc_info())
502 else:
503 print >>sys.stderr, \
504 "'import sitecustomize' failed; use -v for traceback"
507 def execusercustomize():
508 """Run custom user specific code, if available."""
509 try:
510 import usercustomize
511 except ImportError:
512 pass
513 except Exception:
514 if sys.flags.verbose:
515 sys.excepthook(*sys.exc_info())
516 else:
517 print>>sys.stderr, \
518 "'import usercustomize' failed; use -v for traceback"
521 def main():
522 global ENABLE_USER_SITE
524 abs__file__()
525 known_paths = removeduppaths()
526 if (os.name == "posix" and sys.path and
527 os.path.basename(sys.path[-1]) == "Modules"):
528 addbuilddir()
529 if ENABLE_USER_SITE is None:
530 ENABLE_USER_SITE = check_enableusersite()
531 known_paths = addusersitepackages(known_paths)
532 known_paths = addsitepackages(known_paths)
533 if sys.platform == 'os2emx':
534 setBEGINLIBPATH()
535 setquit()
536 setcopyright()
537 sethelper()
538 aliasmbcs()
539 setencoding()
540 execsitecustomize()
541 if ENABLE_USER_SITE:
542 execusercustomize()
543 # Remove sys.setdefaultencoding() so that users cannot change the
544 # encoding after initialization. The test for presence is needed when
545 # this module is run as a script, because this code is executed twice.
546 if hasattr(sys, "setdefaultencoding"):
547 del sys.setdefaultencoding
549 main()
551 def _script():
552 help = """\
553 %s [--user-base] [--user-site]
555 Without arguments print some useful information
556 With arguments print the value of USER_BASE and/or USER_SITE separated
557 by '%s'.
559 Exit codes with --user-base or --user-site:
560 0 - user site directory is enabled
561 1 - user site directory is disabled by user
562 2 - uses site directory is disabled by super user
563 or for security reasons
564 >2 - unknown error
566 args = sys.argv[1:]
567 if not args:
568 print "sys.path = ["
569 for dir in sys.path:
570 print " %r," % (dir,)
571 print "]"
572 print "USER_BASE: %r (%s)" % (USER_BASE,
573 "exists" if os.path.isdir(USER_BASE) else "doesn't exist")
574 print "USER_SITE: %r (%s)" % (USER_SITE,
575 "exists" if os.path.isdir(USER_SITE) else "doesn't exist")
576 print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE
577 sys.exit(0)
579 buffer = []
580 if '--user-base' in args:
581 buffer.append(USER_BASE)
582 if '--user-site' in args:
583 buffer.append(USER_SITE)
585 if buffer:
586 print os.pathsep.join(buffer)
587 if ENABLE_USER_SITE:
588 sys.exit(0)
589 elif ENABLE_USER_SITE is False:
590 sys.exit(1)
591 elif ENABLE_USER_SITE is None:
592 sys.exit(2)
593 else:
594 sys.exit(3)
595 else:
596 import textwrap
597 print textwrap.dedent(help % (sys.argv[0], os.pathsep))
598 sys.exit(10)
600 if __name__ == '__main__':
601 _script()