Source

Recovering lost Python source code if it’s still resident in-memory

I read this on GitHub Gist the other day. I don’t know whether I will ever use it but I am still putting this on my blog for the sake of bookmarking it. Who knows? Someone from the audience might end up using it!

I screwed up using git (git checkout – on the wrong file) and managed to delete the code I had just written… but it was still running in a process in a docker container. Here’s how I got it back, using pyrasite and uncompyle6

Attach a shell to the docker container

Install GDB (needed by pyrasite)

apt-get update && apt-get install gdb

Install pyrasite – this will let you attach a Python shell to the still-running process

pip install pyrasite

Install uncompyle6, which will let you get Python source code back from in-memory code objects

pip install uncompyle6

Find the PID of the process that is still running

ps aux | grep python

Attach an interactive prompt using pyrasite

pyrasite-shell <PID>

Now you’re in an interactive prompt! Import the code you need to recover

>>> from my_package import my_module

Figure out which functions and classes you need to recover

>>> dir(my_module)
['MyClass', 'my_function']

Decompile the function into source code

>>> import uncompyle6
>>> import sys
>>> uncompyle6.main.uncompyle(
    2.7, my_module.my_function.func_code, sys.stdout
)
# uncompyle6 version 2.9.10
# Python bytecode 2.7
# Decompiled from: Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
# [GCC 5.4.0 20160609]
# Embedded file name: /srv/my_package/my_module.py
function_body = "appears here"

For the class, you’ll need to decompile each method in turn

>>> uncompyle6.main.uncompyle(
    2.7, my_module.MyClass.my_method.im_func.func_code, sys.stdout
)
# uncompyle6 version 2.9.10
# Python bytecode 2.7
# Decompiled from: Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
# [GCC 5.4.0 20160609]
# Embedded file name: /srv/my_package/my_module.py
class_method_body = "appears here"

I hope you guys like this post. Stay tuned for the next one in the upcoming days.

Newsletter

×

If you liked what you read then I am sure you will enjoy a newsletter of the content I create. I send it out every other month. It contains new stuff that I make, links I find interesting on the web, and occasional discount coupons for my book. Join the 5000+ other people who receive my newsletter:

I send out the newsletter once every other month. No spam, I promise + you can unsubscribe at anytime

✍️ Comments

phihag

If you are using a good editor, that editor will also record states before the checkout (some even ask you which version you want). Try pressing Ctrl+Z multiple times. And don’t forget to commit regularly!

ToGlarkFromContext

Deep wizardry. I hope I never will need it, though…

cheryll

good

divp

Good one thanks for sharing

akshay pai

Very interesting, but not sure if I will ever need this. But definitely good to know that this is even possible. I have written an article on python-list copy: http://sourcedexter.com/python-list-copy/ . This might be useful to many people starting out on working with python.

Say something

Send me an email when someone comments on this post.

Thank you!

Your comment has been submitted and will be published once it has been approved. 😊

OK