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 # GOOGLE(nanzhang): Don't enable user-site directories, 207 # everything's supposed to be hermetic. 208 return None 209 210 if sys.flags.no_user_site: 211 return False 212 213 if hasattr(os, "getuid") and hasattr(os, "geteuid"): 214 # check process uid == effective uid 215 if os.geteuid() != os.getuid(): 216 return None 217 if hasattr(os, "getgid") and hasattr(os, "getegid"): 218 # check process gid == effective gid 219 if os.getegid() != os.getgid(): 220 return None 221 222 return True 223 224def getuserbase(): 225 """Returns the `user base` directory path. 226 227 The `user base` directory can be used to store data. If the global 228 variable ``USER_BASE`` is not initialized yet, this function will also set 229 it. 230 """ 231 global USER_BASE 232 if USER_BASE is not None: 233 return USER_BASE 234 from sysconfig import get_config_var 235 USER_BASE = get_config_var('userbase') 236 return USER_BASE 237 238def getusersitepackages(): 239 """Returns the user-specific site-packages directory path. 240 241 If the global variable ``USER_SITE`` is not initialized yet, this 242 function will also set it. 243 """ 244 global USER_SITE 245 user_base = getuserbase() # this will also set USER_BASE 246 247 if USER_SITE is not None: 248 return USER_SITE 249 250 from sysconfig import get_path 251 import os 252 253 if sys.platform == 'darwin': 254 from sysconfig import get_config_var 255 if get_config_var('PYTHONFRAMEWORK'): 256 USER_SITE = get_path('purelib', 'osx_framework_user') 257 return USER_SITE 258 259 USER_SITE = get_path('purelib', '%s_user' % os.name) 260 return USER_SITE 261 262def addusersitepackages(known_paths): 263 """Add a per user site-package to sys.path 264 265 Each user has its own python directory with site-packages in the 266 home directory. 267 """ 268 # get the per user site-package path 269 # this call will also make sure USER_BASE and USER_SITE are set 270 user_site = getusersitepackages() 271 272 if ENABLE_USER_SITE and os.path.isdir(user_site): 273 addsitedir(user_site, known_paths) 274 return known_paths 275 276def getsitepackages(): 277 """Returns a list containing all global site-packages directories 278 (and possibly site-python). 279 280 For each directory present in the global ``PREFIXES``, this function 281 will find its `site-packages` subdirectory depending on the system 282 environment, and will return a list of full paths. 283 """ 284 sitepackages = [] 285 seen = set() 286 287 for prefix in PREFIXES: 288 if not prefix or prefix in seen: 289 continue 290 seen.add(prefix) 291 292 if sys.platform in ('os2emx', 'riscos'): 293 sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) 294 elif os.sep == '/': 295 sitepackages.append(os.path.join(prefix, "lib", 296 "python" + sys.version[:3], 297 "site-packages")) 298 sitepackages.append(os.path.join(prefix, "lib", "site-python")) 299 else: 300 sitepackages.append(prefix) 301 sitepackages.append(os.path.join(prefix, "lib", "site-packages")) 302 return sitepackages 303 304def addsitepackages(known_paths): 305 """Add site-packages (and possibly site-python) to sys.path""" 306 for sitedir in getsitepackages(): 307 if os.path.isdir(sitedir): 308 addsitedir(sitedir, known_paths) 309 310 return known_paths 311 312def setBEGINLIBPATH(): 313 """The OS/2 EMX port has optional extension modules that do double duty 314 as DLLs (and must use the .DLL file extension) for other extensions. 315 The library search path needs to be amended so these will be found 316 during module import. Use BEGINLIBPATH so that these are at the start 317 of the library search path. 318 319 """ 320 dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") 321 libpath = os.environ['BEGINLIBPATH'].split(';') 322 if libpath[-1]: 323 libpath.append(dllpath) 324 else: 325 libpath[-1] = dllpath 326 os.environ['BEGINLIBPATH'] = ';'.join(libpath) 327 328 329def setquit(): 330 """Define new builtins 'quit' and 'exit'. 331 332 These are objects which make the interpreter exit when called. 333 The repr of each object contains a hint at how it works. 334 335 """ 336 if os.sep == ':': 337 eof = 'Cmd-Q' 338 elif os.sep == '\\': 339 eof = 'Ctrl-Z plus Return' 340 else: 341 eof = 'Ctrl-D (i.e. EOF)' 342 343 class Quitter(object): 344 def __init__(self, name): 345 self.name = name 346 def __repr__(self): 347 return 'Use %s() or %s to exit' % (self.name, eof) 348 def __call__(self, code=None): 349 # Shells like IDLE catch the SystemExit, but listen when their 350 # stdin wrapper is closed. 351 try: 352 sys.stdin.close() 353 except: 354 pass 355 raise SystemExit(code) 356 __builtin__.quit = Quitter('quit') 357 __builtin__.exit = Quitter('exit') 358 359 360class _Printer(object): 361 """interactive prompt objects for printing the license text, a list of 362 contributors and the copyright notice.""" 363 364 MAXLINES = 23 365 366 def __init__(self, name, data, files=(), dirs=()): 367 self.__name = name 368 self.__data = data 369 self.__files = files 370 self.__dirs = dirs 371 self.__lines = None 372 373 def __setup(self): 374 if self.__lines: 375 return 376 data = None 377 for dir in self.__dirs: 378 for filename in self.__files: 379 filename = os.path.join(dir, filename) 380 try: 381 fp = file(filename, "rU") 382 data = fp.read() 383 fp.close() 384 break 385 except IOError: 386 pass 387 if data: 388 break 389 if not data: 390 data = self.__data 391 self.__lines = data.split('\n') 392 self.__linecnt = len(self.__lines) 393 394 def __repr__(self): 395 self.__setup() 396 if len(self.__lines) <= self.MAXLINES: 397 return "\n".join(self.__lines) 398 else: 399 return "Type %s() to see the full %s text" % ((self.__name,)*2) 400 401 def __call__(self): 402 self.__setup() 403 prompt = 'Hit Return for more, or q (and Return) to quit: ' 404 lineno = 0 405 while 1: 406 try: 407 for i in range(lineno, lineno + self.MAXLINES): 408 print self.__lines[i] 409 except IndexError: 410 break 411 else: 412 lineno += self.MAXLINES 413 key = None 414 while key is None: 415 key = raw_input(prompt) 416 if key not in ('', 'q'): 417 key = None 418 if key == 'q': 419 break 420 421def setcopyright(): 422 """Set 'copyright' and 'credits' in __builtin__""" 423 __builtin__.copyright = _Printer("copyright", sys.copyright) 424 if sys.platform[:4] == 'java': 425 __builtin__.credits = _Printer( 426 "credits", 427 "Jython is maintained by the Jython developers (www.jython.org).") 428 else: 429 __builtin__.credits = _Printer("credits", """\ 430 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands 431 for supporting Python development. See www.python.org for more information.""") 432 here = os.path.dirname(os.__file__) 433 __builtin__.license = _Printer( 434 "license", "See https://www.python.org/psf/license/", 435 ["LICENSE.txt", "LICENSE"], 436 [os.path.join(here, os.pardir), here, os.curdir]) 437 438 439class _Helper(object): 440 """Define the builtin 'help'. 441 This is a wrapper around pydoc.help (with a twist). 442 443 """ 444 445 def __repr__(self): 446 return "Type help() for interactive help, " \ 447 "or help(object) for help about object." 448 def __call__(self, *args, **kwds): 449 import pydoc 450 return pydoc.help(*args, **kwds) 451 452def sethelper(): 453 __builtin__.help = _Helper() 454 455def aliasmbcs(): 456 """On Windows, some default encodings are not provided by Python, 457 while they are always available as "mbcs" in each locale. Make 458 them usable by aliasing to "mbcs" in such a case.""" 459 if sys.platform == 'win32': 460 import locale, codecs 461 enc = locale.getdefaultlocale()[1] 462 if enc.startswith('cp'): # "cp***" ? 463 try: 464 codecs.lookup(enc) 465 except LookupError: 466 import encodings 467 encodings._cache[enc] = encodings._unknown 468 encodings.aliases.aliases[enc] = 'mbcs' 469 470def setencoding(): 471 """Set the string encoding used by the Unicode implementation. The 472 default is 'ascii', but if you're willing to experiment, you can 473 change this.""" 474 encoding = "ascii" # Default value set by _PyUnicode_Init() 475 if 0: 476 # Enable to support locale aware default string encodings. 477 import locale 478 loc = locale.getdefaultlocale() 479 if loc[1]: 480 encoding = loc[1] 481 if 0: 482 # Enable to switch off string to Unicode coercion and implicit 483 # Unicode to string conversion. 484 encoding = "undefined" 485 if encoding != "ascii": 486 # On Non-Unicode builds this will raise an AttributeError... 487 sys.setdefaultencoding(encoding) # Needs Python Unicode build ! 488 489 490def execsitecustomize(): 491 """Run custom site specific code, if available.""" 492 try: 493 import sitecustomize 494 except ImportError: 495 pass 496 except Exception: 497 if sys.flags.verbose: 498 sys.excepthook(*sys.exc_info()) 499 else: 500 print >>sys.stderr, \ 501 "'import sitecustomize' failed; use -v for traceback" 502 503 504def execusercustomize(): 505 """Run custom user specific code, if available.""" 506 try: 507 import usercustomize 508 except ImportError: 509 pass 510 except Exception: 511 if sys.flags.verbose: 512 sys.excepthook(*sys.exc_info()) 513 else: 514 print>>sys.stderr, \ 515 "'import usercustomize' failed; use -v for traceback" 516 517 518def main(): 519 global ENABLE_USER_SITE 520 521 abs__file__() 522 known_paths = removeduppaths() 523 if ENABLE_USER_SITE is None: 524 ENABLE_USER_SITE = check_enableusersite() 525 if ENABLE_USER_SITE: 526 known_paths = addusersitepackages(known_paths) 527 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 544 545main() 546 547def _script(): 548 help = """\ 549 %s [--user-base] [--user-site] 550 551 Without arguments print some useful information 552 With arguments print the value of USER_BASE and/or USER_SITE separated 553 by '%s'. 554 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 561 """ 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) 574 575 buffer = [] 576 if '--user-base' in args: 577 buffer.append(USER_BASE) 578 if '--user-site' in args: 579 buffer.append(USER_SITE) 580 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) 595 596if __name__ == '__main__': 597 _script() 598