1
|
1 |
# Copyright (C) 2005, Giovanni Bajo
|
|
2 |
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
|
|
3 |
#
|
|
4 |
# This program is free software; you can redistribute it and/or
|
|
5 |
# modify it under the terms of the GNU General Public License
|
|
6 |
# as published by the Free Software Foundation; either version 2
|
|
7 |
# of the License, or (at your option) any later version.
|
|
8 |
#
|
|
9 |
# In addition to the permissions in the GNU General Public License, the
|
|
10 |
# authors give you unlimited permission to link or embed the compiled
|
|
11 |
# version of this file into combinations with other programs, and to
|
|
12 |
# distribute those combinations without any restriction coming from the
|
|
13 |
# use of this file. (The General Public License restrictions do apply in
|
|
14 |
# other respects; for example, they cover modification of the file, and
|
|
15 |
# distribution when not linked into a combine executable.)
|
|
16 |
#
|
|
17 |
# This program is distributed in the hope that it will be useful,
|
|
18 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 |
# GNU General Public License for more details.
|
|
21 |
#
|
|
22 |
# You should have received a copy of the GNU General Public License
|
|
23 |
# along with this program; if not, write to the Free Software
|
|
24 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
25 |
|
|
26 |
# **NOTE** This module is used during bootstrap. Import *ONLY* builtin modules.
|
|
27 |
import sys
|
|
28 |
import imp
|
|
29 |
import marshal
|
|
30 |
|
|
31 |
try:
|
|
32 |
py_version = sys.version_info
|
|
33 |
except AttributeError:
|
|
34 |
py_version = (1,5)
|
|
35 |
|
|
36 |
#=======================Owners==========================#
|
|
37 |
# An Owner does imports from a particular piece of turf
|
|
38 |
# That is, there's an Owner for each thing on sys.path
|
|
39 |
# There are owners for directories and .pyz files.
|
|
40 |
# There could be owners for zip files, or even URLs.
|
|
41 |
# A shadowpath (a dictionary mapping the names in
|
|
42 |
# sys.path to their owners) is used so that sys.path
|
|
43 |
# (or a package's __path__) is still a bunch of strings,
|
|
44 |
|
|
45 |
STRINGTYPE = type('')
|
|
46 |
|
|
47 |
class Owner:
|
|
48 |
def __init__(self, path):
|
|
49 |
self.path = path
|
|
50 |
def __str__(self):
|
|
51 |
return self.path
|
|
52 |
def getmod(self, nm):
|
|
53 |
return None
|
|
54 |
class DirOwner(Owner):
|
|
55 |
def __init__(self, path):
|
|
56 |
if path == '':
|
|
57 |
path = _os_getcwd()
|
|
58 |
if not pathisdir(path):
|
|
59 |
raise ValueError, "%s is not a directory" % path
|
|
60 |
Owner.__init__(self, path)
|
|
61 |
def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module):
|
|
62 |
pth = _os_path_join(self.path, nm)
|
|
63 |
possibles = [(pth, 0, None)]
|
|
64 |
if pathisdir(pth):
|
|
65 |
possibles.insert(0, (_os_path_join(pth, '__init__'), 1, pth))
|
|
66 |
py = pyc = None
|
|
67 |
for pth, ispkg, pkgpth in possibles:
|
|
68 |
for ext, mode, typ in getsuffixes():
|
|
69 |
attempt = pth+ext
|
|
70 |
try:
|
|
71 |
st = _os_stat(attempt)
|
|
72 |
except:
|
|
73 |
pass
|
|
74 |
else:
|
|
75 |
if typ == imp.C_EXTENSION:
|
|
76 |
fp = open(attempt, 'rb')
|
|
77 |
mod = imp.load_module(nm, fp, attempt, (ext, mode, typ))
|
|
78 |
mod.__file__ = attempt
|
|
79 |
return mod
|
|
80 |
elif typ == imp.PY_SOURCE:
|
|
81 |
py = (attempt, st)
|
|
82 |
else:
|
|
83 |
pyc = (attempt, st)
|
|
84 |
if py or pyc:
|
|
85 |
break
|
|
86 |
if py is None and pyc is None:
|
|
87 |
return None
|
|
88 |
while 1:
|
|
89 |
if pyc is None or py and pyc[1][8] < py[1][8]:
|
|
90 |
try:
|
|
91 |
co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec')
|
|
92 |
break
|
|
93 |
except SyntaxError, e:
|
|
94 |
print "Invalid syntax in %s" % py[0]
|
|
95 |
print e.args
|
|
96 |
raise
|
|
97 |
elif pyc:
|
|
98 |
stuff = open(pyc[0], 'rb').read()
|
|
99 |
try:
|
|
100 |
co = loadco(stuff[8:])
|
|
101 |
break
|
|
102 |
except (ValueError, EOFError):
|
|
103 |
pyc = None
|
|
104 |
else:
|
|
105 |
return None
|
|
106 |
mod = newmod(nm)
|
|
107 |
mod.__file__ = co.co_filename
|
|
108 |
if ispkg:
|
|
109 |
mod.__path__ = [pkgpth]
|
|
110 |
subimporter = PathImportDirector(mod.__path__)
|
|
111 |
mod.__importsub__ = subimporter.getmod
|
|
112 |
mod.__co__ = co
|
|
113 |
return mod
|
|
114 |
|
|
115 |
_globalownertypes = [
|
|
116 |
DirOwner,
|
|
117 |
Owner,
|
|
118 |
]
|
|
119 |
|
|
120 |
#===================Import Directors====================================#
|
|
121 |
# ImportDirectors live on the metapath
|
|
122 |
# There's one for builtins, one for frozen modules, and one for sys.path
|
|
123 |
# Windows gets one for modules gotten from the Registry
|
|
124 |
# Mac would have them for PY_RESOURCE modules etc.
|
|
125 |
# A generalization of Owner - their concept of "turf" is broader
|
|
126 |
|
|
127 |
class ImportDirector(Owner):
|
|
128 |
pass
|
|
129 |
class BuiltinImportDirector(ImportDirector):
|
|
130 |
def __init__(self):
|
|
131 |
self.path = 'Builtins'
|
|
132 |
def getmod(self, nm, isbuiltin=imp.is_builtin):
|
|
133 |
if isbuiltin(nm):
|
|
134 |
mod = imp.load_module(nm, None, nm, ('','',imp.C_BUILTIN))
|
|
135 |
return mod
|
|
136 |
return None
|
|
137 |
class FrozenImportDirector(ImportDirector):
|
|
138 |
def __init__(self):
|
|
139 |
self.path = 'FrozenModules'
|
|
140 |
def getmod(self, nm, isfrozen=imp.is_frozen):
|
|
141 |
if isfrozen(nm):
|
|
142 |
mod = imp.load_module(nm, None, nm, ('','',imp.PY_FROZEN))
|
|
143 |
if hasattr(mod, '__path__'):
|
|
144 |
mod.__importsub__ = lambda name, pname=nm, owner=self: owner.getmod(pname+'.'+name)
|
|
145 |
return mod
|
|
146 |
return None
|
|
147 |
class RegistryImportDirector(ImportDirector):
|
|
148 |
# for Windows only
|
|
149 |
def __init__(self):
|
|
150 |
self.path = "WindowsRegistry"
|
|
151 |
self.map = {}
|
|
152 |
try:
|
|
153 |
import win32api
|
|
154 |
## import win32con
|
|
155 |
except ImportError:
|
|
156 |
pass
|
|
157 |
else:
|
|
158 |
HKEY_CURRENT_USER = -2147483647
|
|
159 |
HKEY_LOCAL_MACHINE = -2147483646
|
|
160 |
KEY_ALL_ACCESS = 983103
|
|
161 |
KEY_READ = 131097
|
|
162 |
subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver
|
|
163 |
for root in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE):
|
|
164 |
try:
|
|
165 |
#hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS)
|
|
166 |
hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_READ)
|
|
167 |
except:
|
|
168 |
pass
|
|
169 |
else:
|
|
170 |
numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
|
|
171 |
for i in range(numsubkeys):
|
|
172 |
subkeyname = win32api.RegEnumKey(hkey, i)
|
|
173 |
#hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_ALL_ACCESS)
|
|
174 |
hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_READ)
|
|
175 |
val = win32api.RegQueryValueEx(hskey, '')
|
|
176 |
desc = getDescr(val[0])
|
|
177 |
self.map[subkeyname] = (val[0], desc)
|
|
178 |
hskey.Close()
|
|
179 |
hkey.Close()
|
|
180 |
break
|
|
181 |
def getmod(self, nm):
|
|
182 |
stuff = self.map.get(nm)
|
|
183 |
if stuff:
|
|
184 |
fnm, desc = stuff
|
|
185 |
fp = open(fnm, 'rb')
|
|
186 |
mod = imp.load_module(nm, fp, fnm, desc)
|
|
187 |
mod.__file__ = fnm
|
|
188 |
return mod
|
|
189 |
return None
|
|
190 |
|
|
191 |
class PathImportDirector(ImportDirector):
|
|
192 |
def __init__(self, pathlist=None, importers=None, ownertypes=None):
|
|
193 |
if pathlist is None:
|
|
194 |
self.path = sys.path
|
|
195 |
else:
|
|
196 |
self.path = pathlist
|
|
197 |
if ownertypes == None:
|
|
198 |
self.ownertypes = _globalownertypes
|
|
199 |
else:
|
|
200 |
self.ownertypes = ownertypes
|
|
201 |
if importers:
|
|
202 |
self.shadowpath = importers
|
|
203 |
else:
|
|
204 |
self.shadowpath = {}
|
|
205 |
self.inMakeOwner = 0
|
|
206 |
self.building = {}
|
|
207 |
def getmod(self, nm):
|
|
208 |
mod = None
|
|
209 |
for thing in self.path:
|
|
210 |
if type(thing) is STRINGTYPE:
|
|
211 |
owner = self.shadowpath.get(thing, -1)
|
|
212 |
if owner == -1:
|
|
213 |
owner = self.shadowpath[thing] = self.makeOwner(thing)
|
|
214 |
if owner:
|
|
215 |
mod = owner.getmod(nm)
|
|
216 |
else:
|
|
217 |
mod = thing.getmod(nm)
|
|
218 |
if mod:
|
|
219 |
break
|
|
220 |
return mod
|
|
221 |
def makeOwner(self, path):
|
|
222 |
if self.building.get(path):
|
|
223 |
return None
|
|
224 |
self.building[path] = 1
|
|
225 |
owner = None
|
|
226 |
for klass in self.ownertypes:
|
|
227 |
try:
|
|
228 |
# this may cause an import, which may cause recursion
|
|
229 |
# hence the protection
|
|
230 |
owner = klass(path)
|
|
231 |
except:
|
|
232 |
pass
|
|
233 |
else:
|
|
234 |
break
|
|
235 |
del self.building[path]
|
|
236 |
return owner
|
|
237 |
|
|
238 |
def getDescr(fnm):
|
|
239 |
ext = getpathext(fnm)
|
|
240 |
for (suffix, mode, typ) in imp.get_suffixes():
|
|
241 |
if suffix == ext:
|
|
242 |
return (suffix, mode, typ)
|
|
243 |
|
|
244 |
#=================ImportManager============================#
|
|
245 |
# The one-and-only ImportManager
|
|
246 |
# ie, the builtin import
|
|
247 |
|
|
248 |
UNTRIED = -1
|
|
249 |
|
|
250 |
class ImportManager:
|
|
251 |
# really the equivalent of builtin import
|
|
252 |
def __init__(self):
|
|
253 |
self.metapath = [
|
|
254 |
BuiltinImportDirector(),
|
|
255 |
FrozenImportDirector(),
|
|
256 |
RegistryImportDirector(),
|
|
257 |
PathImportDirector()
|
|
258 |
]
|
|
259 |
self.threaded = 0
|
|
260 |
self.rlock = None
|
|
261 |
self.locker = None
|
|
262 |
self.setThreaded()
|
|
263 |
def setThreaded(self):
|
|
264 |
thread = sys.modules.get('thread', None)
|
|
265 |
if thread and not self.threaded:
|
|
266 |
## print "iu setting threaded"
|
|
267 |
self.threaded = 1
|
|
268 |
self.rlock = thread.allocate_lock()
|
|
269 |
self._get_ident = thread.get_ident
|
|
270 |
def install(self):
|
|
271 |
import __builtin__
|
|
272 |
__builtin__.__import__ = self.importHook
|
|
273 |
__builtin__.reload = self.reloadHook
|
|
274 |
def importHook(self, name, globals=None, locals=None, fromlist=None):
|
|
275 |
# first see if we could be importing a relative name
|
|
276 |
#print "importHook(%s, %s, locals, %s)" % (name, globals['__name__'], fromlist)
|
|
277 |
_sys_modules_get = sys.modules.get
|
|
278 |
contexts = [None]
|
|
279 |
if globals:
|
|
280 |
importernm = globals.get('__name__', '')
|
|
281 |
if importernm:
|
|
282 |
if hasattr(_sys_modules_get(importernm), '__path__'):
|
|
283 |
# If you use the "from __init__ import" syntax, the package
|
|
284 |
# name will have a __init__ in it. We want to strip it.
|
|
285 |
if importernm[-len(".__init__"):] == ".__init__":
|
|
286 |
importernm = importernm[:-len(".__init__")]
|
|
287 |
contexts.insert(0,importernm)
|
|
288 |
else:
|
|
289 |
pkgnm = packagename(importernm)
|
|
290 |
if pkgnm:
|
|
291 |
contexts.insert(0,pkgnm)
|
|
292 |
# so contexts is [pkgnm, None] or just [None]
|
|
293 |
# now break the name being imported up so we get:
|
|
294 |
# a.b.c -> [a, b, c]
|
|
295 |
nmparts = namesplit(name)
|
|
296 |
_self_doimport = self.doimport
|
|
297 |
threaded = self.threaded
|
|
298 |
for context in contexts:
|
|
299 |
ctx = context
|
|
300 |
for i in range(len(nmparts)):
|
|
301 |
nm = nmparts[i]
|
|
302 |
#print " importHook trying %s in %s" % (nm, ctx)
|
|
303 |
if ctx:
|
|
304 |
fqname = ctx + '.' + nm
|
|
305 |
else:
|
|
306 |
fqname = nm
|
|
307 |
if threaded:
|
|
308 |
self._acquire()
|
|
309 |
mod = _sys_modules_get(fqname, UNTRIED)
|
|
310 |
if mod is UNTRIED:
|
|
311 |
try:
|
|
312 |
mod = _self_doimport(nm, ctx, fqname)
|
|
313 |
except:
|
|
314 |
if threaded:
|
|
315 |
self._release()
|
|
316 |
raise
|
|
317 |
if threaded:
|
|
318 |
self._release()
|
|
319 |
if mod:
|
|
320 |
ctx = fqname
|
|
321 |
else:
|
|
322 |
break
|
|
323 |
else:
|
|
324 |
# no break, point i beyond end
|
|
325 |
i = i + 1
|
|
326 |
if i:
|
|
327 |
break
|
|
328 |
|
|
329 |
if i<len(nmparts):
|
|
330 |
if ctx and hasattr(sys.modules[ctx], nmparts[i]):
|
|
331 |
#print "importHook done with %s %s %s (case 1)" % (name, globals['__name__'], fromlist)
|
|
332 |
return sys.modules[nmparts[0]]
|
|
333 |
del sys.modules[fqname]
|
|
334 |
raise ImportError, "No module named %s" % fqname
|
|
335 |
if fromlist is None:
|
|
336 |
#print "importHook done with %s %s %s (case 2)" % (name, globals['__name__'], fromlist)
|
|
337 |
if context:
|
|
338 |
return sys.modules[context+'.'+nmparts[0]]
|
|
339 |
return sys.modules[nmparts[0]]
|
|
340 |
bottommod = sys.modules[ctx]
|
|
341 |
if hasattr(bottommod, '__path__'):
|
|
342 |
fromlist = list(fromlist)
|
|
343 |
i = 0
|
|
344 |
while i < len(fromlist):
|
|
345 |
nm = fromlist[i]
|
|
346 |
if nm == '*':
|
|
347 |
fromlist[i:i+1] = list(getattr(bottommod, '__all__', []))
|
|
348 |
if i >= len(fromlist):
|
|
349 |
break
|
|
350 |
nm = fromlist[i]
|
|
351 |
i = i + 1
|
|
352 |
if not hasattr(bottommod, nm):
|
|
353 |
if threaded:
|
|
354 |
self._acquire()
|
|
355 |
try:
|
|
356 |
mod = self.doimport(nm, ctx, ctx+'.'+nm)
|
|
357 |
except:
|
|
358 |
pass
|
|
359 |
if threaded:
|
|
360 |
self._release()
|
|
361 |
#print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist)
|
|
362 |
return bottommod
|
|
363 |
def doimport(self, nm, parentnm, fqname, reload=0):
|
|
364 |
# Not that nm is NEVER a dotted name at this point
|
|
365 |
#print "doimport(%s, %s, %s)" % (nm, parentnm, fqname)
|
|
366 |
if parentnm:
|
|
367 |
parent = sys.modules[parentnm]
|
|
368 |
if hasattr(parent, '__path__'):
|
|
369 |
importfunc = getattr(parent, '__importsub__', None)
|
|
370 |
if not importfunc:
|
|
371 |
subimporter = PathImportDirector(parent.__path__)
|
|
372 |
importfunc = parent.__importsub__ = subimporter.getmod
|
|
373 |
mod = importfunc(nm)
|
|
374 |
if mod and not reload:
|
|
375 |
setattr(parent, nm, mod)
|
|
376 |
else:
|
|
377 |
#print "..parent not a package"
|
|
378 |
return None
|
|
379 |
else:
|
|
380 |
# now we're dealing with an absolute import
|
|
381 |
for director in self.metapath:
|
|
382 |
mod = director.getmod(nm)
|
|
383 |
if mod:
|
|
384 |
break
|
|
385 |
if mod:
|
|
386 |
mod.__name__ = fqname
|
|
387 |
if reload:
|
|
388 |
sys.modules[fqname].__dict__.update(mod.__dict__)
|
|
389 |
else:
|
|
390 |
sys.modules[fqname] = mod
|
|
391 |
if hasattr(mod, '__co__'):
|
|
392 |
co = mod.__co__
|
|
393 |
del mod.__co__
|
|
394 |
try:
|
|
395 |
if reload:
|
|
396 |
exec co in sys.modules[fqname].__dict__
|
|
397 |
else:
|
|
398 |
exec co in mod.__dict__
|
|
399 |
except:
|
|
400 |
# In Python 2.4 and above, sys.modules is left clean
|
|
401 |
# after a broken import. We need to do the same to
|
|
402 |
# achieve perfect compatibility (see ticket #32).
|
|
403 |
if py_version >= (2,4,0):
|
|
404 |
# FIXME: how can we recover from a broken reload()?
|
|
405 |
# Should we save the mod dict and restore it in case
|
|
406 |
# of failure?
|
|
407 |
if not reload:
|
|
408 |
del sys.modules[fqname]
|
|
409 |
raise
|
|
410 |
if fqname == 'thread' and not self.threaded:
|
|
411 |
## print "thread detected!"
|
|
412 |
self.setThreaded()
|
|
413 |
else:
|
|
414 |
sys.modules[fqname] = None
|
|
415 |
#print "..found %s" % mod
|
|
416 |
return mod
|
|
417 |
def reloadHook(self, mod):
|
|
418 |
fqnm = mod.__name__
|
|
419 |
nm = namesplit(fqnm)[-1]
|
|
420 |
parentnm = packagename(fqnm)
|
|
421 |
newmod = self.doimport(nm, parentnm, fqnm, reload=1)
|
|
422 |
#mod.__dict__.update(newmod.__dict__)
|
|
423 |
return newmod
|
|
424 |
def _acquire(self):
|
|
425 |
if self.rlock.locked():
|
|
426 |
if self.locker == self._get_ident():
|
|
427 |
self.lockcount = self.lockcount + 1
|
|
428 |
## print "_acquire incrementing lockcount to", self.lockcount
|
|
429 |
return
|
|
430 |
self.rlock.acquire()
|
|
431 |
self.locker = self._get_ident()
|
|
432 |
self.lockcount = 0
|
|
433 |
## print "_acquire first time!"
|
|
434 |
def _release(self):
|
|
435 |
if self.lockcount:
|
|
436 |
self.lockcount = self.lockcount - 1
|
|
437 |
## print "_release decrementing lockcount to", self.lockcount
|
|
438 |
else:
|
|
439 |
self.locker = None
|
|
440 |
self.rlock.release()
|
|
441 |
## print "_release releasing lock!"
|
|
442 |
|
|
443 |
#=========some helper functions=============================#
|
|
444 |
|
|
445 |
def packagename(s):
|
|
446 |
for i in range(len(s)-1, -1, -1):
|
|
447 |
if s[i] == '.':
|
|
448 |
break
|
|
449 |
else:
|
|
450 |
return ''
|
|
451 |
return s[:i]
|
|
452 |
|
|
453 |
def namesplit(s):
|
|
454 |
rslt = []
|
|
455 |
i = j = 0
|
|
456 |
for j in range(len(s)):
|
|
457 |
if s[j] == '.':
|
|
458 |
rslt.append(s[i:j])
|
|
459 |
i = j+1
|
|
460 |
if i < len(s):
|
|
461 |
rslt.append(s[i:])
|
|
462 |
return rslt
|
|
463 |
|
|
464 |
def getpathext(fnm):
|
|
465 |
for i in range(len(fnm)-1, -1, -1):
|
|
466 |
if fnm[i] == '.':
|
|
467 |
return fnm[i:]
|
|
468 |
return ''
|
|
469 |
|
|
470 |
def pathisdir(pathname):
|
|
471 |
"Local replacement for os.path.isdir()."
|
|
472 |
try:
|
|
473 |
s = _os_stat(pathname)
|
|
474 |
except OSError:
|
|
475 |
return None
|
|
476 |
return (s[0] & 0170000) == 0040000
|
|
477 |
|
|
478 |
_os_stat = _os_path_join = _os_getcwd = _os_path_dirname = None
|
|
479 |
def _os_bootstrap():
|
|
480 |
"Set up 'os' module replacement functions for use during import bootstrap."
|
|
481 |
|
|
482 |
names = sys.builtin_module_names
|
|
483 |
|
|
484 |
join = dirname = None
|
|
485 |
mindirlen = 0
|
|
486 |
if 'posix' in names:
|
|
487 |
sep = '/'
|
|
488 |
mindirlen = 1
|
|
489 |
from posix import stat, getcwd
|
|
490 |
elif 'nt' in names:
|
|
491 |
sep = '\\'
|
|
492 |
mindirlen = 3
|
|
493 |
from nt import stat, getcwd
|
|
494 |
elif 'dos' in names:
|
|
495 |
sep = '\\'
|
|
496 |
mindirlen = 3
|
|
497 |
from dos import stat, getcwd
|
|
498 |
elif 'os2' in names:
|
|
499 |
sep = '\\'
|
|
500 |
from os2 import stat, getcwd
|
|
501 |
elif 'mac' in names:
|
|
502 |
from mac import stat, getcwd
|
|
503 |
def join(a, b):
|
|
504 |
if a == '':
|
|
505 |
return b
|
|
506 |
path = s
|
|
507 |
if ':' not in a:
|
|
508 |
a = ':' + a
|
|
509 |
if a[-1:] != ':':
|
|
510 |
a = a + ':'
|
|
511 |
return a + b
|
|
512 |
else:
|
|
513 |
raise ImportError, 'no os specific module found'
|
|
514 |
|
|
515 |
if join is None:
|
|
516 |
def join(a, b, sep=sep):
|
|
517 |
if a == '':
|
|
518 |
return b
|
|
519 |
lastchar = a[-1:]
|
|
520 |
if lastchar == '/' or lastchar == sep:
|
|
521 |
return a + b
|
|
522 |
return a + sep + b
|
|
523 |
|
|
524 |
if dirname is None:
|
|
525 |
def dirname(a, sep=sep, mindirlen=mindirlen):
|
|
526 |
for i in range(len(a)-1, -1, -1):
|
|
527 |
c = a[i]
|
|
528 |
if c == '/' or c == sep:
|
|
529 |
if i < mindirlen:
|
|
530 |
return a[:i+1]
|
|
531 |
return a[:i]
|
|
532 |
return ''
|
|
533 |
|
|
534 |
global _os_stat
|
|
535 |
_os_stat = stat
|
|
536 |
|
|
537 |
global _os_path_join
|
|
538 |
_os_path_join = join
|
|
539 |
|
|
540 |
global _os_path_dirname
|
|
541 |
_os_path_dirname = dirname
|
|
542 |
|
|
543 |
global _os_getcwd
|
|
544 |
_os_getcwd = getcwd
|
|
545 |
|
|
546 |
_string_replace = _string_join = _string_split = None
|
|
547 |
def _string_bootstrap():
|
|
548 |
"""
|
|
549 |
Set up 'string' module replacement functions for use during import bootstrap.
|
|
550 |
|
|
551 |
During bootstrap, we can use only builtin modules since import does not work
|
|
552 |
yet. For Python 2.0+, we can use string methods so this is not a problem.
|
|
553 |
For Python 1.5, we would need the string module, so we need replacements.
|
|
554 |
"""
|
|
555 |
s = type('')
|
|
556 |
|
|
557 |
global _string_replace, _string_join, _string_split
|
|
558 |
|
|
559 |
if hasattr(s, "join"):
|
|
560 |
_string_join = s.join
|
|
561 |
else:
|
|
562 |
def join(sep, words):
|
|
563 |
res = ''
|
|
564 |
for w in words:
|
|
565 |
res = res + (sep + w)
|
|
566 |
return res[len(sep):]
|
|
567 |
_string_join = join
|
|
568 |
|
|
569 |
if hasattr(s, "split"):
|
|
570 |
_string_split = s.split
|
|
571 |
else:
|
|
572 |
def split(s, sep, maxsplit=0):
|
|
573 |
res = []
|
|
574 |
nsep = len(sep)
|
|
575 |
if nsep == 0:
|
|
576 |
return [s]
|
|
577 |
ns = len(s)
|
|
578 |
if maxsplit <= 0: maxsplit = ns
|
|
579 |
i = j = 0
|
|
580 |
count = 0
|
|
581 |
while j+nsep <= ns:
|
|
582 |
if s[j:j+nsep] == sep:
|
|
583 |
count = count + 1
|
|
584 |
res.append(s[i:j])
|
|
585 |
i = j = j + nsep
|
|
586 |
if count >= maxsplit: break
|
|
587 |
else:
|
|
588 |
j = j + 1
|
|
589 |
res.append(s[i:])
|
|
590 |
return res
|
|
591 |
_string_split = split
|
|
592 |
|
|
593 |
if hasattr(s, "replace"):
|
|
594 |
_string_replace = s.replace
|
|
595 |
else:
|
|
596 |
def replace(str, old, new):
|
|
597 |
return _string_join(new, _string_split(str, old))
|
|
598 |
_string_replace = replace
|
|
599 |
|
|
600 |
|
|
601 |
|
|
602 |
_os_bootstrap()
|
|
603 |
_string_bootstrap()
|