root/galaxy-central/eggs/Cheetah-2.2.2-py2.6-macosx-10.6-universal-ucs2.egg/Cheetah/ImportManager.py @ 3

リビジョン 3, 17.9 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# $Id: ImportManager.py,v 1.6 2007/04/03 01:56:24 tavis_rudd Exp $
2
3"""Provides an emulator/replacement for Python's standard import system.
4
5@@TR: Be warned that Import Hooks are in the deepest, darkest corner of Python's
6jungle.  If you need to start hacking with this, be prepared to get lost for a
7while. Also note, this module predates the newstyle import hooks in Python 2.3
8http://www.python.org/peps/pep-0302.html. 
9
10
11This is a hacked/documented version of Gordon McMillan's iu.py. I have:
12
13  - made it a little less terse
14
15  - added docstrings and explanatations
16
17  - standardized the variable naming scheme
18
19  - reorganized the code layout to enhance readability
20
21Meta-Data
22================================================================================
23Author: Tavis Rudd <tavis@damnsimple.com>  based on Gordon McMillan's iu.py
24License: This software is released for unlimited distribution under the
25         terms of the MIT license.  See the LICENSE file.
26Version: $Revision: 1.6 $
27Start Date: 2001/03/30
28Last Revision Date: $Date: 2007/04/03 01:56:24 $
29"""
30__author__ = "Tavis Rudd <tavis@damnsimple.com>"
31__revision__ = "$Revision: 1.6 $"[11:-2]
32
33##################################################
34## DEPENDENCIES
35
36import sys
37import imp
38import marshal
39
40##################################################
41## CONSTANTS & GLOBALS
42
43try:
44    True,False
45except NameError:
46    True, False = (1==1),(1==0)
47
48_installed = False
49
50STRINGTYPE = type('')
51
52# _globalOwnerTypes is defined at the bottom of this file
53
54_os_stat = _os_path_join = _os_getcwd = _os_path_dirname = None
55
56##################################################
57## FUNCTIONS
58
59def _os_bootstrap():
60    """Set up 'os' module replacement functions for use during import bootstrap."""
61
62    names = sys.builtin_module_names
63
64    join = dirname = None
65    if 'posix' in names:
66        sep = '/'
67        from posix import stat, getcwd
68    elif 'nt' in names:
69        sep = '\\'
70        from nt import stat, getcwd
71    elif 'dos' in names:
72        sep = '\\'
73        from dos import stat, getcwd
74    elif 'os2' in names:
75        sep = '\\'
76        from os2 import stat, getcwd
77    elif 'mac' in names:
78        from mac import stat, getcwd
79        def join(a, b):
80            if a == '':
81                return b
82            if ':' not in a:
83                a = ':' + a
84            if a[-1:] != ':':
85                a = a + ':'
86            return a + b
87    else:
88        raise ImportError, 'no os specific module found'
89
90    if join is None:
91        def join(a, b, sep=sep):
92            if a == '':
93                return b
94            lastchar = a[-1:]
95            if lastchar == '/' or lastchar == sep:
96                return a + b
97            return a + sep + b
98
99    if dirname is None:
100        def dirname(a, sep=sep):
101            for i in range(len(a)-1, -1, -1):
102                c = a[i]
103                if c == '/' or c == sep:
104                    return a[:i]
105            return ''
106   
107    global _os_stat
108    _os_stat = stat
109
110    global _os_path_join
111    _os_path_join = join
112
113    global _os_path_dirname
114    _os_path_dirname = dirname
115   
116    global _os_getcwd
117    _os_getcwd = getcwd
118   
119_os_bootstrap()
120
121def packageName(s):
122    for i in range(len(s)-1, -1, -1):
123        if s[i] == '.':
124            break
125    else:
126        return ''
127    return s[:i]
128
129def nameSplit(s):
130    rslt = []
131    i = j = 0
132    for j in range(len(s)):
133        if s[j] == '.':
134            rslt.append(s[i:j])
135            i = j+1
136    if i < len(s):
137        rslt.append(s[i:])
138    return rslt
139
140def getPathExt(fnm):
141    for i in range(len(fnm)-1, -1, -1):
142        if fnm[i] == '.':
143            return fnm[i:]
144    return ''
145
146def pathIsDir(pathname):
147    "Local replacement for os.path.isdir()."
148    try:
149        s = _os_stat(pathname)
150    except OSError:
151        return None
152    return (s[0] & 0170000) == 0040000
153
154def getDescr(fnm):
155    ext = getPathExt(fnm)
156    for (suffix, mode, typ) in imp.get_suffixes():
157        if suffix == ext:
158            return (suffix, mode, typ)
159
160##################################################
161## CLASSES
162
163class Owner:
164   
165    """An Owner does imports from a particular piece of turf That is, there's
166    an Owner for each thing on sys.path There are owners for directories and
167    .pyz files.  There could be owners for zip files, or even URLs.  A
168    shadowpath (a dictionary mapping the names in sys.path to their owners) is
169    used so that sys.path (or a package's __path__) is still a bunch of strings,
170    """
171   
172    def __init__(self, path):
173        self.path = path
174
175    def __str__(self):
176        return self.path
177   
178    def getmod(self, nm):
179        return None
180   
181class DirOwner(Owner):
182   
183    def __init__(self, path):
184        if path == '':
185            path = _os_getcwd()
186        if not pathIsDir(path):
187            raise ValueError, "%s is not a directory" % path
188        Owner.__init__(self, path)
189       
190    def getmod(self, nm,
191               getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module):
192       
193        pth =  _os_path_join(self.path, nm)
194
195        possibles = [(pth, 0, None)]
196        if pathIsDir(pth):
197            possibles.insert(0, (_os_path_join(pth, '__init__'), 1, pth))
198        py = pyc = None
199        for pth, ispkg, pkgpth in possibles:
200            for ext, mode, typ in getsuffixes():
201                attempt = pth+ext
202                try:
203                    st = _os_stat(attempt)
204                except:
205                    pass
206                else:
207                    if typ == imp.C_EXTENSION:
208                        fp = open(attempt, 'rb')
209                        mod = imp.load_module(nm, fp, attempt, (ext, mode, typ))
210                        mod.__file__ = attempt
211                        return mod
212                    elif typ == imp.PY_SOURCE:
213                        py = (attempt, st)
214                    else:
215                        pyc = (attempt, st)
216            if py or pyc:
217                break
218        if py is None and pyc is None:
219            return None
220        while 1:
221            if pyc is None or py and pyc[1][8] < py[1][8]:
222                try:
223                    co = compile(open(py[0], 'r').read()+'\n', py[0], 'exec')
224                    break
225                except SyntaxError, e:
226                    print "Invalid syntax in %s" % py[0]
227                    print e.args
228                    raise
229            elif pyc:
230                stuff = open(pyc[0], 'rb').read()
231                try:
232                    co = loadco(stuff[8:])
233                    break
234                except (ValueError, EOFError):
235                    pyc = None
236            else:
237                return None
238        mod = newmod(nm)
239        mod.__file__ = co.co_filename
240        if ispkg:
241            mod.__path__ = [pkgpth]
242            subimporter = PathImportDirector(mod.__path__)
243            mod.__importsub__ = subimporter.getmod
244        mod.__co__ = co
245        return mod
246
247
248class ImportDirector(Owner):
249    """ImportDirectors live on the metapath There's one for builtins, one for
250    frozen modules, and one for sys.path Windows gets one for modules gotten
251    from the Registry Mac would have them for PY_RESOURCE modules etc.  A
252    generalization of Owner - their concept of 'turf' is broader"""
253
254    pass
255
256class BuiltinImportDirector(ImportDirector):
257    """Directs imports of builtin modules"""
258    def __init__(self):
259        self.path = 'Builtins'
260
261    def getmod(self, nm, isbuiltin=imp.is_builtin):
262        if isbuiltin(nm):
263            mod = imp.load_module(nm, None, nm, ('','',imp.C_BUILTIN))
264            return mod
265        return None
266
267class FrozenImportDirector(ImportDirector):
268    """Directs imports of frozen modules"""
269   
270    def __init__(self):
271        self.path = 'FrozenModules'
272
273    def getmod(self, nm,
274               isFrozen=imp.is_frozen, loadMod=imp.load_module):
275        if isFrozen(nm):
276            mod = loadMod(nm, None, nm, ('','',imp.PY_FROZEN))
277            if hasattr(mod, '__path__'):
278                mod.__importsub__ = lambda name, pname=nm, owner=self: owner.getmod(pname+'.'+name)
279            return mod
280        return None
281
282
283class RegistryImportDirector(ImportDirector):
284    """Directs imports of modules stored in the Windows Registry"""
285
286    def __init__(self):
287        self.path = "WindowsRegistry"
288        self.map = {}
289        try:
290            import win32api
291            ## import win32con
292        except ImportError:
293            pass
294        else:
295            HKEY_CURRENT_USER = -2147483647
296            HKEY_LOCAL_MACHINE = -2147483646
297            KEY_ALL_ACCESS = 983103
298            subkey = r"Software\Python\PythonCore\%s\Modules" % sys.winver
299            for root in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE):
300                try:
301                    hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS)
302                except:
303                    pass
304                else:
305                    numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
306                    for i in range(numsubkeys):
307                        subkeyname = win32api.RegEnumKey(hkey, i)
308                        hskey = win32api.RegOpenKeyEx(hkey, subkeyname, 0, KEY_ALL_ACCESS)
309                        val = win32api.RegQueryValueEx(hskey, '')
310                        desc = getDescr(val[0])
311                        self.map[subkeyname] = (val[0], desc)
312                        hskey.Close()
313                    hkey.Close()
314                    break
315               
316    def getmod(self, nm):
317        stuff = self.map.get(nm)
318        if stuff:
319            fnm, desc = stuff
320            fp = open(fnm, 'rb')
321            mod = imp.load_module(nm, fp, fnm, desc)
322            mod.__file__ = fnm
323            return mod
324        return None
325   
326class PathImportDirector(ImportDirector):
327    """Directs imports of modules stored on the filesystem."""
328
329    def __init__(self, pathlist=None, importers=None, ownertypes=None):
330        if pathlist is None:
331            self.path = sys.path
332        else:
333            self.path = pathlist
334        if ownertypes == None:
335            self._ownertypes = _globalOwnerTypes
336        else:
337            self._ownertypes = ownertypes
338        if importers:
339            self._shadowPath = importers
340        else:
341            self._shadowPath = {}
342        self._inMakeOwner = False
343        self._building = {}
344       
345    def getmod(self, nm):
346        mod = None
347        for thing in self.path:
348            if type(thing) is STRINGTYPE:
349                owner = self._shadowPath.get(thing, -1)
350                if owner == -1:
351                    owner = self._shadowPath[thing] = self._makeOwner(thing)
352                if owner:
353                    mod = owner.getmod(nm)
354            else:
355                mod = thing.getmod(nm)
356            if mod:
357                break
358        return mod
359   
360    def _makeOwner(self, path):
361        if self._building.get(path):
362            return None
363        self._building[path] = 1
364        owner = None
365        for klass in self._ownertypes:
366            try:
367                # this may cause an import, which may cause recursion
368                # hence the protection
369                owner = klass(path)
370            except:
371                pass
372            else:
373                break
374        del self._building[path]
375        return owner
376
377#=================ImportManager============================#
378# The one-and-only ImportManager
379# ie, the builtin import
380
381UNTRIED = -1
382
383class ImportManager:
384    # really the equivalent of builtin import
385    def __init__(self):
386        self.metapath = [
387            BuiltinImportDirector(),
388            FrozenImportDirector(),
389            RegistryImportDirector(),
390            PathImportDirector()
391        ]
392        self.threaded = 0
393        self.rlock = None
394        self.locker = None
395        self.setThreaded()
396       
397    def setThreaded(self):
398        thread = sys.modules.get('thread', None)
399        if thread and not self.threaded:
400            self.threaded = 1
401            self.rlock = thread.allocate_lock()
402            self._get_ident = thread.get_ident
403           
404    def install(self):
405        import __builtin__
406        __builtin__.__import__ = self.importHook
407        __builtin__.reload = self.reloadHook
408       
409    def importHook(self, name, globals=None, locals=None, fromlist=None, level=-1):
410        '''
411            NOTE: Currently importHook will accept the keyword-argument "level"
412            but it will *NOT* use it (currently). Details about the "level" keyword
413            argument can be found here: http://www.python.org/doc/2.5.2/lib/built-in-funcs.html
414        '''
415        # first see if we could be importing a relative name
416        #print "importHook(%s, %s, locals, %s)" % (name, globals['__name__'], fromlist)
417        _sys_modules_get = sys.modules.get
418        contexts = [None]
419        if globals:
420            importernm = globals.get('__name__', '')
421            if importernm:
422                if hasattr(_sys_modules_get(importernm), '__path__'):
423                    contexts.insert(0,importernm)
424                else:
425                    pkgnm = packageName(importernm)
426                    if pkgnm:
427                        contexts.insert(0,pkgnm)
428        # so contexts is [pkgnm, None] or just [None]
429        # now break the name being imported up so we get:
430        # a.b.c -> [a, b, c]
431        nmparts = nameSplit(name)
432        _self_doimport = self.doimport
433        threaded = self.threaded
434        for context in contexts:
435            ctx = context
436            for i in range(len(nmparts)):
437                nm = nmparts[i]
438                #print " importHook trying %s in %s" % (nm, ctx)
439                if ctx:
440                    fqname = ctx + '.' + nm
441                else:
442                    fqname = nm
443                if threaded:
444                    self._acquire()
445                mod = _sys_modules_get(fqname, UNTRIED)
446                if mod is UNTRIED:
447                    mod = _self_doimport(nm, ctx, fqname)
448                if threaded:
449                    self._release()
450                if mod:
451                    ctx = fqname
452                else:
453                    break
454            else:
455                # no break, point i beyond end
456                i = i + 1
457            if i:
458                break
459           
460        if i<len(nmparts):
461            if ctx and hasattr(sys.modules[ctx], nmparts[i]):
462                #print "importHook done with %s %s %s (case 1)" % (name, globals['__name__'], fromlist)
463                return sys.modules[nmparts[0]]
464            del sys.modules[fqname]
465            raise ImportError, "No module named %s" % fqname
466        if fromlist is None:
467            #print "importHook done with %s %s %s (case 2)" % (name, globals['__name__'], fromlist)
468            if context:
469                return sys.modules[context+'.'+nmparts[0]]
470            return sys.modules[nmparts[0]]
471        bottommod = sys.modules[ctx]
472        if hasattr(bottommod, '__path__'):
473            fromlist = list(fromlist)
474            i = 0
475            while i < len(fromlist):
476                nm = fromlist[i]
477                if nm == '*':
478                    fromlist[i:i+1] = list(getattr(bottommod, '__all__', []))
479                    if i >= len(fromlist):
480                        break
481                    nm = fromlist[i]
482                i = i + 1
483                if not hasattr(bottommod, nm):
484                    if self.threaded:
485                        self._acquire()
486                    mod = self.doimport(nm, ctx, ctx+'.'+nm)
487                    if self.threaded:
488                        self._release()
489                    if not mod:
490                        raise ImportError, "%s not found in %s" % (nm, ctx)
491        #print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist)
492        return bottommod
493   
494    def doimport(self, nm, parentnm, fqname):
495        # Not that nm is NEVER a dotted name at this point
496        #print "doimport(%s, %s, %s)" % (nm, parentnm, fqname)
497        if parentnm:
498            parent = sys.modules[parentnm]
499            if hasattr(parent, '__path__'):
500                importfunc = getattr(parent, '__importsub__', None)
501                if not importfunc:
502                    subimporter = PathImportDirector(parent.__path__)
503                    importfunc = parent.__importsub__ = subimporter.getmod
504                mod = importfunc(nm)
505                if mod:
506                    setattr(parent, nm, mod)
507            else:
508                #print "..parent not a package"
509                return None
510        else:
511            # now we're dealing with an absolute import
512            for director in self.metapath:
513                mod = director.getmod(nm)
514                if mod:
515                    break
516        if mod:
517            mod.__name__ = fqname
518            sys.modules[fqname] = mod
519            if hasattr(mod, '__co__'):
520                co = mod.__co__
521                del mod.__co__
522                exec co in mod.__dict__
523            if fqname == 'thread' and not self.threaded:
524##                print "thread detected!"
525                self.setThreaded()
526        else:
527            sys.modules[fqname] = None
528        #print "..found %s" % mod
529        return mod
530   
531    def reloadHook(self, mod):
532        fqnm = mod.__name__
533        nm = nameSplit(fqnm)[-1]
534        parentnm = packageName(fqnm)
535        newmod = self.doimport(nm, parentnm, fqnm)
536        mod.__dict__.update(newmod.__dict__)
537##        return newmod
538       
539    def _acquire(self):
540        if self.rlock.locked():
541            if self.locker == self._get_ident():
542                self.lockcount = self.lockcount + 1
543##                print "_acquire incrementing lockcount to", self.lockcount
544                return
545        self.rlock.acquire()
546        self.locker = self._get_ident()
547        self.lockcount = 0
548##        print "_acquire first time!"
549       
550    def _release(self):
551        if self.lockcount:
552            self.lockcount = self.lockcount - 1
553##            print "_release decrementing lockcount to", self.lockcount
554        else:
555            self.rlock.release()
556##            print "_release releasing lock!"
557
558
559##################################################
560## MORE CONSTANTS & GLOBALS
561
562_globalOwnerTypes = [
563    DirOwner,
564    Owner,
565]
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。