diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index d1831d68f0281d..c415cfd338ce6a 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -591,6 +591,22 @@ def test_multiple_keywords_same_funcname_errors(self): '\tkeyword="_": Expected a string constant for argument 1, got 42\n' '\tkeyword="_:2": Expected a string constant for argument 2, got y\n') + def test_utf8_encoding(self): + with temp_cwd(None): + with open('test.py', 'w', encoding='utf-8') as fp: + fp.write('_("áscii")') + + res = assert_python_ok(self.script, + 'test.py', + PYTHONCOERCECLOCALE="0", + PYTHONUTF8="0", + LANG="C", + LC_ALL="C") + self.assertEqual(res.err, b'') + + with open('messages.pot', encoding='utf-8') as fp: + pot_content = fp.read() + self.assertIn('áscii', pot_content) def extract_from_snapshots(): snapshots = { diff --git a/Misc/NEWS.d/next/Tools-Demos/2025-10-10-18-07-18.gh-issue-139873.aVALQm.rst b/Misc/NEWS.d/next/Tools-Demos/2025-10-10-18-07-18.gh-issue-139873.aVALQm.rst new file mode 100644 index 00000000000000..d77a34c592d8df --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2025-10-10-18-07-18.gh-issue-139873.aVALQm.rst @@ -0,0 +1 @@ +:program:`pygettext`: open files with the uft-8 encoding diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index ddf4474d2bce55..ddd16b1e26ffec 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -767,7 +767,7 @@ class Options: elif opt in ('-x', '--exclude-file'): options.excludefilename = arg elif opt in ('-X', '--no-docstrings'): - fp = open(arg) + fp = open(arg, encoding='utf-8') try: while 1: line = fp.readline() @@ -794,7 +794,7 @@ class Options: # initialize list of strings to exclude if options.excludefilename: try: - with open(options.excludefilename) as fp: + with open(options.excludefilename, encoding='utf-8') as fp: options.toexclude = fp.readlines() except OSError: print(f"Can't read --exclude-file: {options.excludefilename}", @@ -834,7 +834,7 @@ class Options: else: if options.outpath: options.outfile = os.path.join(options.outpath, options.outfile) - fp = open(options.outfile, 'w') + fp = open(options.outfile, 'w', encoding='utf-8') closep = 1 try: write_pot_file(visitor.messages, options, fp)