IPython doesn't release object references on exit

Bug #239054 reported by the_gigi
2
Affects Status Importance Assigned to Milestone
IPython
Fix Released
Medium
Fernando Perez

Bug Description

# ---- Test IPython exit behavior
class A(object):
  def __init__(self):
    if os.path.exists('__del__.txt'):
      os.remove('__del__.txt')
    print '__init__ is here'
  def __del__(self):
    print '__del__ is here'
    open('__del__.txt', 'w').write('Yeah, it works!!!')

a = A()

# --- End test script ---------

When you run the following script from CPython it prints:
__init__ is here
__del__ is here

and creates the __del__.txt file

When you run it from IPython it prints:
__init__ is here

When you exit() or Exit from IPython neothing is printed and no file is created (the file thing is to make sure __del__ is really never called and not that just the output is eaten).

Note that if you call %reset in IPython then everything is Ok.

IPython should do the equivalent of %reset and release all the references it holds before exit. This behavior is important when working with binding objects that rely on __del__. If the current behavior has some use case then I suggest to add a configuration option to IPython to control it.

Revision history for this message
Gael Varoquaux (gael-varoquaux) wrote : Re: [Bug 239054] [NEW] IPython doesn't release object references on exit

Have you tested that the normal Python interpreter does not exhibit the
same behavior? I have the fealing this is pretty much unspecified
behavior.

Cheers,

Gaël

Revision history for this message
kilian (kilian.koepsell) wrote :

The __del__ method is not guaranteed to be executed when the object is still around at the time when python exits:
  http://docs.python.org/ref/customization.html
So, for python the behavior seems to be not well specified. (However, in this particular case, python seems to call the __del__ method).

In ipython, the situation is more complicated: If you run the above script in ipython, you will have a reference to the object a in your interactive session. You can access the object a and cannot be destroyed yet. If you add a line
  del a
to your script, also ipython wil release the object and the __del__ function will be called.

Revision history for this message
the_gigi (gsayfan) wrote :

It is true that the __del__ method is not guarantueed to be called in the Python spec. So, officially IPython is fine and does everything "by the book". However, this is a defficiency of the spec and not a desirable state. The CPython implementation does the right thing and calls __del__ on exit. It would be nice if IPython could do the same. It will make IPython more compatible with CPython and more predictable. The current situation is that scripts that work in CPython and rely on __del__ being called will not work properly with IPython.

The interactive nature of IPython indeed complicates things because it keeps an outstanding reference, but the problem is that even when you exit IPython (and at this point the interactive reference should go away) the __del__ method is not called.

The suggestion to add 'del a' to the script is a good solution is some situations, but not all. Often there is a complicated object graph and references are stored in lists and dictionaries. Getting rid of all these references manually is a tedious and error prone procedure.

Gigi

Changed in ipython:
assignee: nobody → fdo.perez
importance: Undecided → Medium
status: New → In Progress
Revision history for this message
Fernando Perez (fdo.perez) wrote :
Changed in ipython:
status: In Progress → Fix Committed
Changed in ipython:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.