| ########################################################################### |
| # |
| # Psyco general support module. |
| # Copyright (C) 2001-2002 Armin Rigo et.al. |
| |
| """Psyco general support module. |
| |
| For internal use. |
| """ |
| ########################################################################### |
| |
| import sys, _psyco, __builtin__ |
| |
| error = _psyco.error |
| class warning(Warning): |
| pass |
| |
| _psyco.NoLocalsWarning = warning |
| |
| def warn(msg): |
| from warnings import warn |
| warn(msg, warning, stacklevel=2) |
| |
| # |
| # Version checks |
| # |
| __version__ = 0x010600f0 |
| if _psyco.PSYVER != __version__: |
| raise error, "version mismatch between Psyco parts, reinstall it" |
| |
| version_info = (__version__ >> 24, |
| (__version__ >> 16) & 0xff, |
| (__version__ >> 8) & 0xff, |
| {0xa0: 'alpha', |
| 0xb0: 'beta', |
| 0xc0: 'candidate', |
| 0xf0: 'final'}[__version__ & 0xf0], |
| __version__ & 0xf) |
| |
| |
| VERSION_LIMITS = [0x02020200, # 2.2.2 |
| 0x02030000, # 2.3 |
| 0x02040000] # 2.4 |
| |
| if ([v for v in VERSION_LIMITS if v <= sys.hexversion] != |
| [v for v in VERSION_LIMITS if v <= _psyco.PYVER ]): |
| if sys.hexversion < VERSION_LIMITS[0]: |
| warn("Psyco requires Python version 2.2.2 or later") |
| else: |
| warn("Psyco version does not match Python version. " |
| "Psyco must be updated or recompiled") |
| |
| |
| if hasattr(_psyco, 'ALL_CHECKS') and hasattr(_psyco, 'VERBOSE_LEVEL'): |
| print >> sys.stderr, ('psyco: running in debugging mode on %s' % |
| _psyco.PROCESSOR) |
| |
| |
| ########################################################################### |
| # sys._getframe() gives strange results on a mixed Psyco- and Python-style |
| # stack frame. Psyco provides a replacement that partially emulates Python |
| # frames from Psyco frames. The new sys._getframe() may return objects of |
| # a custom "Psyco frame" type, which is a subtype of the normal frame type. |
| # |
| # The same problems require some other built-in functions to be replaced |
| # as well. Note that the local variables are not available in any |
| # dictionary with Psyco. |
| |
| |
| class Frame: |
| pass |
| |
| |
| class PythonFrame(Frame): |
| |
| def __init__(self, frame): |
| self.__dict__.update({ |
| '_frame': frame, |
| }) |
| |
| def __getattr__(self, attr): |
| if attr == 'f_back': |
| try: |
| result = embedframe(_psyco.getframe(self._frame)) |
| except ValueError: |
| result = None |
| except error: |
| warn("f_back is skipping dead Psyco frames") |
| result = self._frame.f_back |
| self.__dict__['f_back'] = result |
| return result |
| else: |
| return getattr(self._frame, attr) |
| |
| def __setattr__(self, attr, value): |
| setattr(self._frame, attr, value) |
| |
| def __delattr__(self, attr): |
| delattr(self._frame, attr) |
| |
| |
| class PsycoFrame(Frame): |
| |
| def __init__(self, tag): |
| self.__dict__.update({ |
| '_tag' : tag, |
| 'f_code' : tag[0], |
| 'f_globals': tag[1], |
| }) |
| |
| def __getattr__(self, attr): |
| if attr == 'f_back': |
| try: |
| result = embedframe(_psyco.getframe(self._tag)) |
| except ValueError: |
| result = None |
| elif attr == 'f_lineno': |
| result = self.f_code.co_firstlineno # better than nothing |
| elif attr == 'f_builtins': |
| result = self.f_globals['__builtins__'] |
| elif attr == 'f_restricted': |
| result = self.f_builtins is not __builtins__ |
| elif attr == 'f_locals': |
| raise AttributeError, ("local variables of functions run by Psyco " |
| "cannot be accessed in any way, sorry") |
| else: |
| raise AttributeError, ("emulated Psyco frames have " |
| "no '%s' attribute" % attr) |
| self.__dict__[attr] = result |
| return result |
| |
| def __setattr__(self, attr, value): |
| raise AttributeError, "Psyco frame objects are read-only" |
| |
| def __delattr__(self, attr): |
| if attr == 'f_trace': |
| # for bdb which relies on CPython frames exhibiting a slightly |
| # buggy behavior: you can 'del f.f_trace' as often as you like |
| # even without having set it previously. |
| return |
| raise AttributeError, "Psyco frame objects are read-only" |
| |
| |
| def embedframe(result): |
| if type(result) is type(()): |
| return PsycoFrame(result) |
| else: |
| return PythonFrame(result) |
| |
| def _getframe(depth=0): |
| """Return a frame object from the call stack. This is a replacement for |
| sys._getframe() which is aware of Psyco frames. |
| |
| The returned objects are instances of either PythonFrame or PsycoFrame |
| instead of being real Python-level frame object, so that they can emulate |
| the common attributes of frame objects. |
| |
| The original sys._getframe() ignoring Psyco frames altogether is stored in |
| psyco._getrealframe(). See also psyco._getemulframe().""" |
| # 'depth+1' to account for this _getframe() Python function |
| return embedframe(_psyco.getframe(depth+1)) |
| |
| def _getemulframe(depth=0): |
| """As _getframe(), but the returned objects are real Python frame objects |
| emulating Psyco frames. Some of their attributes can be wrong or missing, |
| however.""" |
| # 'depth+1' to account for this _getemulframe() Python function |
| return _psyco.getframe(depth+1, 1) |
| |
| def patch(name, module=__builtin__): |
| f = getattr(_psyco, name) |
| org = getattr(module, name) |
| if org is not f: |
| setattr(module, name, f) |
| setattr(_psyco, 'original_' + name, org) |
| |
| _getrealframe = sys._getframe |
| sys._getframe = _getframe |
| patch('globals') |
| patch('eval') |
| patch('execfile') |
| patch('locals') |
| patch('vars') |
| patch('dir') |
| patch('input') |
| _psyco.original_raw_input = raw_input |
| __builtin__.__in_psyco__ = 0==1 # False |
| |
| if hasattr(_psyco, 'compact'): |
| import kdictproxy |
| _psyco.compactdictproxy = kdictproxy.compactdictproxy |