ipdb icon indicating copy to clipboard operation
ipdb copied to clipboard

ipdb.set_trace() prevents Pickling valid top-level function

Open bboerner opened this issue 9 years ago • 6 comments

Use of ipdb.set_trace() prevents Pickling valid top-level function which precludes use of Python modules which rely on Pickling e.g. multiprocessing. The following reproduces on two Ubuntu boxes - 14.04 LTS and 16.04 LTS.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pickle
import ipdb

def f(x):
    return x*x

if __name__ == '__main__':

    try:
        x = pickle.dumps(f)
        print('1st pickle: %s' % x)
    except Exception, e:
        print('exception: %s' % e)

    ipdb.set_trace()

    try:
        x = pickle.dumps(f)
        print('2nd pickle: %s' % x)
    except Exception, e:
        print('exception: %s' % e)
1st pickle: c__main__
f
p0
.
> /home/sandbox/ipdb_pickle_bug.py(20)<module>()
     19 
---> 20     try:
     21         x = pickle.dumps(f)

ipdb> c
exception: Can't pickle <function f at 0x7fe575328e60>: it's not found as __main__.f

bboerner avatar Aug 23 '16 16:08 bboerner

This bug costs me quite a bit of time.

whenov avatar Nov 24 '16 08:11 whenov

I just ran into this too. I think it's just the import of ipdb which prevents pickle from pickling any functions defined in main. See this IPython bug (still open unfortunately) for more details: https://github.com/ipython/ipython/issues/1252

nonagonal avatar Mar 06 '17 17:03 nonagonal

In particular, read

Generally speaking, pickling things that are defined in the main module (functions, classes, instances of said classes, things that reference any of the above) is simply not going to work robustly. You can never be sure that whatever is unpickling is going to have your module as main. The use of Tracer() just made it fail sooner rather than later.

gotcha avatar Mar 07 '17 09:03 gotcha

That's reasonable I suppose, but now ipdb is preventing a pretty simple use case: a single file run as a script which wants to use multiprocessing.Pool (which requires the pickling of a function).

nonagonal avatar Mar 07 '17 18:03 nonagonal

As far as I understand, the issue comes from IPython. If someone finds a workaround, PR welcome

gotcha avatar Mar 07 '17 22:03 gotcha

Well we could do what I'm doing inside ipdb itself: we could save sys.modules['__main__'] before importing anything from IPython, then restore it. I think this will have some effect on IPython though so it's probably not a great idea!

nonagonal avatar Mar 08 '17 02:03 nonagonal