buildframework/helium/tools/startup/bootstrap/site.py
changeset 1 be27ed110b50
equal deleted inserted replaced
0:044383f39525 1:be27ed110b50
       
     1 #============================================================================ 
       
     2 #Name        : site.py 
       
     3 #Part of     : Helium 
       
     4 
       
     5 #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     6 #All rights reserved.
       
     7 #This component and the accompanying materials are made available
       
     8 #under the terms of the License "Eclipse Public License v1.0"
       
     9 #which accompanies this distribution, and is available
       
    10 #at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
    11 #
       
    12 #Initial Contributors:
       
    13 #Nokia Corporation - initial contribution.
       
    14 #
       
    15 #Contributors:
       
    16 #
       
    17 #Description:
       
    18 #===============================================================================
       
    19 
       
    20 # Duplicating setuptools' site.py...
       
    21 def __boot():
       
    22     PYTHONPATH = []    
       
    23     if sys.platform=='win32':
       
    24         PYTHONPATH.append(os.path.join(sys.prefix, 'lib'))
       
    25     if not (os.environ.get('PYTHONPATH') is None or (sys.platform=='win32' and not os.environ.get('PYTHONPATH'))):
       
    26         PYTHONPATH.extend(os.environ.get('PYTHONPATH').split(os.pathsep))
       
    27     pic = getattr(sys,'path_importer_cache',{})
       
    28     stdpath = sys.path[len(PYTHONPATH):]
       
    29     mydir = os.path.dirname(__file__)
       
    30     known_paths = dict([(makepath(item)[1],1) for item in sys.path]) # 2.2 comp
       
    31 
       
    32     oldpos = getattr(sys,'__egginsert',0)   # save old insertion position
       
    33     sys.__egginsert = 0                     # and reset the current one
       
    34 
       
    35     for item in PYTHONPATH:
       
    36         addsitedir(item)
       
    37         item_site_packages = os.path.join(item, 'site-packages')
       
    38         if os.path.exists(item_site_packages):
       
    39             addsitedir(item_site_packages)
       
    40 
       
    41     sys.__egginsert += oldpos           # restore effective old position
       
    42 
       
    43     d,nd = makepath(stdpath[0])
       
    44     insert_at = None
       
    45     new_path = []
       
    46 
       
    47     for item in sys.path:
       
    48         p,np = makepath(item)
       
    49 
       
    50         if np==nd and insert_at is None:
       
    51             # We've hit the first 'system' path entry, so added entries go here
       
    52             insert_at = len(new_path)
       
    53 
       
    54         if np in known_paths or insert_at is None:
       
    55             new_path.append(item)
       
    56         else:
       
    57             # new path after the insert point, back-insert it
       
    58             new_path.insert(insert_at, item)
       
    59             insert_at += 1
       
    60 
       
    61     sys.path[:] = new_path
       
    62     
       
    63 import sys
       
    64 import os
       
    65 import __builtin__
       
    66 
       
    67 def makepath(*paths):
       
    68     dir = os.path.abspath(os.path.join(*paths))
       
    69     return dir, os.path.normcase(dir)
       
    70 
       
    71 def abs__file__():
       
    72     """Set all module' __file__ attribute to an absolute path"""
       
    73     for m in sys.modules.values():
       
    74         try:
       
    75             m.__file__ = os.path.abspath(m.__file__)
       
    76         except AttributeError:
       
    77             continue
       
    78 
       
    79 try:
       
    80     set
       
    81 except NameError:
       
    82     class set:
       
    83         def __init__(self, args=()):
       
    84             self.d = {}
       
    85             for v in args:
       
    86                 self.d[v] = None
       
    87         def __contains__(self, key):
       
    88             return key in self.d
       
    89         def add(self, key):
       
    90             self.d[key] = None
       
    91 
       
    92 def removeduppaths():
       
    93     """ Remove duplicate entries from sys.path along with making them
       
    94     absolute"""
       
    95     # This ensures that the initial path provided by the interpreter contains
       
    96     # only absolute pathnames, even if we're running from the build directory.
       
    97     L = []
       
    98     known_paths = set()
       
    99     for dir in sys.path:
       
   100         # Filter out duplicate paths (on case-insensitive file systems also
       
   101         # if they only differ in case); turn relative paths into absolute
       
   102         # paths.
       
   103         dir, dircase = makepath(dir)
       
   104         if not dircase in known_paths:
       
   105             L.append(dir)
       
   106             known_paths.add(dircase)
       
   107     sys.path[:] = L
       
   108     return known_paths
       
   109 
       
   110 def _init_pathinfo():
       
   111     """Return a set containing all existing directory entries from sys.path"""
       
   112     d = set()
       
   113     for dir in sys.path:
       
   114         try:
       
   115             if os.path.isdir(dir):
       
   116                 dir, dircase = makepath(dir)
       
   117                 d.add(dircase)
       
   118         except TypeError:
       
   119             continue
       
   120     return d
       
   121 
       
   122 def addpackage(sitedir, name, known_paths, exclude_packages=()):
       
   123     """Add a new path to known_paths by combining sitedir and 'name' or execute
       
   124     sitedir if it starts with 'import'"""
       
   125     import fnmatch
       
   126     if known_paths is None:
       
   127         _init_pathinfo()
       
   128         reset = 1
       
   129     else:
       
   130         reset = 0
       
   131     fullname = os.path.join(sitedir, name)
       
   132     try:
       
   133         f = open(fullname, "rU")
       
   134     except IOError:
       
   135         return
       
   136     try:
       
   137         for line in f:
       
   138             if line.startswith("#"):
       
   139                 continue
       
   140             found_exclude = False
       
   141             for exclude in exclude_packages:
       
   142                 if exclude(line):
       
   143                     found_exclude = True
       
   144                     break
       
   145             if found_exclude:
       
   146                 continue
       
   147             if line.startswith("import"):
       
   148                 exec line
       
   149                 continue
       
   150             line = line.rstrip()
       
   151             dir, dircase = makepath(sitedir, line)
       
   152             if not dircase in known_paths and os.path.exists(dir):
       
   153                 sys.path.append(dir)
       
   154                 known_paths.add(dircase)
       
   155     finally:
       
   156         f.close()
       
   157     if reset:
       
   158         known_paths = None
       
   159     return known_paths
       
   160 
       
   161 def addsitedir(sitedir, known_paths=None, exclude_packages=()):
       
   162     """Add 'sitedir' argument to sys.path if missing and handle .pth files in
       
   163     'sitedir'"""
       
   164     if known_paths is None:
       
   165         known_paths = _init_pathinfo()
       
   166         reset = 1
       
   167     else:
       
   168         reset = 0
       
   169     sitedir, sitedircase = makepath(sitedir)
       
   170     if not sitedircase in known_paths:
       
   171         sys.path.append(sitedir)        # Add path component
       
   172     try:
       
   173         names = os.listdir(sitedir)
       
   174     except os.error:
       
   175         return
       
   176     names.sort()
       
   177     for name in names:
       
   178         if name.endswith(os.extsep + "pth"):
       
   179             addpackage(sitedir, name, known_paths,
       
   180                        exclude_packages=exclude_packages)
       
   181     if reset:
       
   182         known_paths = None
       
   183     return known_paths
       
   184 
       
   185 def addsitepackages(known_paths):
       
   186     """Add site-packages (and possibly site-python) to sys.path"""
       
   187     prefixes = [os.path.join(sys.prefix, "local"), sys.prefix]
       
   188     if sys.exec_prefix != sys.prefix:
       
   189         prefixes.append(os.path.join(sys.exec_prefix, "local"))
       
   190     for prefix in prefixes:
       
   191         if prefix:
       
   192             if sys.platform in ('os2emx', 'riscos'):
       
   193                 sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
       
   194             elif os.sep == '/':
       
   195                 sitedirs = [os.path.join(prefix,
       
   196                                          "lib",
       
   197                                          "python" + sys.version[:3],
       
   198                                          "site-packages"),
       
   199                             os.path.join(prefix, "lib", "site-python")]
       
   200                 try:
       
   201                     # sys.getobjects only available in --with-pydebug build
       
   202                     # pylint: disable-msg=E1101
       
   203                     sys.getobjects
       
   204                     sitedirs.insert(0, os.path.join(sitedirs[0], 'debug'))
       
   205                 except AttributeError:
       
   206                     pass
       
   207             else:
       
   208                 sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]
       
   209             if sys.platform == 'darwin':
       
   210                 sitedirs.append( os.path.join('/opt/local', 'lib', 'python' + sys.version[:3], 'site-packages') )
       
   211                 # for framework builds *only* we add the standard Apple
       
   212                 # locations. Currently only per-user, but /Library and
       
   213                 # /Network/Library could be added too
       
   214                 if 'Python.framework' in prefix:
       
   215                     home = os.environ.get('HOME')
       
   216                     if home:
       
   217                         sitedirs.append(
       
   218                             os.path.join(home,
       
   219                                          'Library',
       
   220                                          'Python',
       
   221                                          sys.version[:3],
       
   222                                          'site-packages'))
       
   223             for sitedir in sitedirs:
       
   224                 if os.path.isdir(sitedir):
       
   225                     addsitedir(sitedir, known_paths,
       
   226                                exclude_packages=[lambda line: 'setuptools' in line])
       
   227     return None
       
   228 
       
   229 def setquit():
       
   230     """Define new built-ins 'quit' and 'exit'.
       
   231     These are simply strings that display a hint on how to exit.
       
   232 
       
   233     """
       
   234     if os.sep == ':':
       
   235         exit = 'Use Cmd-Q to quit.'
       
   236     elif os.sep == '\\':
       
   237         exit = 'Use Ctrl-Z plus Return to exit.'
       
   238     else:
       
   239         exit = 'Use Ctrl-D (i.e. EOF) to exit.'
       
   240     __builtin__.quit = __builtin__.exit = exit
       
   241 
       
   242 
       
   243 class _Printer(object):
       
   244     """interactive prompt objects for printing the license text, a list of
       
   245     contributors and the copyright notice."""
       
   246 
       
   247     MAXLINES = 23
       
   248 
       
   249     def __init__(self, name, data, files=(), dirs=()):
       
   250         self.__name = name
       
   251         self.__data = data
       
   252         self.__files = files
       
   253         self.__dirs = dirs
       
   254         self.__lines = None
       
   255 
       
   256     def __setup(self):
       
   257         if self.__lines:
       
   258             return
       
   259         data = None
       
   260         for dir in self.__dirs:
       
   261             for filename in self.__files:
       
   262                 filename = os.path.join(dir, filename)
       
   263                 try:
       
   264                     fp = file(filename, "rU")
       
   265                     data = fp.read()
       
   266                     fp.close()
       
   267                     break
       
   268                 except IOError:
       
   269                     pass
       
   270             if data:
       
   271                 break
       
   272         if not data:
       
   273             data = self.__data
       
   274         self.__lines = data.split('\n')
       
   275         self.__linecnt = len(self.__lines)
       
   276 
       
   277     def __repr__(self):
       
   278         self.__setup()
       
   279         if len(self.__lines) <= self.MAXLINES:
       
   280             return "\n".join(self.__lines)
       
   281         else:
       
   282             return "Type %s() to see the full %s text" % ((self.__name,)*2)
       
   283 
       
   284     def __call__(self):
       
   285         self.__setup()
       
   286         prompt = 'Hit Return for more, or q (and Return) to quit: '
       
   287         lineno = 0
       
   288         while 1:
       
   289             try:
       
   290                 for i in range(lineno, lineno + self.MAXLINES):
       
   291                     print self.__lines[i]
       
   292             except IndexError:
       
   293                 break
       
   294             else:
       
   295                 lineno += self.MAXLINES
       
   296                 key = None
       
   297                 while key is None:
       
   298                     key = raw_input(prompt)
       
   299                     if key not in ('', 'q'):
       
   300                         key = None
       
   301                 if key == 'q':
       
   302                     break
       
   303 
       
   304 def setcopyright():
       
   305     """Set 'copyright' and 'credits' in __builtin__"""
       
   306     __builtin__.copyright = _Printer("copyright", sys.copyright)
       
   307     if sys.platform[:4] == 'java':
       
   308         __builtin__.credits = _Printer(
       
   309             "credits",
       
   310             "Jython is maintained by the Jython developers (www.jython.org).")
       
   311     else:
       
   312         __builtin__.credits = _Printer("credits", """\
       
   313     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
       
   314     for supporting Python development.  See www.python.org for more information.""")
       
   315     here = os.path.dirname(os.__file__)
       
   316     __builtin__.license = _Printer(
       
   317         "license", "See http://www.python.org/%.3s/license.html" % sys.version,
       
   318         ["LICENSE.txt", "LICENSE"],
       
   319         [os.path.join(here, os.pardir), here, os.curdir])
       
   320 
       
   321 
       
   322 class _Helper(object):
       
   323     """Define the built-in 'help'.
       
   324     This is a wrapper around pydoc.help (with a twist).
       
   325 
       
   326     """
       
   327 
       
   328     def __repr__(self):
       
   329         return "Type help() for interactive help, " \
       
   330                "or help(object) for help about object."
       
   331     def __call__(self, *args, **kwds):
       
   332         import pydoc
       
   333         return pydoc.help(*args, **kwds)
       
   334 
       
   335 def sethelper():
       
   336     __builtin__.help = _Helper()
       
   337 
       
   338 def aliasmbcs():
       
   339     """On Windows, some default encodings are not provided by Python,
       
   340     while they are always available as "mbcs" in each locale. Make
       
   341     them usable by aliasing to "mbcs" in such a case."""
       
   342     if sys.platform == 'win32':
       
   343         import locale, codecs
       
   344         enc = locale.getdefaultlocale()[1]
       
   345         if enc.startswith('cp'):            # "cp***" ?
       
   346             try:
       
   347                 codecs.lookup(enc)
       
   348             except LookupError:
       
   349                 import encodings
       
   350                 encodings._cache[enc] = encodings._unknown
       
   351                 encodings.aliases.aliases[enc] = 'mbcs'
       
   352 
       
   353 def setencoding():
       
   354     """Set the string encoding used by the Unicode implementation.  The
       
   355     default is 'ascii', but if you're willing to experiment, you can
       
   356     change this."""
       
   357     encoding = "ascii" # Default value set by _PyUnicode_Init()
       
   358     if 0:
       
   359         # Enable to support locale aware default string encodings.
       
   360         import locale
       
   361         loc = locale.getdefaultlocale()
       
   362         if loc[1]:
       
   363             encoding = loc[1]
       
   364     if 0:
       
   365         # Enable to switch off string to Unicode coercion and implicit
       
   366         # Unicode to string conversion.
       
   367         encoding = "undefined"
       
   368     if encoding != "ascii":
       
   369         # On Non-Unicode builds this will raise an AttributeError...
       
   370         sys.setdefaultencoding(encoding) # Needs Python Unicode build !
       
   371 
       
   372 
       
   373 def execsitecustomize():
       
   374     """Run custom site specific code, if available."""
       
   375     try:
       
   376         import sitecustomize
       
   377     except ImportError:
       
   378         pass
       
   379 
       
   380 def fixup_setuptools():
       
   381     """Make sure our setuptools monkeypatch is in place"""
       
   382     for i in range(len(sys.path)):
       
   383         if sys.path[i].find('setuptools') != -1:
       
   384             path = sys.path[i]
       
   385             del sys.path[i]
       
   386             sys.path.append(path)
       
   387 
       
   388 def main():
       
   389     abs__file__()
       
   390     paths_in_sys = removeduppaths()
       
   391     if include_site_packages:
       
   392         paths_in_sys = addsitepackages(paths_in_sys)
       
   393     setquit()
       
   394     setcopyright()
       
   395     sethelper()
       
   396     aliasmbcs()
       
   397     setencoding()
       
   398     execsitecustomize()
       
   399     # Remove sys.setdefaultencoding() so that users cannot change the
       
   400     # encoding after initialization.  The test for presence is needed when
       
   401     # this module is run as a script, because this code is executed twice.
       
   402     if hasattr(sys, "setdefaultencoding"):
       
   403         del sys.setdefaultencoding
       
   404     __boot()
       
   405     fixup_setuptools()
       
   406     
       
   407 
       
   408 
       
   409 include_site_packages = False
       
   410 
       
   411 
       
   412 
       
   413 main()