blob: bcccaa58d9f8f490dc497db30fa4a698d69d908c [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001import imp
2import os
3import sys
4from marshal import Unmarshaller
5
6__debugging__ = False
7
8def __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
17def __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
25class __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
63class __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
83sys.meta_path.insert(0, __MetaImporter())