Author chortos
Recipients chortos
Date 2011-05-16.03:08:54
SpamBayes Score 1.11022e-16
Marked as misclassified No
Message-id <1305515335.66.0.95766532071.issue12085@psf.upfronthosting.co.za>
In-reply-to
Content
If subprocess.Popen is called with a keyword argument whose name is undefined or simply too many arguments, an instance of the Popen class is created but its __init__ method call fails due to the invalid argument list. (Immediately) afterwards, the new instance is destroyed and its __del__ method is called, which checks the _child_created field that is defined by __init__; but __init__ never got the chance to execute, so the field is not defined, and __del__ raises an AttributeError, which is written out to stderr.

>>> subprocess.Popen(fdsa=1)
Exception AttributeError: "'Popen' object has no attribute '_child_created'" in <bound method Popen.__del__ of <subprocess.Popen object at 0x1006ee790>> ignored
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'fdsa'
>>> subprocess.Popen((), 0, None, None, None, None, None, True, False, None, None, False, None, 0, True, False, (), None)
Exception AttributeError: "'Popen' object has no attribute '_child_created'" in <bound method Popen.__del__ of <subprocess.Popen object at 0x1006ee790>> ignored
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes at most 18 positional arguments (19 given)

I encountered this while trying to write a piece of code compatible with Python 3.2 and earlier versions simultaneously. The subprocess module in Python 3.2 adds a new argument to the constructor of Popen, pass_fds, while changing the default value of another, close_fds, from False to True. In order to utilize pass_fds, I tried code that looked like this:

    try:
        process = Popen(*args, pass_fds=myfds, **kwargs)
    except TypeError:
        process = Popen(*args, **kwargs)

It worked but printed a message about the exception in __del__, which interfered with my own output. Without delving too much into the details of my code, I ended up just passing close_fds=False.

The attached patch avoids the exception by converting the reference to _child_created in __del__ into a three-argument getattr call.
History
Date User Action Args
2011-05-16 03:08:55chortossetrecipients: + chortos
2011-05-16 03:08:55chortossetmessageid: <1305515335.66.0.95766532071.issue12085@psf.upfronthosting.co.za>
2011-05-16 03:08:55chortoslinkissue12085 messages
2011-05-16 03:08:54chortoscreate