source: python/trunk/Lib/site.py@ 393

Last change on this file since 393 was 393, checked in by dmik, 11 years ago

python: Fix merge typos.

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