1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #36010 -- Avoided touching mo files while checking writability.

This commit is contained in:
Claude Paroz 2024-12-20 23:26:22 +01:00
parent fcd9d08379
commit 3b349fd134
2 changed files with 12 additions and 10 deletions

View File

@ -2,6 +2,7 @@ import codecs
import concurrent.futures
import glob
import os
import tempfile
from pathlib import Path
from django.core.management.base import BaseCommand, CommandError
@ -16,12 +17,10 @@ def has_bom(fn):
)
def is_writable(path):
# Known side effect: updating file access/modified time to current time if
# it is writable.
def is_dir_writable(path):
try:
with open(path, "a"):
os.utime(path, None)
with tempfile.NamedTemporaryFile(dir=path):
pass
except OSError:
return False
return True
@ -172,7 +171,7 @@ class Command(BaseCommand):
continue
# Check writability on first location
if i == 0 and not is_writable(mo_path):
if i == 0 and not is_dir_writable(mo_path.parent):
self.stderr.write(
"The po files under %s are in a seemingly not writable "
"location. mo files will not be updated/created." % dirpath

View File

@ -43,9 +43,9 @@ class PoFileTests(MessageCompilationTests):
def test_no_write_access(self):
mo_file_en = Path(self.MO_FILE_EN)
err_buffer = StringIO()
# Put file in read-only mode.
old_mode = mo_file_en.stat().st_mode
mo_file_en.chmod(stat.S_IREAD)
# Put parent directory in read-only mode.
old_mode = mo_file_en.parent.stat().st_mode
mo_file_en.parent.chmod(stat.S_IRUSR | stat.S_IXUSR)
# Ensure .po file is more recent than .mo file.
mo_file_en.with_suffix(".po").touch()
try:
@ -57,7 +57,7 @@ class PoFileTests(MessageCompilationTests):
)
self.assertIn("not writable location", err_buffer.getvalue())
finally:
mo_file_en.chmod(old_mode)
mo_file_en.parent.chmod(old_mode)
def test_no_compile_when_unneeded(self):
mo_file_en = Path(self.MO_FILE_EN)
@ -258,6 +258,9 @@ class CompilationErrorHandling(MessageCompilationTests):
# po file contains wrong po formatting.
with self.assertRaises(CommandError):
call_command("compilemessages", locale=["ja"], verbosity=0)
# It should still fail a second time.
with self.assertRaises(CommandError):
call_command("compilemessages", locale=["ja"], verbosity=0)
def test_msgfmt_error_including_non_ascii(self):
# po file contains invalid msgstr content (triggers non-ascii error content).