Python – How to call tempfile.mkstemp() with “with”? – or why doesn’t it return an fd with __exit__()

python, python-internals, temporary-files, with-statement

To me the most idiomatic way of calling tempfile.mkstemp() would be as:

with tempfile.mkstemp() as fd, filename:    pass

however, this obviously(?) raises AttributeError: __exit__

Calling os.close(fd) explicitly using try-finally is an easy way to solve this, but feels like violation of There should be one– and preferably only one –obvious way to do it.

Is there a way to "fix" this in tempfile or is there a rationale why this has been implemented this way?

Best Solution

The workings of the with statement is defined in PEP 343, including its so called context management protocol:

This PEP proposes that the protocol consisting of the enter() and exit() methods be known as the "context management protocol", and that objects that implement that protocol be known as "context managers".

mkstemp does not return a context manager, that is an object which implements the __enter__ and __exit__ methods, and is therefore not compatible.

An obvious workaround is to create a wrapper class that implements the context manager protocol.