Package SCons :: Package compat
[hide private]
[frames] | no frames]

Source Code for Package SCons.compat

  1  # 
  2  # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation 
  3  # 
  4  # Permission is hereby granted, free of charge, to any person obtaining 
  5  # a copy of this software and associated documentation files (the 
  6  # "Software"), to deal in the Software without restriction, including 
  7  # without limitation the rights to use, copy, modify, merge, publish, 
  8  # distribute, sublicense, and/or sell copies of the Software, and to 
  9  # permit persons to whom the Software is furnished to do so, subject to 
 10  # the following conditions: 
 11  # 
 12  # The above copyright notice and this permission notice shall be included 
 13  # in all copies or substantial portions of the Software. 
 14  # 
 15  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 16  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 17  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 18  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
 19  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 20  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 21  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 22  # 
 23   
 24  __doc__ = """ 
 25  SCons compatibility package for old Python versions 
 26   
 27  This subpackage holds modules that provide backwards-compatible 
 28  implementations of various things that we'd like to use in SCons but which 
 29  only show up in later versions of Python than the early, old version(s) 
 30  we still support. 
 31   
 32  Other code will not generally reference things in this package through 
 33  the SCons.compat namespace.  The modules included here add things to 
 34  the builtins namespace or the global module list so that the rest 
 35  of our code can use the objects and names imported here regardless of 
 36  Python version. 
 37   
 38  Simply enough, things that go in the builtins name space come from 
 39  our _scons_builtins module. 
 40   
 41  The rest of the things here will be in individual compatibility modules 
 42  that are either: 1) suitably modified copies of the future modules that 
 43  we want to use; or 2) backwards compatible re-implementations of the 
 44  specific portions of a future module's API that we want to use. 
 45   
 46  GENERAL WARNINGS:  Implementations of functions in the SCons.compat 
 47  modules are *NOT* guaranteed to be fully compliant with these functions in 
 48  later versions of Python.  We are only concerned with adding functionality 
 49  that we actually use in SCons, so be wary if you lift this code for 
 50  other uses.  (That said, making these more nearly the same as later, 
 51  official versions is still a desirable goal, we just don't need to be 
 52  obsessive about it.) 
 53   
 54  We name the compatibility modules with an initial '_scons_' (for example, 
 55  _scons_subprocess.py is our compatibility module for subprocess) so 
 56  that we can still try to import the real module name and fall back to 
 57  our compatibility module if we get an ImportError.  The import_as() 
 58  function defined below loads the module as the "real" name (without the 
 59  '_scons'), after which all of the "import {module}" statements in the 
 60  rest of our code will find our pre-loaded compatibility module. 
 61  """ 
 62   
 63  __revision__ = "src/engine/SCons/compat/__init__.py 5023 2010/06/14 22:05:46 scons" 
 64   
 65  import os 
 66  import sys 
 67  import imp   # Use the "imp" module to protect imports from fixers. 
 68   
69 -def import_as(module, name):
70 """ 71 Imports the specified module (from our local directory) as the 72 specified name, returning the loaded module object. 73 """ 74 dir = os.path.split(__file__)[0] 75 return imp.load_module(name, *imp.find_module(module, [dir]))
76
77 -def rename_module(new, old):
78 """ 79 Attempts to import the old module and load it under the new name. 80 Used for purely cosmetic name changes in Python 3.x. 81 """ 82 try: 83 sys.modules[new] = imp.load_module(old, *imp.find_module(old)) 84 return True 85 except ImportError: 86 return False
87 88 89 rename_module('builtins', '__builtin__') 90 import _scons_builtins 91 92 93 try: 94 import hashlib 95 except ImportError: 96 # Pre-2.5 Python has no hashlib module. 97 try: 98 import_as('_scons_hashlib', 'hashlib') 99 except ImportError: 100 # If we failed importing our compatibility module, it probably 101 # means this version of Python has no md5 module. Don't do 102 # anything and let the higher layer discover this fact, so it 103 # can fall back to using timestamp. 104 pass 105 106 try: 107 set 108 except NameError: 109 # Pre-2.4 Python has no native set type 110 import_as('_scons_sets', 'sets') 111 import builtins, sets 112 builtins.set = sets.Set 113 114 115 try: 116 import collections 117 except ImportError: 118 # Pre-2.4 Python has no collections module. 119 import_as('_scons_collections', 'collections') 120 else: 121 try: 122 collections.UserDict 123 except AttributeError: 124 exec('from UserDict import UserDict as _UserDict') 125 collections.UserDict = _UserDict 126 del _UserDict 127 try: 128 collections.UserList 129 except AttributeError: 130 exec('from UserList import UserList as _UserList') 131 collections.UserList = _UserList 132 del _UserList 133 try: 134 collections.UserString 135 except AttributeError: 136 exec('from UserString import UserString as _UserString') 137 collections.UserString = _UserString 138 del _UserString 139 140 141 try: 142 import io 143 except ImportError: 144 # Pre-2.6 Python has no io module. 145 import_as('_scons_io', 'io') 146 147 148 try: 149 os.devnull 150 except AttributeError: 151 # Pre-2.4 Python has no os.devnull attribute 152 _names = sys.builtin_module_names 153 if 'posix' in _names: 154 os.devnull = '/dev/null' 155 elif 'nt' in _names: 156 os.devnull = 'nul' 157 os.path.devnull = os.devnull 158 try: 159 os.path.lexists 160 except AttributeError: 161 # Pre-2.4 Python has no os.path.lexists function
162 - def lexists(path):
163 return os.path.exists(path) or os.path.islink(path)
164 os.path.lexists = lexists 165 166 167 # When we're using the '-3' option during regression tests, importing 168 # cPickle gives a warning no matter how it's done, so always use the 169 # real profile module, whether it's fast or not. 170 if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is None: 171 # Not a regression test with '-3', so try to use faster version. 172 # In 3.x, 'pickle' automatically loads the fast version if available. 173 rename_module('pickle', 'cPickle') 174 175 176 # In 3.x, 'profile' automatically loads the fast version if available. 177 rename_module('profile', 'cProfile') 178 179 180 # Before Python 3.0, the 'queue' module was named 'Queue'. 181 rename_module('queue', 'Queue') 182 183 184 # Before Python 3.0, the 'winreg' module was named '_winreg' 185 rename_module('winreg', '_winreg') 186 187 188 try: 189 import subprocess 190 except ImportError: 191 # Pre-2.4 Python has no subprocess module. 192 import_as('_scons_subprocess', 'subprocess') 193 194 try: 195 sys.intern 196 except AttributeError: 197 # Pre-2.6 Python has no sys.intern() function. 198 import builtins 199 try: 200 sys.intern = builtins.intern 201 except AttributeError: 202 # Pre-2.x Python has no builtin intern() function.
203 - def intern(x):
204 return x
205 sys.intern = intern 206 del intern 207 try: 208 sys.maxsize 209 except AttributeError: 210 # Pre-2.6 Python has no sys.maxsize attribute 211 # Wrapping sys in () is silly, but protects it from 2to3 renames fixer 212 sys.maxsize = (sys).maxint 213 214 215 if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None: 216 # We can't apply the 'callable' fixer until the floor is 2.6, but the 217 # '-3' option to Python 2.6 and 2.7 generates almost ten thousand 218 # warnings. This hack allows us to run regression tests with the '-3' 219 # option by replacing the callable() built-in function with a hack 220 # that performs the same function but doesn't generate the warning. 221 # Note that this hack is ONLY intended to be used for regression 222 # testing, and should NEVER be used for real runs. 223 from types import ClassType
224 - def callable(obj):
225 if hasattr(obj, '__call__'): return True 226 if isinstance(obj, (ClassType, type)): return True 227 return False
228 import builtins 229 builtins.callable = callable 230 del callable 231 232 233 # Local Variables: 234 # tab-width:4 235 # indent-tabs-mode:nil 236 # End: 237 # vim: set expandtab tabstop=4 shiftwidth=4: 238