Author serhiy.storchaka
Recipients Mark.Shannon, benjamin.peterson, ncoghlan, serhiy.storchaka, yselivanov
Date 2018-07-07.17:11:52
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1530983512.39.0.56676864532.issue34066@psf.upfronthosting.co.za>
In-reply-to
Content
The bytecode generated for "with open()":

with open(path) as file:
    data = file.read()

  1           0 LOAD_NAME                0 (open)
              2 LOAD_NAME                1 (path)
              4 CALL_FUNCTION            1
              6 SETUP_WITH              14 (to 22)
              8 STORE_NAME               2 (file)

  2          10 LOAD_NAME                2 (file)
             12 LOAD_METHOD              3 (read)
             14 CALL_METHOD              0
             16 STORE_NAME               4 (data)
             18 POP_BLOCK
             20 BEGIN_FINALLY
        >>   22 WITH_CLEANUP_START
             24 WITH_CLEANUP_FINISH
             26 END_FINALLY
             28 LOAD_CONST               0 (None)
             30 RETURN_VALUE

The execution can be interrupted by Ctrl-C between calling open() and entering the 'with' block. In this case the file object will be created, but its __enter__ and __exit__ methods will be not executed. As a result it will be closed after disappearing a reference to it and a ResourceWarning will be emitted.

The solution is disabling interruption before the SETUP_WITH opcode. It is already disabled before SETUP_FINALLY and YIELD_FROM. It is worth to disable it before BEFORE_ASYNC_WITH for consistency although I don't have examples for it.

See also issue29988.
History
Date User Action Args
2018-07-07 17:11:52serhiy.storchakasetrecipients: + serhiy.storchaka, ncoghlan, benjamin.peterson, Mark.Shannon, yselivanov
2018-07-07 17:11:52serhiy.storchakasetmessageid: <1530983512.39.0.56676864532.issue34066@psf.upfronthosting.co.za>
2018-07-07 17:11:52serhiy.storchakalinkissue34066 messages
2018-07-07 17:11:52serhiy.storchakacreate