[New-bugs-announce] [issue22427] TemporaryDirectory attempts to clean up twice

Jack O'Connor report at bugs.python.org
Wed Sep 17 07:18:39 CEST 2014

New submission from Jack O'Connor:

The following little script prints (but ignores) a FileNotFoundError.

import tempfile
def generator():
    with tempfile.TemporaryDirectory():
g = generator()

Exception ignored in: <generator object generator at 0x7fb319fe2c60>
Traceback (most recent call last):
  File "gen.py", line 6, in generator
  File "/usr/lib/python3.4/tempfile.py", line 691, in __exit__
  File "/usr/lib/python3.4/tempfile.py", line 697, in cleanup
  File "/usr/lib/python3.4/shutil.py", line 454, in rmtree
  File "/usr/lib/python3.4/shutil.py", line 452, in rmtree
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmp7wek4xhy'

Putting print statements in the TemporaryDirectory class shows what's happening (confirming Guido's theory from https://groups.google.com/forum/#!topic/python-tulip/QXgWH32P2uM): As the program exits, the TemporaryDirectory object is finalized. This actually rmtree's the directory. After that, the generator is finalized, which raises a GeneratorExit inside of it. That exception causes the with statement to call __exit__ on the already-finalized TemporaryDirectory, which tries to rmtree again and throws the FileNotFoundError.

The main downside of this bug is just garbage on stderr. I suppose in exceptionally unlikely circumstances, a new temp dir by the same name could be created between the two calls, and we might actually delete something we shouldn't. The simple fix would be to store a _was_cleaned flag or something on the object. Is there any black magic in finalizers or multithreading that demands something more complicated?

components: Library (Lib)
messages: 226979
nosy: oconnor663
priority: normal
severity: normal
status: open
title: TemporaryDirectory attempts to clean up twice
type: behavior
versions: Python 3.4

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list