1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
"""
$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/quixote/ptl/ptl_import.py $
$Id: ptl_import.py 26357 2005-03-16 14:56:23Z dbinger $
Import hooks; when installed, these hooks allow importing .ptl files
as if they were Python modules.
Note: there's some unpleasant incompatibility between ZODB's import
trickery and the import hooks here. Bottom line: if you're using ZODB,
import it *before* installing the PTL import hooks.
"""
import sys
import os.path
import imp, ihooks, new
import struct
import marshal
import __builtin__
from ptl_compile import compile_template, PTL_EXT
assert sys.hexversion >= 0x20000b1, "need Python 2.0b1 or later"
def _exec_module_code(code, name, filename):
if sys.modules.has_key(name):
mod = sys.modules[name] # necessary for reload()
else:
mod = new.module(name)
sys.modules[name] = mod
mod.__name__ = name
mod.__file__ = filename
exec code in mod.__dict__
return mod
def _timestamp(filename):
try:
s = os.stat(filename)
except OSError:
return None
return s.st_mtime
def _load_pyc(name, filename, pyc_filename):
try:
fp = open(pyc_filename, "rb")
except IOError:
return None
if fp.read(4) == imp.get_magic():
mtime = struct.unpack('<I', fp.read(4))[0]
ptl_mtime = _timestamp(filename)
if ptl_mtime is not None and mtime >= ptl_mtime:
code = marshal.load(fp)
return _exec_module_code(code, name, filename)
return None
def _load_ptl(name, filename, file=None):
if not file:
try:
file = open(filename, "rb")
except IOError:
return None
path, ext = os.path.splitext(filename)
pyc_filename = path + ".pyc"
module = _load_pyc(name, filename, pyc_filename)
if module is not None:
return module
try:
output = open(pyc_filename, "wb")
except IOError:
output = None
try:
code = compile_template(file, filename, output)
except:
if output:
output.close()
os.unlink(pyc_filename)
raise
else:
if output:
output.close()
return _exec_module_code(code, name, filename)
# Constant used to signal a PTL files
PTL_FILE = object()
class PTLHooks(ihooks.Hooks):
def get_suffixes(self):
# add our suffixes
return [(PTL_EXT, 'r', PTL_FILE)] + imp.get_suffixes()
class PTLLoader(ihooks.ModuleLoader):
def load_module(self, name, stuff):
file, filename, info = stuff
(suff, mode, type) = info
# If it's a PTL file, load it specially.
if type is PTL_FILE:
return _load_ptl(name, filename, file)
else:
# Otherwise, use the default handler for loading
return ihooks.ModuleLoader.load_module(self, name, stuff)
try:
import cimport
except ImportError:
cimport = None
class cModuleImporter(ihooks.ModuleImporter):
def __init__(self, loader=None):
self.loader = loader or ihooks.ModuleLoader()
cimport.set_loader(self.find_import_module)
def find_import_module(self, fullname, subname, path):
stuff = self.loader.find_module(subname, path)
if not stuff:
return None
return self.loader.load_module(fullname, stuff)
def install(self):
self.save_import_module = __builtin__.__import__
self.save_reload = __builtin__.reload
if not hasattr(__builtin__, 'unload'):
__builtin__.unload = None
self.save_unload = __builtin__.unload
__builtin__.__import__ = cimport.import_module
__builtin__.reload = cimport.reload_module
__builtin__.unload = self.unload
_installed = False
def install():
global _installed
if not _installed:
hooks = PTLHooks()
loader = PTLLoader(hooks)
if cimport is not None:
importer = cModuleImporter(loader)
else:
importer = ihooks.ModuleImporter(loader)
ihooks.install(importer)
_installed = True
if __name__ == '__main__':
install()
|