Reputation: 127
Because I am an idiot, I deleted some python files and failed to back them up. Before doing this I opened the python interpreter (ie, ran python
) and then used the command import myfile.py
.
EDIT: I actually used the command import myfile
, which, apparently, is worse.
Is there any way I can recover the .pyc (or better the .py, but that seems impossible) file from the python interpreter session I have open?
Upvotes: 4
Views: 2599
Reputation: 157414
The byte-code decompiler uncompyle2 can decompile Python 2.x classes, methods, functions and code to source code (note: via Reassembling Python bytecode to the original code?).
This will work well enough for functions:
from StringIO import StringIO
from uncompyle2 import uncompyle
from inspect import *
def decompile_function(f, indent=''):
s = StringIO()
uncompyle(2.7, f.func_code, s)
return '%sdef %s%s:\n%s %s' % (
indent,
f.func_name,
inspect.formatargspec(*inspect.getargspec(f)),
indent,
('\n ' + indent).join(''.join(s.buflist).split('\n')))
Unfortunately because classes are already executed it won't be able to recover their structure; you'd need to decompile the methods individually and hope that that's enough:
def decompile_class(c):
return 'class %s(%s):\n' % (
c.__name__,
','.join(b.__module__ + '.' + b.__name__ for b in c.__bases__)) + \
'\n'.join(decompile_function(m.im_func, ' ')
for n, m in inspect.getmembers(c) if inspect.ismethod(m))
Full solution:
def decompile_module(mod):
return '\n\n'.join(decompile_function(m) if isfunction(m) else
decompile_class(m) if isclass(m) else
'# UNKNOWN: ' + repr((n, m))
for n, m in inspect.getmembers(mod) if inspect.getmodule(m) is mod)
Upvotes: 4
Reputation: 23322
inspect.getsource
supports dumping modules, so you can simply
import inspect
inspect.getsource(myfile)
As that doesn't seem to work, you should at least be able to get the disassembled (".pyc
) code with
import dis
dis.dis(myfile)
Upvotes: 1