diff --git a/mitogen/core.py b/mitogen/core.py index 23ecebe7..6ad7592e 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -37,6 +37,7 @@ import encodings.latin_1 import errno import fcntl import itertools +import linecache import logging import pickle as py_pickle import os @@ -128,6 +129,7 @@ except NameError: BaseException = Exception IS_WSL = 'Microsoft' in os.uname()[2] +PY24 = sys.version_info < (2, 5) PY3 = sys.version_info > (3,) if PY3: b = str.encode @@ -1091,15 +1093,31 @@ class Importer(object): self._callbacks = {} self._cache = {} if core_src: + self._update_linecache('x/mitogen/core.py', core_src) self._cache['mitogen.core'] = ( 'mitogen.core', None, - 'mitogen/core.py', + 'x/mitogen/core.py', zlib.compress(core_src, 9), [], ) self._install_handler(router) + def _update_linecache(self, path, data): + """ + The Python 2.4 linecache module, used to fetch source code for + tracebacks and :func:`inspect.getsource`, does not support PEP-302, + meaning it needs extra help to for Mitogen-loaded modules. Directly + populate its cache if a loaded module belongs to the Mitogen package. + """ + if PY24 and 'mitogen' in path: + linecache.cache[path] = ( + len(data), + 0.0, + data.splitlines(), + path, + ) + def _install_handler(self, router): router.add_handler( fn=self._on_load_module, @@ -1214,6 +1232,11 @@ class Importer(object): self._lock.acquire() try: self._cache[fullname] = tup + if tup[2] is not None and PY24: + self._update_linecache( + path='master:' + tup[2], + data=zlib.decompress(tup[3]) + ) callbacks = self._callbacks.pop(fullname, []) finally: self._lock.release()