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