Commit 4cacecaaa2 for

commit 4cacecaaa2bbf8af0967bd3eee43297fada475a9
Author: Philippe Mathieu-Daudé <>
Date:   Sun Jan 10 01:02:40 2021 +0100

    decodetree: Open files with encoding='utf-8'

    When was added in commit 568ae7efae7, QEMU was
    using Python 2 which happily reads UTF-8 files in text mode.
    Python 3 requires either UTF-8 locale or an explicit encoding
    passed to open(). Now that Python 3 is required, explicit
    UTF-8 encoding for decodetree source files.

    To avoid further problems with the user locale, also explicit
    UTF-8 encoding for the generated C files.

    Explicit both input/output are plain text by using the 't' mode.

    This fixes:

      $ /usr/bin/python3 scripts/ test.decode
      Traceback (most recent call last):
        File "scripts/", line 1397, in <module>
        File "scripts/", line 1308, in main
          parse_file(f, toppat)
        File "scripts/", line 994, in parse_file
          for line in f:
        File "/usr/lib/python3.6/encodings/", line 26, in decode
          return codecs.ascii_decode(input, self.errors)[0]
      UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 80:
      ordinal not in range(128)

    Reported-by: Peter Maydell <>
    Suggested-by: Yonggang Luo <>
    Reviewed-by: Eduardo Habkost <>
    Signed-off-by: Philippe Mathieu-Daudé <>
    Message-Id: <>
    Signed-off-by: Richard Henderson <>

diff --git a/scripts/ b/scripts/
index 47aa9caf6d..4637b633e7 100644
--- a/scripts/
+++ b/scripts/
@@ -20,6 +20,7 @@
 # See the syntax and semantics in docs/devel/decodetree.rst.

+import io
 import os
 import re
 import sys
@@ -1304,7 +1305,7 @@ def main():

     for filename in args:
         input_file = filename
-        f = open(filename, 'r')
+        f = open(filename, 'rt', encoding='utf-8')
         parse_file(f, toppat)

@@ -1324,9 +1325,11 @@ def main():

     if output_file:
-        output_fd = open(output_file, 'w')
+        output_fd = open(output_file, 'wt', encoding='utf-8')
-        output_fd = sys.stdout
+        output_fd = io.TextIOWrapper(sys.stdout.buffer,
+                                     encoding=sys.stdout.encoding,
+                                     errors="ignore")

     for n in sorted(arguments.keys()):