Fixed #30147 -- Simplified directory creation with os.makedirs(..., exist_ok=True).

This commit is contained in:
Jon Dufresne 2019-01-31 07:12:55 -08:00 committed by Tim Graham
parent ba7a420012
commit 290d8471bb
12 changed files with 43 additions and 66 deletions

View File

@ -310,10 +310,7 @@ class Command(BaseCommand):
else: else:
self.log("Linking '%s'" % source_path, level=2) self.log("Linking '%s'" % source_path, level=2)
full_path = self.storage.path(prefixed_path) full_path = self.storage.path(prefixed_path)
try: os.makedirs(os.path.dirname(full_path), exist_ok=True)
os.makedirs(os.path.dirname(full_path))
except OSError:
pass
try: try:
if os.path.lexists(full_path): if os.path.lexists(full_path):
os.unlink(full_path) os.unlink(full_path)

View File

@ -113,11 +113,7 @@ class FileBasedCache(BaseCache):
self._delete(fname) self._delete(fname)
def _createdir(self): def _createdir(self):
if not os.path.exists(self._dir): os.makedirs(self._dir, 0o700, exist_ok=True)
try:
os.makedirs(self._dir, 0o700)
except FileExistsError:
pass
def _key_to_file(self, key, version=None): def _key_to_file(self, key, version=None):
""" """

View File

@ -228,24 +228,18 @@ class FileSystemStorage(Storage):
# Create any intermediate directories that do not exist. # Create any intermediate directories that do not exist.
directory = os.path.dirname(full_path) directory = os.path.dirname(full_path)
if not os.path.exists(directory): try:
try: if self.directory_permissions_mode is not None:
if self.directory_permissions_mode is not None: # os.makedirs applies the global umask, so we reset it,
# os.makedirs applies the global umask, so we reset it, # for consistency with file_permissions_mode behavior.
# for consistency with file_permissions_mode behavior. old_umask = os.umask(0)
old_umask = os.umask(0) try:
try: os.makedirs(directory, self.directory_permissions_mode, exist_ok=True)
os.makedirs(directory, self.directory_permissions_mode) finally:
finally: os.umask(old_umask)
os.umask(old_umask) else:
else: os.makedirs(directory, exist_ok=True)
os.makedirs(directory) except FileExistsError:
except FileExistsError:
# There's a race between os.path.exists() and os.makedirs().
# If os.makedirs() fails with FileExistsError, the directory
# was created concurrently.
pass
if not os.path.isdir(directory):
raise FileExistsError('%s exists and is not a directory.' % directory) raise FileExistsError('%s exists and is not a directory.' % directory)
# There's a potential race condition between get_available_name and # There's a potential race condition between get_available_name and

View File

@ -21,19 +21,16 @@ class EmailBackend(ConsoleEmailBackend):
if not isinstance(self.file_path, str): if not isinstance(self.file_path, str):
raise ImproperlyConfigured('Path for saving emails is invalid: %r' % self.file_path) raise ImproperlyConfigured('Path for saving emails is invalid: %r' % self.file_path)
self.file_path = os.path.abspath(self.file_path) self.file_path = os.path.abspath(self.file_path)
# Make sure that self.file_path is a directory if it exists. try:
if os.path.exists(self.file_path) and not os.path.isdir(self.file_path): os.makedirs(self.file_path, exist_ok=True)
except FileExistsError:
raise ImproperlyConfigured( raise ImproperlyConfigured(
'Path for saving email messages exists, but is not a directory: %s' % self.file_path 'Path for saving email messages exists, but is not a directory: %s' % self.file_path
) )
# Try to create it, if it not exists. except OSError as err:
elif not os.path.exists(self.file_path): raise ImproperlyConfigured(
try: 'Could not create directory for saving email messages: %s (%s)' % (self.file_path, err)
os.makedirs(self.file_path) )
except OSError as err:
raise ImproperlyConfigured(
'Could not create directory for saving email messages: %s (%s)' % (self.file_path, err)
)
# Make sure that self.file_path is writable. # Make sure that self.file_path is writable.
if not os.access(self.file_path, os.W_OK): if not os.access(self.file_path, os.W_OK):
raise ImproperlyConfigured('Could not write to directory: %s' % self.file_path) raise ImproperlyConfigured('Could not write to directory: %s' % self.file_path)

View File

@ -356,8 +356,7 @@ class Command(BaseCommand):
self.locale_paths.append(os.path.abspath('locale')) self.locale_paths.append(os.path.abspath('locale'))
if self.locale_paths: if self.locale_paths:
self.default_locale_path = self.locale_paths[0] self.default_locale_path = self.locale_paths[0]
if not os.path.exists(self.default_locale_path): os.makedirs(self.default_locale_path, exist_ok=True)
os.makedirs(self.default_locale_path)
# Build locale list # Build locale list
looks_like_locale = re.compile(r'[a-z]{2}') looks_like_locale = re.compile(r'[a-z]{2}')
@ -598,8 +597,7 @@ class Command(BaseCommand):
Use msgmerge and msgattrib GNU gettext utilities. Use msgmerge and msgattrib GNU gettext utilities.
""" """
basedir = os.path.join(os.path.dirname(potfile), locale, 'LC_MESSAGES') basedir = os.path.join(os.path.dirname(potfile), locale, 'LC_MESSAGES')
if not os.path.isdir(basedir): os.makedirs(basedir, exist_ok=True)
os.makedirs(basedir)
pofile = os.path.join(basedir, '%s.po' % self.domain) pofile = os.path.join(basedir, '%s.po' % self.domain)
if os.path.exists(pofile): if os.path.exists(pofile):

View File

@ -210,8 +210,7 @@ class Command(BaseCommand):
# Write the migrations file to the disk. # Write the migrations file to the disk.
migrations_directory = os.path.dirname(writer.path) migrations_directory = os.path.dirname(writer.path)
if not directory_created.get(app_label): if not directory_created.get(app_label):
if not os.path.isdir(migrations_directory): os.makedirs(migrations_directory, exist_ok=True)
os.mkdir(migrations_directory)
init_path = os.path.join(migrations_directory, "__init__.py") init_path = os.path.join(migrations_directory, "__init__.py")
if not os.path.isfile(init_path): if not os.path.isfile(init_path):
open(init_path, "w").close() open(init_path, "w").close()

View File

@ -120,8 +120,7 @@ class TemplateCommand(BaseCommand):
relative_dir = path_rest.replace(base_name, name) relative_dir = path_rest.replace(base_name, name)
if relative_dir: if relative_dir:
target_dir = path.join(top_dir, relative_dir) target_dir = path.join(top_dir, relative_dir)
if not path.exists(target_dir): os.makedirs(target_dir, exist_ok=True)
os.mkdir(target_dir)
for dirname in dirs[:]: for dirname in dirs[:]:
if dirname.startswith('.') or dirname == '__pycache__': if dirname.startswith('.') or dirname == '__pycache__':

View File

@ -1,3 +1,4 @@
import os import os
import re import re
from importlib import import_module from importlib import import_module
@ -249,8 +250,7 @@ class MigrationWriter:
migrations_package_name) migrations_package_name)
final_dir = os.path.join(base_dir, *missing_dirs) final_dir = os.path.join(base_dir, *missing_dirs)
if not os.path.isdir(final_dir): os.makedirs(final_dir, exist_ok=True)
os.makedirs(final_dir)
for missing_dir in missing_dirs: for missing_dir in missing_dirs:
base_dir = os.path.join(base_dir, missing_dir) base_dir = os.path.join(base_dir, missing_dir)
with open(os.path.join(base_dir, "__init__.py"), "w"): with open(os.path.join(base_dir, "__init__.py"), "w"):

View File

@ -157,8 +157,8 @@ class TarArchive(BaseArchive):
name = self.split_leading_dir(name)[1] name = self.split_leading_dir(name)[1]
filename = os.path.join(to_path, name) filename = os.path.join(to_path, name)
if member.isdir(): if member.isdir():
if filename and not os.path.exists(filename): if filename:
os.makedirs(filename) os.makedirs(filename, exist_ok=True)
else: else:
try: try:
extracted = self._archive.extractfile(member) extracted = self._archive.extractfile(member)
@ -169,8 +169,8 @@ class TarArchive(BaseArchive):
(name, member.name, exc)) (name, member.name, exc))
else: else:
dirname = os.path.dirname(filename) dirname = os.path.dirname(filename)
if dirname and not os.path.exists(dirname): if dirname:
os.makedirs(dirname) os.makedirs(dirname, exist_ok=True)
with open(filename, 'wb') as outfile: with open(filename, 'wb') as outfile:
shutil.copyfileobj(extracted, outfile) shutil.copyfileobj(extracted, outfile)
self._copy_permissions(member.mode, filename) self._copy_permissions(member.mode, filename)
@ -199,14 +199,13 @@ class ZipArchive(BaseArchive):
if leading: if leading:
name = self.split_leading_dir(name)[1] name = self.split_leading_dir(name)[1]
filename = os.path.join(to_path, name) filename = os.path.join(to_path, name)
dirname = os.path.dirname(filename)
if dirname and not os.path.exists(dirname):
os.makedirs(dirname)
if filename.endswith(('/', '\\')): if filename.endswith(('/', '\\')):
# A directory # A directory
if not os.path.exists(filename): os.makedirs(filename, exist_ok=True)
os.makedirs(filename)
else: else:
dirname = os.path.dirname(filename)
if dirname:
os.makedirs(dirname, exist_ok=True)
with open(filename, 'wb') as outfile: with open(filename, 'wb') as outfile:
outfile.write(data) outfile.write(data)
# Convert ZipInfo.external_attr to mode # Convert ZipInfo.external_attr to mode

View File

@ -48,8 +48,7 @@ class AdminScriptTestCase(SimpleTestCase):
cls.__name__, cls.__name__,
'test_project', 'test_project',
)) ))
if not os.path.exists(cls.test_dir): os.makedirs(cls.test_dir)
os.makedirs(cls.test_dir)
with open(os.path.join(cls.test_dir, '__init__.py'), 'w'): with open(os.path.join(cls.test_dir, '__init__.py'), 'w'):
pass pass

View File

@ -410,12 +410,13 @@ class FileStorageTests(SimpleTestCase):
# Monkey-patch os.makedirs, to simulate a normal call, a raced call, # Monkey-patch os.makedirs, to simulate a normal call, a raced call,
# and an error. # and an error.
def fake_makedirs(path): def fake_makedirs(path, mode=0o777, exist_ok=False):
if path == os.path.join(self.temp_dir, 'normal'): if path == os.path.join(self.temp_dir, 'normal'):
real_makedirs(path) real_makedirs(path, mode, exist_ok)
elif path == os.path.join(self.temp_dir, 'raced'): elif path == os.path.join(self.temp_dir, 'raced'):
real_makedirs(path) real_makedirs(path, mode, exist_ok)
raise FileExistsError() if not exist_ok:
raise FileExistsError()
elif path == os.path.join(self.temp_dir, 'error'): elif path == os.path.join(self.temp_dir, 'error'):
raise PermissionError() raise PermissionError()
else: else:

View File

@ -29,8 +29,7 @@ class FileUploadTests(TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
if not os.path.isdir(MEDIA_ROOT): os.makedirs(MEDIA_ROOT, exist_ok=True)
os.makedirs(MEDIA_ROOT)
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
@ -528,8 +527,7 @@ class DirectoryCreationTests(SimpleTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
if not os.path.isdir(MEDIA_ROOT): os.makedirs(MEDIA_ROOT, exist_ok=True)
os.makedirs(MEDIA_ROOT)
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):