| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame^] | 1 | import imp |
| 2 | import os |
| 3 | import sys |
| 4 | from marshal import Unmarshaller |
| 5 | |
| 6 | __debugging__ = False |
| 7 | |
| 8 | def __readPycHeader(file): |
| 9 | def read(): |
| 10 | return ord(file.read(1)) |
| 11 | magic = read() | (read()<<8) |
| 12 | if not ( file.read(1) == '\r' and file.read(1) == '\n' ): |
| 13 | raise TypeError("not valid pyc-file") |
| 14 | mtime = read() | (read()<<8) | (read()<<16) | (read()<<24) |
| 15 | return magic, mtime |
| 16 | |
| 17 | def __makeModule(name, code, path): |
| 18 | module = sys.modules.get(name) |
| 19 | if not module: |
| 20 | module = sys.modules[name] = imp.new_module(name) |
| 21 | module.__file__ = path |
| 22 | exec code in module.__dict__ |
| 23 | return module |
| 24 | |
| 25 | class __Importer(object): |
| 26 | def __init__(self, path): |
| 27 | if __debugging__: print "Importer invoked" |
| 28 | self.__path = path |
| 29 | def find_module(self, fullname, path=None): |
| 30 | if __debugging__: |
| 31 | print "Importer.find_module(fullname=%s, path=%s)" % ( |
| 32 | repr(fullname), repr(path)) |
| 33 | path = fullname.split('.') |
| 34 | filename = path[-1] |
| 35 | path = path[:-1] |
| 36 | pycfile = os.path.join(self.__path, *(path + [filename + '.pyc'])) |
| 37 | pyfile = os.path.join(self.__path, *(path + [filename + '.py'])) |
| 38 | if os.path.exists(pycfile): |
| 39 | f = open(pycfile, 'rb') |
| 40 | try: |
| 41 | magic, mtime = __readPycHeader(f) |
| 42 | except: |
| 43 | return None # abort! not a valid pyc-file |
| 44 | f.close() |
| 45 | if os.path.exists(pyfile): |
| 46 | pytime = os.stat(pyfile).st_mtime |
| 47 | if pytime > mtime: |
| 48 | return None # abort! py-file was newer |
| 49 | return self |
| 50 | else: |
| 51 | return None # abort! pyc-file does not exist |
| 52 | def load_module(self, fullname): |
| 53 | path = fullname.split('.') |
| 54 | path[-1] += '.pyc' |
| 55 | filename = os.path.join(self.__path, *path) |
| 56 | f = open(filename, 'rb') |
| 57 | magic, mtime = __readPycHeader(f) |
| 58 | #code = Unmarshaller(f, magic=magic).load() |
| 59 | code = Unmarshaller(f).load() |
| 60 | if __debugging__: print "Successfully loaded:", fullname |
| 61 | return __makeModule( fullname, code, filename ) |
| 62 | |
| 63 | class __MetaImporter(object): |
| 64 | def __init__(self): |
| 65 | self.__importers = {} |
| 66 | def find_module(self, fullname, path): |
| 67 | if __debugging__: print "MetaImporter.find_module(%s, %s)" % ( |
| 68 | repr(fullname), repr(path)) |
| 69 | for _path in sys.path: |
| 70 | if _path not in self.__importers: |
| 71 | try: |
| 72 | self.__importers[_path] = __Importer(_path) |
| 73 | except: |
| 74 | self.__importers[_path] = None |
| 75 | importer = self.__importers[_path] |
| 76 | if importer is not None: |
| 77 | loader = importer.find_module(fullname, path) |
| 78 | if loader is not None: |
| 79 | return loader |
| 80 | else: |
| 81 | return None |
| 82 | |
| 83 | sys.meta_path.insert(0, __MetaImporter()) |