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