5

I have the following script, which does the same thing twice, in very slightly different ways. The first works, the second does not:

#!/usr/bin/python import tempfile fhandle=tempfile.NamedTemporaryFile(dir=".",delete=False) fhandle.write("hello") tempfile.NamedTemporaryFile(dir=".",delete=False).write("hello") 

I get the follow error:

Traceback (most recent call last): File "./test.py", line 7, in <module> tempfile.NamedTemporaryFile().write("hello") ValueError: I/O operation on closed file 

In my example script, I have put them together to show that the first one works. This does not affect the results, just points out that there is a difference.

Is this a bug in Python? Something weird about my machine? Expected behaviour? Correct behaviour? It looks like the object is being destroyed before the write().

Python 2.7.3 on Ubuntu 12.04.3 LTS

10
  • 1
    Something is not as it appears in the implementation of NamedTemporaryFile. Why would you want do this? Commented Aug 28, 2013 at 22:50
  • The only thing I can deduce is that __del__ somehow gets called on the result of NamedTemporaryFile before the call to write occurs. Why that would happen, I do not know. Commented Aug 28, 2013 at 22:56
  • Looks like garbage collection - no references to the temp file instance and it become closed immediately. Commented Aug 28, 2013 at 23:03
  • No errors for me with Python 2.7.5 on a Windows machine... Note the docs say the returned object is a file-like object, so maybe that has something to do with it. Commented Aug 28, 2013 at 23:08
  • 1
    @alecxe: It's still being referenced within the expression being evaluated. Commented Aug 28, 2013 at 23:10

2 Answers 2

2

Correct answer (from both answers to this question, and further test): This is a bug.

I have raised a bug, which can be seen here: http://bugs.python.org/issue18879

Sign up to request clarification or add additional context in comments.

Comments

0

I think the comments from @Eric Urban and @alecxe are right, the file is closed - depending on the platform - based on the refcount, or something similar. I tried looking at a newly created tempfile object using a similar process:

>>> tempfile.NamedTemporaryFile().__dict__ {'close_called': True, 'name': '/tmp/tmpCRzR_c', 'file': <closed file '<fdopen>', mode 'w+b' at 0x7f9448e541e0>, 'delete': True} >>> a = tempfile.NamedTemporaryFile() >>> a.__dict__ {'close_called': False, 'name': '/tmp/tmpnmWpQ5', 'file': <open file '<fdopen>', mode 'w+b' at 0x7f9448e54270>, 'delete': True} 

So some time after creation, close is being called on your newly created temp file, probably as there are no references to it. Depending on your platform and the way you call it, closing a file may also delete it.

4 Comments

From the source of tempfile.py you can definitely see what it does wrt to closing the file is os-dependent.
Actually I think I see a bug here in tempfile.py, where from the comments above it I think it should be self.unlink = _os.unlink. Can't test whether that's the cause of the OP's problem myself, since I'm on Windows...
In _TemporaryFileWrapper, line 379? You could well be right there. I'm not sure whether __del__ or close should be called (something is calling one of those) in the OP's situation, though.
I can confirm that del ("Called when the instance is about to be destroyed") is being called BEFORE the exception. Why is it being destroyed when there are still method calls pending?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.