0

I'm running IPython3 in Emacs with Elpy and trying to edit nested functions on the fly. For example, I have the attached file open in one frame and IPython3 in the other. I send the buffer to IPython with C-c C-y b, switch to the IPython frame with C-x o.

import sys

def print_name():
    print ("Alice")

def name ():
    print_name()

def main(argv):
    print ("In main.")
    import ipdb; ipdb.set_trace()
    name()

if __name__ == "__main__":
    main(sys.argv[1:])

Now I run the code by typing main(0).

In [1]: main(0)
In main.
> /Users/ayank/Documents/programming/python/bar.py(12)main()
     11     import ipdb; ipdb.set_trace()
---> 12     name()
     13 

I get a debug prompt and do:

ipdb> name()
Alice

Now, I go back to the code window for print_name(), change Alice to Bob, and resend the function to IPython3 with C-c C-y f. I see the following appear in the IPython frame:

ipdb> def print_name():
 ...:     print ("Bob")

I go back to the IPython frame and type:

ipdb> name()
Alice
ipdb> print_name()
Bob

That's not right: both should print Bob. I can resend the entire buffer to IPython with C-c C-y b, but I get the same answer: name() always outputs Alice.

What's going on here? How do I update nested functions in IPython3 while debugging?

1 Answers1

0

The issue is that when execution hits the breakpoint, code typed at the ipdb prompt gets executed in the main namespace. Hence, the new print_name() is in the main namespace while name() continues to call print_name() in the global namespace.

The new print_name() can be added to the global namespace manually by typing globals()['print_name'] = print_name.

An example run of the code:

ayank@snorri$ ./foo.py
In main.
> /Users/ayank/Documents/programming/python/bar.py(13)main()
     12     import ipdb; ipdb.set_trace()
---> 13     name()
     14 
ipdb> print_name()
Alice
ipdb> name()
Alice
ipdb> def print_name(): print ("Bob")
ipdb> print_name()
Bob
ipdb> name()
Alice
ipdb> globals()["print_name"] = print_name
ipdb> name()
Bob