Mention Giampolo R's new FTP TLS support in the what's new file
[python.git] / Lib / site.py
blobf2b72ef46b812f47b0066d623cf0f5360d4008d5
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 distutils.util 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[-1]), 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
229 env_base = os.environ.get("PYTHONUSERBASE", None)
231 def joinuser(*args):
232 return os.path.expanduser(os.path.join(*args))
234 # what about 'os2emx', 'riscos' ?
235 if os.name == "nt":
236 base = os.environ.get("APPDATA") or "~"
237 USER_BASE = env_base if env_base else joinuser(base, "Python")
238 else:
239 USER_BASE = env_base if env_base else joinuser("~", ".local")
241 return USER_BASE
243 def getusersitepackages():
244 """Returns the user-specific site-packages directory path.
246 If the global variable ``USER_SITE`` is not initialized yet, this
247 function will also set it.
249 global USER_SITE
250 user_base = getuserbase() # this will also set USER_BASE
252 if USER_SITE is not None:
253 return USER_SITE
255 if os.name == "nt":
256 USER_SITE = os.path.join(user_base, "Python" + sys.version[0] +
257 sys.version[2], "site-packages")
258 else:
259 USER_SITE = os.path.join(user_base, "lib", "python" + sys.version[:3],
260 "site-packages")
262 return USER_SITE
264 def addusersitepackages(known_paths):
265 """Add a per user site-package to sys.path
267 Each user has its own python directory with site-packages in the
268 home directory.
270 # get the per user site-package path
271 # this call will also make sure USER_BASE and USER_SITE are set
272 user_site = getusersitepackages()
274 if ENABLE_USER_SITE and os.path.isdir(user_site):
275 addsitedir(user_site, known_paths)
276 return known_paths
278 def getsitepackages():
279 """Returns a list containing all global site-packages directories
280 (and possibly site-python).
282 For each directory present in the global ``PREFIXES``, this function
283 will find its `site-packages` subdirectory depending on the system
284 environment, and will return a list of full paths.
286 sitepackages = []
287 seen = []
289 for prefix in PREFIXES:
290 if not prefix or prefix in seen:
291 continue
292 seen.append(prefix)
294 if sys.platform in ('os2emx', 'riscos'):
295 sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
296 elif os.sep == '/':
297 sitepackages.append(os.path.join(prefix, "lib",
298 "python" + sys.version[:3],
299 "site-packages"))
300 sitepackages.append(os.path.join(prefix, "lib", "site-python"))
301 else:
302 sitepackages.append(prefix)
303 sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
304 if sys.platform == "darwin":
305 # for framework builds *only* we add the standard Apple
306 # locations.
307 if 'Python.framework' in prefix:
308 sitepackages.append(
309 os.path.expanduser(
310 os.path.join("~", "Library", "Python",
311 sys.version[:3], "site-packages")))
312 sitepackages.append(
313 os.path.join("/Library", "Python",
314 sys.version[:3], "site-packages"))
315 return sitepackages
317 def addsitepackages(known_paths):
318 """Add site-packages (and possibly site-python) to sys.path"""
319 for sitedir in getsitepackages():
320 if os.path.isdir(sitedir):
321 addsitedir(sitedir, known_paths)
323 return known_paths
325 def setBEGINLIBPATH():
326 """The OS/2 EMX port has optional extension modules that do double duty
327 as DLLs (and must use the .DLL file extension) for other extensions.
328 The library search path needs to be amended so these will be found
329 during module import. Use BEGINLIBPATH so that these are at the start
330 of the library search path.
333 dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")
334 libpath = os.environ['BEGINLIBPATH'].split(';')
335 if libpath[-1]:
336 libpath.append(dllpath)
337 else:
338 libpath[-1] = dllpath
339 os.environ['BEGINLIBPATH'] = ';'.join(libpath)
342 def setquit():
343 """Define new built-ins 'quit' and 'exit'.
344 These are simply strings that display a hint on how to exit.
347 if os.sep == ':':
348 eof = 'Cmd-Q'
349 elif os.sep == '\\':
350 eof = 'Ctrl-Z plus Return'
351 else:
352 eof = 'Ctrl-D (i.e. EOF)'
354 class Quitter(object):
355 def __init__(self, name):
356 self.name = name
357 def __repr__(self):
358 return 'Use %s() or %s to exit' % (self.name, eof)
359 def __call__(self, code=None):
360 # Shells like IDLE catch the SystemExit, but listen when their
361 # stdin wrapper is closed.
362 try:
363 sys.stdin.close()
364 except:
365 pass
366 raise SystemExit(code)
367 __builtin__.quit = Quitter('quit')
368 __builtin__.exit = Quitter('exit')
371 class _Printer(object):
372 """interactive prompt objects for printing the license text, a list of
373 contributors and the copyright notice."""
375 MAXLINES = 23
377 def __init__(self, name, data, files=(), dirs=()):
378 self.__name = name
379 self.__data = data
380 self.__files = files
381 self.__dirs = dirs
382 self.__lines = None
384 def __setup(self):
385 if self.__lines:
386 return
387 data = None
388 for dir in self.__dirs:
389 for filename in self.__files:
390 filename = os.path.join(dir, filename)
391 try:
392 fp = file(filename, "rU")
393 data = fp.read()
394 fp.close()
395 break
396 except IOError:
397 pass
398 if data:
399 break
400 if not data:
401 data = self.__data
402 self.__lines = data.split('\n')
403 self.__linecnt = len(self.__lines)
405 def __repr__(self):
406 self.__setup()
407 if len(self.__lines) <= self.MAXLINES:
408 return "\n".join(self.__lines)
409 else:
410 return "Type %s() to see the full %s text" % ((self.__name,)*2)
412 def __call__(self):
413 self.__setup()
414 prompt = 'Hit Return for more, or q (and Return) to quit: '
415 lineno = 0
416 while 1:
417 try:
418 for i in range(lineno, lineno + self.MAXLINES):
419 print self.__lines[i]
420 except IndexError:
421 break
422 else:
423 lineno += self.MAXLINES
424 key = None
425 while key is None:
426 key = raw_input(prompt)
427 if key not in ('', 'q'):
428 key = None
429 if key == 'q':
430 break
432 def setcopyright():
433 """Set 'copyright' and 'credits' in __builtin__"""
434 __builtin__.copyright = _Printer("copyright", sys.copyright)
435 if sys.platform[:4] == 'java':
436 __builtin__.credits = _Printer(
437 "credits",
438 "Jython is maintained by the Jython developers (www.jython.org).")
439 else:
440 __builtin__.credits = _Printer("credits", """\
441 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
442 for supporting Python development. See www.python.org for more information.""")
443 here = os.path.dirname(os.__file__)
444 __builtin__.license = _Printer(
445 "license", "See http://www.python.org/%.3s/license.html" % sys.version,
446 ["LICENSE.txt", "LICENSE"],
447 [os.path.join(here, os.pardir), here, os.curdir])
450 class _Helper(object):
451 """Define the built-in 'help'.
452 This is a wrapper around pydoc.help (with a twist).
456 def __repr__(self):
457 return "Type help() for interactive help, " \
458 "or help(object) for help about object."
459 def __call__(self, *args, **kwds):
460 import pydoc
461 return pydoc.help(*args, **kwds)
463 def sethelper():
464 __builtin__.help = _Helper()
466 def aliasmbcs():
467 """On Windows, some default encodings are not provided by Python,
468 while they are always available as "mbcs" in each locale. Make
469 them usable by aliasing to "mbcs" in such a case."""
470 if sys.platform == 'win32':
471 import locale, codecs
472 enc = locale.getdefaultlocale()[1]
473 if enc.startswith('cp'): # "cp***" ?
474 try:
475 codecs.lookup(enc)
476 except LookupError:
477 import encodings
478 encodings._cache[enc] = encodings._unknown
479 encodings.aliases.aliases[enc] = 'mbcs'
481 def setencoding():
482 """Set the string encoding used by the Unicode implementation. The
483 default is 'ascii', but if you're willing to experiment, you can
484 change this."""
485 encoding = "ascii" # Default value set by _PyUnicode_Init()
486 if 0:
487 # Enable to support locale aware default string encodings.
488 import locale
489 loc = locale.getdefaultlocale()
490 if loc[1]:
491 encoding = loc[1]
492 if 0:
493 # Enable to switch off string to Unicode coercion and implicit
494 # Unicode to string conversion.
495 encoding = "undefined"
496 if encoding != "ascii":
497 # On Non-Unicode builds this will raise an AttributeError...
498 sys.setdefaultencoding(encoding) # Needs Python Unicode build !
501 def execsitecustomize():
502 """Run custom site specific code, if available."""
503 try:
504 import sitecustomize
505 except ImportError:
506 pass
509 def execusercustomize():
510 """Run custom user specific code, if available."""
511 try:
512 import usercustomize
513 except ImportError:
514 pass
517 def main():
518 global ENABLE_USER_SITE
520 abs__file__()
521 known_paths = removeduppaths()
522 if (os.name == "posix" and sys.path and
523 os.path.basename(sys.path[-1]) == "Modules"):
524 addbuilddir()
525 if ENABLE_USER_SITE is None:
526 ENABLE_USER_SITE = check_enableusersite()
527 known_paths = addusersitepackages(known_paths)
528 known_paths = addsitepackages(known_paths)
529 if sys.platform == 'os2emx':
530 setBEGINLIBPATH()
531 setquit()
532 setcopyright()
533 sethelper()
534 aliasmbcs()
535 setencoding()
536 execsitecustomize()
537 if ENABLE_USER_SITE:
538 execusercustomize()
539 # Remove sys.setdefaultencoding() so that users cannot change the
540 # encoding after initialization. The test for presence is needed when
541 # this module is run as a script, because this code is executed twice.
542 if hasattr(sys, "setdefaultencoding"):
543 del sys.setdefaultencoding
545 main()
547 def _script():
548 help = """\
549 %s [--user-base] [--user-site]
551 Without arguments print some useful information
552 With arguments print the value of USER_BASE and/or USER_SITE separated
553 by '%s'.
555 Exit codes with --user-base or --user-site:
556 0 - user site directory is enabled
557 1 - user site directory is disabled by user
558 2 - uses site directory is disabled by super user
559 or for security reasons
560 >2 - unknown error
562 args = sys.argv[1:]
563 if not args:
564 print "sys.path = ["
565 for dir in sys.path:
566 print " %r," % (dir,)
567 print "]"
568 print "USER_BASE: %r (%s)" % (USER_BASE,
569 "exists" if os.path.isdir(USER_BASE) else "doesn't exist")
570 print "USER_SITE: %r (%s)" % (USER_SITE,
571 "exists" if os.path.isdir(USER_SITE) else "doesn't exist")
572 print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE
573 sys.exit(0)
575 buffer = []
576 if '--user-base' in args:
577 buffer.append(USER_BASE)
578 if '--user-site' in args:
579 buffer.append(USER_SITE)
581 if buffer:
582 print os.pathsep.join(buffer)
583 if ENABLE_USER_SITE:
584 sys.exit(0)
585 elif ENABLE_USER_SITE is False:
586 sys.exit(1)
587 elif ENABLE_USER_SITE is None:
588 sys.exit(2)
589 else:
590 sys.exit(3)
591 else:
592 import textwrap
593 print textwrap.dedent(help % (sys.argv[0], os.pathsep))
594 sys.exit(10)
596 if __name__ == '__main__':
597 _script()