From ec00a70b0c74c1d1617e6bf650df9e89b4cafb25 2007-02-18 21:23:21 From: fperez Date: 2007-02-18 21:23:21 Subject: [PATCH] - Small fix to pexpect to prevent unhandled exceptions at Python shutdown time. --- diff --git a/IPython/irunner.py b/IPython/irunner.py index 077dc26..012ab09 100755 --- a/IPython/irunner.py +++ b/IPython/irunner.py @@ -45,6 +45,41 @@ Interactive script runner, type: %s runner [opts] script_name """ +def pexpect_monkeypatch(): + """Patch pexpect to prevent unhandled exceptions at VM teardown. + + Calling this function will monkeypatch the pexpect.spawn class and modify + its __del__ method to make it more robust in the face of failures that can + occur if it is called when the Python VM is shutting down. + + Since Python may fire __del__ methods arbitrarily late, it's possible for + them to execute during the teardown of the Python VM itself. At this + point, various builtin modules have been reset to None. Thus, the call to + self.close() will trigger an exception because it tries to call os.close(), + and os is now None. + """ + + if pexpect.__version__[:3] >= '2.2': + # No need to patch, fix is already the upstream version. + return + + def __del__(self): + """This makes sure that no system resources are left open. + Python only garbage collects Python objects. OS file descriptors + are not Python objects, so they must be handled explicitly. + If the child file descriptor was opened outside of this class + (passed to the constructor) then this does not close it. + """ + if not self.closed: + try: + self.close() + except AttributeError: + pass + + pexpect.spawn.__del__ = __del__ + +pexpect_monkeypatch() + # The generic runner class class InteractiveRunner(object): """Class to run a sequence of commands through an interactive program.""" diff --git a/doc/ChangeLog b/doc/ChangeLog index d1af405..0faa5dc 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2007-02-18 Fernando Perez + + * IPython/irunner.py (pexpect_monkeypatch): patch pexpect to + protect against exceptions at Python shutdown time. Patch + sumbmitted to upstream. + 2007-02-14 Walter Doerwald * IPython/Extensions/ibrowse.py: If entering the first object level