1 ########################################################################### |
|
2 # |
|
3 # Psyco general support module. |
|
4 # Copyright (C) 2001-2002 Armin Rigo et.al. |
|
5 |
|
6 """Psyco general support module. |
|
7 |
|
8 For internal use. |
|
9 """ |
|
10 ########################################################################### |
|
11 |
|
12 import sys, _psyco, __builtin__ |
|
13 |
|
14 error = _psyco.error |
|
15 class warning(Warning): |
|
16 pass |
|
17 |
|
18 _psyco.NoLocalsWarning = warning |
|
19 |
|
20 def warn(msg): |
|
21 from warnings import warn |
|
22 warn(msg, warning, stacklevel=2) |
|
23 |
|
24 # |
|
25 # Version checks |
|
26 # |
|
27 __version__ = 0x010600f0 |
|
28 if _psyco.PSYVER != __version__: |
|
29 raise error, "version mismatch between Psyco parts, reinstall it" |
|
30 |
|
31 version_info = (__version__ >> 24, |
|
32 (__version__ >> 16) & 0xff, |
|
33 (__version__ >> 8) & 0xff, |
|
34 {0xa0: 'alpha', |
|
35 0xb0: 'beta', |
|
36 0xc0: 'candidate', |
|
37 0xf0: 'final'}[__version__ & 0xf0], |
|
38 __version__ & 0xf) |
|
39 |
|
40 |
|
41 VERSION_LIMITS = [0x02020200, # 2.2.2 |
|
42 0x02030000, # 2.3 |
|
43 0x02040000] # 2.4 |
|
44 |
|
45 if ([v for v in VERSION_LIMITS if v <= sys.hexversion] != |
|
46 [v for v in VERSION_LIMITS if v <= _psyco.PYVER ]): |
|
47 if sys.hexversion < VERSION_LIMITS[0]: |
|
48 warn("Psyco requires Python version 2.2.2 or later") |
|
49 else: |
|
50 warn("Psyco version does not match Python version. " |
|
51 "Psyco must be updated or recompiled") |
|
52 |
|
53 |
|
54 if hasattr(_psyco, 'ALL_CHECKS') and hasattr(_psyco, 'VERBOSE_LEVEL'): |
|
55 print >> sys.stderr, ('psyco: running in debugging mode on %s' % |
|
56 _psyco.PROCESSOR) |
|
57 |
|
58 |
|
59 ########################################################################### |
|
60 # sys._getframe() gives strange results on a mixed Psyco- and Python-style |
|
61 # stack frame. Psyco provides a replacement that partially emulates Python |
|
62 # frames from Psyco frames. The new sys._getframe() may return objects of |
|
63 # a custom "Psyco frame" type, which is a subtype of the normal frame type. |
|
64 # |
|
65 # The same problems require some other built-in functions to be replaced |
|
66 # as well. Note that the local variables are not available in any |
|
67 # dictionary with Psyco. |
|
68 |
|
69 |
|
70 class Frame: |
|
71 pass |
|
72 |
|
73 |
|
74 class PythonFrame(Frame): |
|
75 |
|
76 def __init__(self, frame): |
|
77 self.__dict__.update({ |
|
78 '_frame': frame, |
|
79 }) |
|
80 |
|
81 def __getattr__(self, attr): |
|
82 if attr == 'f_back': |
|
83 try: |
|
84 result = embedframe(_psyco.getframe(self._frame)) |
|
85 except ValueError: |
|
86 result = None |
|
87 except error: |
|
88 warn("f_back is skipping dead Psyco frames") |
|
89 result = self._frame.f_back |
|
90 self.__dict__['f_back'] = result |
|
91 return result |
|
92 else: |
|
93 return getattr(self._frame, attr) |
|
94 |
|
95 def __setattr__(self, attr, value): |
|
96 setattr(self._frame, attr, value) |
|
97 |
|
98 def __delattr__(self, attr): |
|
99 delattr(self._frame, attr) |
|
100 |
|
101 |
|
102 class PsycoFrame(Frame): |
|
103 |
|
104 def __init__(self, tag): |
|
105 self.__dict__.update({ |
|
106 '_tag' : tag, |
|
107 'f_code' : tag[0], |
|
108 'f_globals': tag[1], |
|
109 }) |
|
110 |
|
111 def __getattr__(self, attr): |
|
112 if attr == 'f_back': |
|
113 try: |
|
114 result = embedframe(_psyco.getframe(self._tag)) |
|
115 except ValueError: |
|
116 result = None |
|
117 elif attr == 'f_lineno': |
|
118 result = self.f_code.co_firstlineno # better than nothing |
|
119 elif attr == 'f_builtins': |
|
120 result = self.f_globals['__builtins__'] |
|
121 elif attr == 'f_restricted': |
|
122 result = self.f_builtins is not __builtins__ |
|
123 elif attr == 'f_locals': |
|
124 raise AttributeError, ("local variables of functions run by Psyco " |
|
125 "cannot be accessed in any way, sorry") |
|
126 else: |
|
127 raise AttributeError, ("emulated Psyco frames have " |
|
128 "no '%s' attribute" % attr) |
|
129 self.__dict__[attr] = result |
|
130 return result |
|
131 |
|
132 def __setattr__(self, attr, value): |
|
133 raise AttributeError, "Psyco frame objects are read-only" |
|
134 |
|
135 def __delattr__(self, attr): |
|
136 if attr == 'f_trace': |
|
137 # for bdb which relies on CPython frames exhibiting a slightly |
|
138 # buggy behavior: you can 'del f.f_trace' as often as you like |
|
139 # even without having set it previously. |
|
140 return |
|
141 raise AttributeError, "Psyco frame objects are read-only" |
|
142 |
|
143 |
|
144 def embedframe(result): |
|
145 if type(result) is type(()): |
|
146 return PsycoFrame(result) |
|
147 else: |
|
148 return PythonFrame(result) |
|
149 |
|
150 def _getframe(depth=0): |
|
151 """Return a frame object from the call stack. This is a replacement for |
|
152 sys._getframe() which is aware of Psyco frames. |
|
153 |
|
154 The returned objects are instances of either PythonFrame or PsycoFrame |
|
155 instead of being real Python-level frame object, so that they can emulate |
|
156 the common attributes of frame objects. |
|
157 |
|
158 The original sys._getframe() ignoring Psyco frames altogether is stored in |
|
159 psyco._getrealframe(). See also psyco._getemulframe().""" |
|
160 # 'depth+1' to account for this _getframe() Python function |
|
161 return embedframe(_psyco.getframe(depth+1)) |
|
162 |
|
163 def _getemulframe(depth=0): |
|
164 """As _getframe(), but the returned objects are real Python frame objects |
|
165 emulating Psyco frames. Some of their attributes can be wrong or missing, |
|
166 however.""" |
|
167 # 'depth+1' to account for this _getemulframe() Python function |
|
168 return _psyco.getframe(depth+1, 1) |
|
169 |
|
170 def patch(name, module=__builtin__): |
|
171 f = getattr(_psyco, name) |
|
172 org = getattr(module, name) |
|
173 if org is not f: |
|
174 setattr(module, name, f) |
|
175 setattr(_psyco, 'original_' + name, org) |
|
176 |
|
177 _getrealframe = sys._getframe |
|
178 sys._getframe = _getframe |
|
179 patch('globals') |
|
180 patch('eval') |
|
181 patch('execfile') |
|
182 patch('locals') |
|
183 patch('vars') |
|
184 patch('dir') |
|
185 patch('input') |
|
186 _psyco.original_raw_input = raw_input |
|
187 __builtin__.__in_psyco__ = 0==1 # False |
|
188 |
|
189 if hasattr(_psyco, 'compact'): |
|
190 import kdictproxy |
|
191 _psyco.compactdictproxy = kdictproxy.compactdictproxy |
|