[llvm] Revert "[Lit] Change processRedirects to open all files in binary mode" (PR #196328)

Benjamin Stott via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 07:32:40 PDT 2026


https://github.com/BStott6 created https://github.com/llvm/llvm-project/pull/196328

Reverts llvm/llvm-project#194368 due to breaking tests on z/OS

>From 11608cdc25c9fb7013bd322d755928adc45ef528 Mon Sep 17 00:00:00 2001
From: Benjamin Stott <Benjamin.Stott at sony.com>
Date: Thu, 7 May 2026 15:32:11 +0100
Subject: [PATCH] Revert "[Lit] Change processRedirects to open all files in
 binary mode (#194368)"

This reverts commit d769ce21768c66a04b3e46d1b330fd29238b34a5.
---
 llvm/utils/lit/lit/InprocBuiltins.py   | 26 +++++++++++++-------------
 llvm/utils/lit/lit/ShellEnvironment.py | 17 ++++++++---------
 llvm/utils/lit/lit/TestRunner.py       |  6 +++---
 llvm/utils/lit/tests/shtest-glob.py    |  2 +-
 4 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/llvm/utils/lit/lit/InprocBuiltins.py b/llvm/utils/lit/lit/InprocBuiltins.py
index 34a4d7eae1e88..b20aeb6993726 100644
--- a/llvm/utils/lit/lit/InprocBuiltins.py
+++ b/llvm/utils/lit/lit/InprocBuiltins.py
@@ -5,7 +5,7 @@
 import shutil
 import stat
 import subprocess
-from io import BytesIO, StringIO
+from io import StringIO
 
 import lit.util
 from lit.ShellEnvironment import (
@@ -70,7 +70,13 @@ def executeBuiltinEcho(cmd, shenv):
     is_redirected = True
     if stdout == subprocess.PIPE:
         is_redirected = False
-        stdout = BytesIO()
+        stdout = StringIO()
+    elif kIsWindows:
+        # Reopen stdout with `newline=""` to avoid CRLF translation.
+        # The versions of echo we are replacing on Windows all emit plain LF,
+        # and the LLVM tests now depend on this.
+        stdout = open(stdout.name, stdout.mode, encoding="utf-8", newline="")
+        opened_files.append((None, None, stdout, None))
 
     # Implement echo flags. We only support -e and -n, and not yet in
     # combination. We have to ignore unknown flags, because `echo "-D FOO"`
@@ -94,22 +100,16 @@ def maybeUnescape(arg):
 
     if args:
         for arg in args[:-1]:
-            stdout.write(maybeUnescape(arg).encode())
-            stdout.write(b" ")
-        stdout.write(maybeUnescape(args[-1]).encode())
+            stdout.write(maybeUnescape(arg))
+            stdout.write(" ")
+        stdout.write(maybeUnescape(args[-1]))
     if write_newline:
-        stdout.write("\n".encode())
+        stdout.write("\n")
 
     for name, mode, f, path in opened_files:
         f.close()
 
-    output = (
-        ""
-        if is_redirected
-        # TODO(BStott) remove decode once new interface for in-process builtin
-        # IO is introduced.
-        else stdout.getvalue().decode(encoding="utf8", errors="replace")
-    )
+    output = "" if is_redirected else stdout.getvalue()
     return ShellCommandResult(cmd, output, "", 0, False)
 
 
diff --git a/llvm/utils/lit/lit/ShellEnvironment.py b/llvm/utils/lit/lit/ShellEnvironment.py
index b4ff7b1a120f6..4f6753bd11b52 100644
--- a/llvm/utils/lit/lit/ShellEnvironment.py
+++ b/llvm/utils/lit/lit/ShellEnvironment.py
@@ -108,19 +108,19 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files):
     redirects = [(0,), (1,), (2,)]
     for op, filename in cmd.redirects:
         if op == (">", 2):
-            redirects[2] = [filename, "wb", None]
+            redirects[2] = [filename, "w", None]
         elif op == (">>", 2):
-            redirects[2] = [filename, "ab", None]
+            redirects[2] = [filename, "a", None]
         elif op == (">&", 2) and filename in "012":
             redirects[2] = redirects[int(filename)]
         elif op == (">&",) or op == ("&>",):
-            redirects[1] = redirects[2] = [filename, "wb", None]
+            redirects[1] = redirects[2] = [filename, "w", None]
         elif op == (">",):
-            redirects[1] = [filename, "wb", None]
+            redirects[1] = [filename, "w", None]
         elif op == (">>",):
-            redirects[1] = [filename, "ab", None]
+            redirects[1] = [filename, "a", None]
         elif op == ("<",):
-            redirects[0] = [filename, "rb", None]
+            redirects[0] = [filename, "r", None]
         else:
             raise InternalShellError(
                 cmd, "Unsupported redirect: %r" % ((op, filename),)
@@ -173,12 +173,11 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files):
         else:
             # Make sure relative paths are relative to the cwd.
             redir_filename = os.path.join(cmd_shenv.cwd, name)
-            fd = open(redir_filename, mode)
-
+            fd = open(redir_filename, mode, encoding="utf-8")
         # Workaround a Win32 and/or subprocess bug when appending.
         #
         # FIXME: Actually, this is probably an instance of PR6753.
-        if mode == "ab":
+        if mode == "a":
             fd.seek(0, 2)
         # Mutate the underlying redirect list so that we can redirect stdout
         # and stderr to the same place without opening the file twice.
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 743f7bcccd533..32f47109053a6 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -520,11 +520,11 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
         if procs[i].stdout is not None:
             out = procs[i].stdout.read()
         else:
-            out = b""
+            out = ""
         if procs[i].stderr is not None:
             err = procs[i].stderr.read()
         else:
-            err = b""
+            err = ""
         procData[i] = (out, err)
 
     # Read stderr out of the temp files.
@@ -567,7 +567,7 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
         output_files = []
         if res != 0:
             for (name, mode, f, path) in sorted(opened_files):
-                if path is not None and mode in ("wb", "ab"):
+                if path is not None and mode in ("w", "a"):
                     try:
                         with open(path, "rb") as f:
                             data = f.read()
diff --git a/llvm/utils/lit/tests/shtest-glob.py b/llvm/utils/lit/tests/shtest-glob.py
index 95a53e4dd2223..ba609e036c166 100644
--- a/llvm/utils/lit/tests/shtest-glob.py
+++ b/llvm/utils/lit/tests/shtest-glob.py
@@ -5,7 +5,7 @@
 # END.
 
 # CHECK: UNRESOLVED: shtest-glob :: glob-echo.txt ({{[^)]*}})
-# CHECK: AttributeError: 'GlobItem' object has no attribute 'encode'
+# CHECK: TypeError: string argument expected, got 'GlobItem'
 
 # CHECK:      FAIL: shtest-glob :: glob-mkdir.txt ({{[^)]*}})
 # CHECK:      # | Error: 'mkdir' command failed, {{.*}}example_file1.input'



More information about the llvm-commits mailing list