1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 __builtin__ 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 __builtin__ name space come from
39 our 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 5110 2010/07/25 16:14:38 bdeegan"
64
66 """
67 Imports the specified module (from our local directory) as the
68 specified name.
69 """
70 import imp
71 import os.path
72 dir = os.path.split(__file__)[0]
73 file, filename, suffix_mode_type = imp.find_module(module, [dir])
74 imp.load_module(name, file, filename, suffix_mode_type)
75
76 import builtins
77
78 try:
79 import hashlib
80 except ImportError:
81
82 try:
83 import_as('_scons_hashlib', 'hashlib')
84 except ImportError:
85
86
87
88
89 pass
90
91 try:
92 set
93 except NameError:
94
95 try:
96
97
98 import_as('_scons_sets', 'sets')
99 except (ImportError, SyntaxError):
100
101
102
103
104
105 import_as('_scons_sets15', 'sets')
106 import __builtin__
107 import sets
108 __builtin__.set = sets.Set
109
110 import fnmatch
111 try:
112 fnmatch.filter
113 except AttributeError:
114
116 """Return the subset of the list NAMES that match PAT"""
117 import os,posixpath
118 result=[]
119 pat = os.path.normcase(pat)
120 if not fnmatch._cache.has_key(pat):
121 import re
122 res = fnmatch.translate(pat)
123 fnmatch._cache[pat] = re.compile(res)
124 match = fnmatch._cache[pat].match
125 if os.path is posixpath:
126
127 for name in names:
128 if match(name):
129 result.append(name)
130 else:
131 for name in names:
132 if match(os.path.normcase(name)):
133 result.append(name)
134 return result
135 fnmatch.filter = filter
136 del filter
137
138 try:
139 import itertools
140 except ImportError:
141
142 import_as('_scons_itertools', 'itertools')
143
144
145
146 try:
147 import textwrap
148 except ImportError:
149
150 import_as('_scons_textwrap', 'textwrap')
151
152 try:
153 import optparse
154 except ImportError:
155
156 import_as('_scons_optparse', 'optparse')
157
158 import os
159 try:
160 os.devnull
161 except AttributeError:
162
163 import sys
164 _names = sys.builtin_module_names
165 if 'posix' in _names:
166 os.devnull = '/dev/null'
167 elif 'nt' in _names:
168 os.devnull = 'nul'
169 os.path.devnull = os.devnull
170 try:
171 os.path.lexists
172 except AttributeError:
173
176 os.path.lexists = lexists
177
178
179 try:
180 import platform
181 except ImportError:
182
183 import_as('_scons_platform', 'platform')
184
185
186 import shlex
187 try:
188 shlex.split
189 except AttributeError:
190
191
192
193
194
195
196 del shlex
197 import_as('_scons_shlex', 'shlex')
198
199
200 import shutil
201 try:
202 shutil.move
203 except AttributeError:
204
205
206
207 import os
208
209 - def move(src, dst):
210 """Recursively move a file or directory to another location.
211
212 If the destination is on our current filesystem, then simply use
213 rename. Otherwise, copy src to the dst and then remove src.
214 A lot more could be done here... A look at a mv.c shows a lot of
215 the issues this implementation glosses over.
216
217 """
218 try:
219 os.rename(src, dst)
220 except OSError:
221 if os.path.isdir(src):
222 if shutil.destinsrc(src, dst):
223 raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
224 shutil.copytree(src, dst, symlinks=True)
225 shutil.rmtree(src)
226 else:
227 shutil.copy2(src,dst)
228 os.unlink(src)
229 shutil.move = move
230 del move
231
233 src = os.path.abspath(src)
234 return os.path.abspath(dst)[:len(src)] == src
235 shutil.destinsrc = destinsrc
236 del destinsrc
237
238
239 try:
240 import subprocess
241 except ImportError:
242
243 import_as('_scons_subprocess', 'subprocess')
244
245 import sys
246 try:
247 sys.version_info
248 except AttributeError:
249
250 import string
251 version_string = string.split(sys.version)[0]
252 version_ints = map(int, string.split(version_string, '.'))
253 sys.version_info = tuple(version_ints + ['final', 0])
254
255 try:
256 import UserString
257 except ImportError:
258
259 import_as('_scons_UserString', 'UserString')
260
261 import tempfile
262 try:
263 tempfile.mkstemp
264 except AttributeError:
265
266
267 import os
268 import errno
270 text = False
271
272
273 if 'text' in kw.keys() :
274 text = kw['text']
275 del kw['text']
276 elif len( args ) == 4 :
277 text = args[3]
278 args = args[:3]
279 flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
280 if not text and hasattr( os, 'O_BINARY' ) :
281 flags = flags | os.O_BINARY
282 while True:
283 try :
284 name = apply(tempfile.mktemp, args, kw)
285 fd = os.open( name, flags, 0600 )
286 return (fd, os.path.abspath(name))
287 except OSError, e:
288 if e.errno == errno.EEXIST:
289 continue
290 raise
291
292 tempfile.mkstemp = mkstemp
293 del mkstemp
294
295
296
297
298
299
300
301
302
303