﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37447	makemessages fails in UTF-8 mode when processing non-UTF-8 filenames	Jacob Walls	Jacob Walls	"Surfaced on CI just now after bumping Windows jobs to Python 3.15, now that UTF-8 mode is the [https://docs.python.org/3/whatsnew/3.15.html#whatsnew315-utf8-default default].

{{{#!py
ERROR: test_unicode_file_name (i18n.test_extraction.BasicExtractorTests.test_unicode_file_name)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""C:\hostedtoolcache\windows\Python\3.15.1\x64\Lib\unittest\case.py"", line 58, in testPartExecutor
    yield
  File ""C:\hostedtoolcache\windows\Python\3.15.1\x64\Lib\unittest\case.py"", line 691, in run
    self._callTestMethod(testMethod)
    
  File ""C:\hostedtoolcache\windows\Python\3.15.1\x64\Lib\unittest\case.py"", line 637, in _callTestMethod
    result = method()
    ^^^^^^^^^^^^^^^
  File ""D:\a\django\django\tests\i18n\test_extraction.py"", line 372, in test_unicode_file_name
    management.call_command(""makemessages"", locale=[LOCALE], verbosity=0)
    ^^^^^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\__init__.py"", line 195, in call_command
    return command.execute(*args, **defaults)
      ^^^^^^^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\base.py"", line 471, in execute
    output = self.handle(*args, **options)
    ^^^^^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\commands\makemessages.py"", line 423, in handle
    potfiles = self.build_potfiles()
    ^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\commands\makemessages.py"", line 504, in build_potfiles
    self.process_files(file_list)
    ^^^^^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\commands\makemessages.py"", line 596, in process_files
    self.process_locale_dir(locale_dir, files)
    ^^^^^^^^^^^
  File ""D:\a\django\django\django\core\management\commands\makemessages.py"", line 677, in process_locale_dir
    raise CommandError(
    ^^^^^^^
django.core.management.base.CommandError: errors happened while running xgettext on .\__init__.py
.\ignore_dir\ignored.html.py
.\media_root\media_ignored.html.py
.\static\static_ignored.html.py
.\templates\empty.html.py
.\templates\subdir\ignored.html.py
.\templates\test.html.py
.\templates\xxx_ignored.html.py
.\vidéo.txt.py
xgettext: error while opening "".\vidÃ©o.txt.py"" for reading: No such file or directory
}}}

I believe the fix is to write using the system locale, which we should have been doing all along ([https://docs.astral.sh/ruff/rules/unspecified-encoding/#why-is-this-bad linter rule on this topic])

{{{#!diff
diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index 5a4bd55bb8..9db5a6ef2a 100644
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -663,8 +663,10 @@ class Command(BaseCommand):
             return
 
         input_files = [bf.work_path for bf in build_files]
-        with NamedTemporaryFile(mode=""w+"") as input_files_list:
-            input_files_list.write(""\n"".join(input_files))
+        with NamedTemporaryFile(mode=""w+b"") as input_files_list:
+            input_files_list.write(
+                ""\n"".join(input_files).encode(DEFAULT_LOCALE_ENCODING)
+            )
             input_files_list.flush()
             args.extend([""--files-from"", input_files_list.name])
             args.extend(self.xgettext_options)
}}}

If a triager confirms the approach, I can open the PR. I propose backporting to 6.1 as part of 3.15 support, but with a release note, since it affects released behavior and would have been visible on prior Python versions when running in UTF-8 mode."	Bug	assigned	Internationalization	6.1	Release blocker		makemessages, locale, utf-8	Sarah Boyce	Unreviewed	0	0	0	0	0	0
