OLD | NEW |
(Empty) | |
| 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 |
OLD | NEW |