Parcourir la source

Fixed #29890 -- Fixed FileSystemStorage crash if concurrent saves try to create the same directory.

Regression in 632c4ffd9cb1da273303bcd8005fff216506c795.
Tim Graham il y a 6 ans
Parent
commit
98ef3829e9
3 fichiers modifiés avec 10 ajouts et 6 suppressions
  1. 2 2
      django/core/files/storage.py
  2. 4 0
      docs/releases/2.1.3.txt
  3. 4 4
      tests/file_storage/tests.py

+ 2 - 2
django/core/files/storage.py

@@ -240,9 +240,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):

+ 4 - 0
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`).

+ 4 - 4
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