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 118 def _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 131 def 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 172 def 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 196 def 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 220 def 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 234 def 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 258 def 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 272 def 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 os.sep == '/': 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-python")) 295 else: 296 sitepackages.append(prefix) 297 sitepackages.append(os.path.join(prefix, "lib", "site-packages")) 298 return sitepackages 299 300 def addsitepackages(known_paths): 301 """Add site-packages (and possibly site-python) to sys.path""" 302 for sitedir in getsitepackages(): 303 if os.path.isdir(sitedir): 304 addsitedir(sitedir, known_paths) 305 306 return known_paths 307 308 def setBEGINLIBPATH(): 309 """The OS/2 EMX port has optional extension modules that do double duty 310 as DLLs (and must use the .DLL file extension) for other extensions. 311 The library search path needs to be amended so these will be found 312 during module import. Use BEGINLIBPATH so that these are at the start 313 of the library search path. 314 315 """ 316 dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") 317 libpath = os.environ['BEGINLIBPATH'].split(';') 318 if libpath[-1]: 319 libpath.append(dllpath) 320 else: 321 libpath[-1] = dllpath 322 os.environ['BEGINLIBPATH'] = ';'.join(libpath) 323 324 325 def setquit(): 326 """Define new builtins 'quit' and 'exit'. 327 328 These are objects which make the interpreter exit when called. 329 The repr of each object contains a hint at how it works. 330 331 """ 332 if os.sep == ':': 333 eof = 'Cmd-Q' 334 elif os.sep == '\\': 335 eof = 'Ctrl-Z plus Return' 336 else: 337 eof = 'Ctrl-D (i.e. EOF)' 338 339 class Quitter(object): 340 def __init__(self, name): 341 self.name = name 342 def __repr__(self): 343 return 'Use %s() or %s to exit' % (self.name, eof) 344 def __call__(self, code=None): 345 # Shells like IDLE catch the SystemExit, but listen when their 346 # stdin wrapper is closed. 347 try: 348 sys.stdin.close() 349 except: 350 pass 351 raise SystemExit(code) 352 __builtin__.quit = Quitter('quit') 353 __builtin__.exit = Quitter('exit') 354 355 356 class _Printer(object): 357 """interactive prompt objects for printing the license text, a list of 358 contributors and the copyright notice.""" 359 360 MAXLINES = 23 361 362 def __init__(self, name, data, files=(), dirs=()): 363 self.__name = name 364 self.__data = data 365 self.__files = files 366 self.__dirs = dirs 367 self.__lines = None 368 369 def __setup(self): 370 if self.__lines: 371 return 372 data = None 373 for dir in self.__dirs: 374 for filename in self.__files: 375 filename = os.path.join(dir, filename) 376 try: 377 fp = file(filename, "rU") 378 data = fp.read() 379 fp.close() 380 break 381 except IOError: 382 pass 383 if data: 384 break 385 if not data: 386 data = self.__data 387 self.__lines = data.split('\n') 388 self.__linecnt = len(self.__lines) 389 390 def __repr__(self): 391 self.__setup() 392 if len(self.__lines) <= self.MAXLINES: 393 return "\n".join(self.__lines) 394 else: 395 return "Type %s() to see the full %s text" % ((self.__name,)*2) 396 397 def __call__(self): 398 self.__setup() 399 prompt = 'Hit Return for more, or q (and Return) to quit: ' 400 lineno = 0 401 while 1: 402 try: 403 for i in range(lineno, lineno + self.MAXLINES): 404 print self.__lines[i] 405 except IndexError: 406 break 407 else: 408 lineno += self.MAXLINES 409 key = None 410 while key is None: 411 key = raw_input(prompt) 412 if key not in ('', 'q'): 413 key = None 414 if key == 'q': 415 break 416 417 def setcopyright(): 418 """Set 'copyright' and 'credits' in __builtin__""" 419 __builtin__.copyright = _Printer("copyright", sys.copyright) 420 if sys.platform[:4] == 'java': 421 __builtin__.credits = _Printer( 422 "credits", 423 "Jython is maintained by the Jython developers (www.jython.org).") 424 else: 425 __builtin__.credits = _Printer("credits", """\ 426 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands 427 for supporting Python development. See www.python.org for more information.""") 428 here = os.path.dirname(os.__file__) 429 __builtin__.license = _Printer( 430 "license", "See https://www.python.org/psf/license/", 431 ["LICENSE.txt", "LICENSE"], 432 [os.path.join(here, os.pardir), here, os.curdir]) 433 434 435 class _Helper(object): 436 """Define the builtin 'help'. 437 This is a wrapper around pydoc.help (with a twist). 438 439 """ 440 441 def __repr__(self): 442 return "Type help() for interactive help, " \ 443 "or help(object) for help about object." 444 def __call__(self, *args, **kwds): 445 import pydoc 446 return pydoc.help(*args, **kwds) 447 448 def sethelper(): 449 __builtin__.help = _Helper() 450 451 def aliasmbcs(): 452 """On Windows, some default encodings are not provided by Python, 453 while they are always available as "mbcs" in each locale. Make 454 them usable by aliasing to "mbcs" in such a case.""" 455 if sys.platform == 'win32': 456 import locale, codecs 457 enc = locale.getdefaultlocale()[1] 458 if enc.startswith('cp'): # "cp***" ? 459 try: 460 codecs.lookup(enc) 461 except LookupError: 462 import encodings 463 encodings._cache[enc] = encodings._unknown 464 encodings.aliases.aliases[enc] = 'mbcs' 465 466 def setencoding(): 467 """Set the string encoding used by the Unicode implementation. The 468 default is 'ascii', but if you're willing to experiment, you can 469 change this.""" 470 encoding = "ascii" # Default value set by _PyUnicode_Init() 471 if 0: 472 # Enable to support locale aware default string encodings. 473 import locale 474 loc = locale.getdefaultlocale() 475 if loc[1]: 476 encoding = loc[1] 477 if 0: 478 # Enable to switch off string to Unicode coercion and implicit 479 # Unicode to string conversion. 480 encoding = "undefined" 481 if encoding != "ascii": 482 # On Non-Unicode builds this will raise an AttributeError... 483 sys.setdefaultencoding(encoding) # Needs Python Unicode build ! 484 485 486 def execsitecustomize(): 487 """Run custom site specific code, if available.""" 488 try: 489 import sitecustomize 490 except ImportError: 491 pass 492 except Exception: 493 if sys.flags.verbose: 494 sys.excepthook(*sys.exc_info()) 495 else: 496 print >>sys.stderr, \ 497 "'import sitecustomize' failed; use -v for traceback" 498 499 500 def execusercustomize(): 501 """Run custom user specific code, if available.""" 502 try: 503 import usercustomize 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 usercustomize' failed; use -v for traceback" 512 513 514 def main(): 515 global ENABLE_USER_SITE 516 517 abs__file__() 518 known_paths = removeduppaths() 519 if ENABLE_USER_SITE is None: 520 ENABLE_USER_SITE = check_enableusersite() 521 known_paths = addusersitepackages(known_paths) 522 known_paths = addsitepackages(known_paths) 523 if sys.platform == 'os2emx': 524 setBEGINLIBPATH() 525 setquit() 526 setcopyright() 527 sethelper() 528 aliasmbcs() 529 setencoding() 530 execsitecustomize() 531 if ENABLE_USER_SITE: 532 execusercustomize() 533 # Remove sys.setdefaultencoding() so that users cannot change the 534 # encoding after initialization. The test for presence is needed when 535 # this module is run as a script, because this code is executed twice. 536 if hasattr(sys, "setdefaultencoding"): 537 del sys.setdefaultencoding 538 539 main() 540 541 def _script(): 542 help = """\ 543 %s [--user-base] [--user-site] 544 545 Without arguments print some useful information 546 With arguments print the value of USER_BASE and/or USER_SITE separated 547 by '%s'. 548 549 Exit codes with --user-base or --user-site: 550 0 - user site directory is enabled 551 1 - user site directory is disabled by user 552 2 - uses site directory is disabled by super user 553 or for security reasons 554 >2 - unknown error 555 """ 556 args = sys.argv[1:] 557 if not args: 558 print "sys.path = [" 559 for dir in sys.path: 560 print " %r," % (dir,) 561 print "]" 562 print "USER_BASE: %r (%s)" % (USER_BASE, 563 "exists" if os.path.isdir(USER_BASE) else "doesn't exist") 564 print "USER_SITE: %r (%s)" % (USER_SITE, 565 "exists" if os.path.isdir(USER_SITE) else "doesn't exist") 566 print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE 567 sys.exit(0) 568 569 buffer = [] 570 if '--user-base' in args: 571 buffer.append(USER_BASE) 572 if '--user-site' in args: 573 buffer.append(USER_SITE) 574 575 if buffer: 576 print os.pathsep.join(buffer) 577 if ENABLE_USER_SITE: 578 sys.exit(0) 579 elif ENABLE_USER_SITE is False: 580 sys.exit(1) 581 elif ENABLE_USER_SITE is None: 582 sys.exit(2) 583 else: 584 sys.exit(3) 585 else: 586 import textwrap 587 print textwrap.dedent(help % (sys.argv[0], os.pathsep)) 588 sys.exit(10) 589 590 if __name__ == '__main__': 591 _script() 592