summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-10-31 19:25:53 -0400
committerTim Graham <timograham@gmail.com>2018-10-31 20:24:16 -0400
commitcd7d6c8af7e9ecfd033c584ba50c782d6b82817c (patch)
tree9ce72bddf998f187d50b24ee37f61d8ed023c7ac
parent0f02d71995530f29a2d3246083854fe19697c3a5 (diff)
[2.1.x] Fixed #29890 -- Fixed FileSystemStorage crash if concurrent saves try to create the same directory.
Regression in 632c4ffd9cb1da273303bcd8005fff216506c795. Backport of 98ef3829e96ebc73d4d446f92465e671ff520d2b from master.
-rw-r--r--django/core/files/storage.py4
-rw-r--r--docs/releases/2.1.3.txt4
-rw-r--r--tests/file_storage/tests.py8
3 files changed, 10 insertions, 6 deletions
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index 47642ff2f2..faa9a483a0 100644
--- a/django/core/files/storage.py
+++ b/django/core/files/storage.py
@@ -234,9 +234,9 @@ class FileSystemStorage(Storage):
os.umask(old_umask)
else:
os.makedirs(directory)
- except FileNotFoundError:
+ except FileExistsError:
# There's a race between os.path.exists() and os.makedirs().
- # If os.makedirs() fails with FileNotFoundError, the directory
+ # If os.makedirs() fails with FileExistsError, the directory
# was created concurrently.
pass
if not os.path.isdir(directory):
diff --git a/docs/releases/2.1.3.txt b/docs/releases/2.1.3.txt
index 72ec3e4a32..f4f33803bb 100644
--- a/docs/releases/2.1.3.txt
+++ b/docs/releases/2.1.3.txt
@@ -20,3 +20,7 @@ Bugfixes
* Fixed a regression where cached foreign keys that use ``to_field`` were
incorrectly cleared in ``Model.save()`` (:ticket:`29896`).
+
+* Fixed a regression in Django 2.0 where ``FileSystemStorage`` crashes with
+ ``FileExistsError`` if concurrent saves try to create the same directory
+ (:ticket:`29890`).
diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py
index 16548b86cb..47d7a20891 100644
--- a/tests/file_storage/tests.py
+++ b/tests/file_storage/tests.py
@@ -415,9 +415,9 @@ class FileStorageTests(SimpleTestCase):
real_makedirs(path)
elif path == os.path.join(self.temp_dir, 'raced'):
real_makedirs(path)
- raise FileNotFoundError()
- elif path == os.path.join(self.temp_dir, 'error'):
raise FileExistsError()
+ elif path == os.path.join(self.temp_dir, 'error'):
+ raise PermissionError()
else:
self.fail('unexpected argument %r' % path)
@@ -432,8 +432,8 @@ class FileStorageTests(SimpleTestCase):
with self.storage.open('raced/test.file') as f:
self.assertEqual(f.read(), b'saved with race')
- # Exceptions aside from FileNotFoundError are raised.
- with self.assertRaises(FileExistsError):
+ # Exceptions aside from FileExistsError are raised.
+ with self.assertRaises(PermissionError):
self.storage.save('error/test.file', ContentFile('not saved'))
finally:
os.makedirs = real_makedirs