What happens to file descriptors in Python 3 when .close() fails?
Question: The following Python 3 code exhibits some strange behavior (to me, at least)
when I run it through `strace`:

    
    
    import os
    import sys
    
    if len(sys.argv) != 2:
        print('Usage: ecpy <filename>')
    sys.exit(1)
    try:
        print('my PID: %d' % os.getpid())
        with open(sys.argv[1], 'w') as fp:
            try:
                fp.write('Hello Stack Overflow!')
            except IOError as e:
                print('### before close')
                print(str(e))
                sys.stdout.flush()
    except IOError as e:
        print('### after close')
        print(str(e))
        sys.stdout.flush()
    
    print('### after exception block')
    sys.stdout.flush()
    

Since I/O is buffered, if you run this code with `/dev/full`, it doesn't fail
until `fp` closes at the end of the `with` block. That's no surprise. In
Python 2.7.3rc2 (on my system), the code runs the exception handler after
actually closing the file descriptor corresponding to `fp`:

    
    
    write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
    close(3)                                = 0
    munmap(0x7f9de3f78000, 4096)            = 0
    write(1, "### after close\n", 16)       = 16
    write(1, "[Errno 28] No space left on devi"..., 35) = 35
    write(1, "### after exception block\n", 26) = 26
    

However, in Python 3.2.3 (on my system), the file descriptor is still open
after the exception block runs:

    
    
    write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
    write(1, "### after close\n", 16)       = 16
    write(1, "[Errno 28] No space left on devi"..., 35) = 35
    write(1, "### after exception block\n", 26) = 26
    ...
    write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
    write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
    close(3)                                = 0
    

The interpreter tries to write to the file a few more times and fails
silently. When does Python actually call `close()`? What is invoking it? This
behavior seems to leak a file descriptor.


Answer: I took the liberty of submitting an issue to bugs.python.org, let's wait and
see if it pans out.

<http://bugs.python.org/issue16597>

EDIT: Looks like it's a bug, good catch!

