[llvm] [lit] Use text mode when opening text files on z/OS (PR #217434)

Abhina Sree via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 06:07:54 PDT 2026


https://github.com/abhina-sree updated https://github.com/llvm/llvm-project/pull/217434

>From fed4c46a4c89a739e1c319cbac7e8d7ceb181c74 Mon Sep 17 00:00:00 2001
From: Abhina Sreeskantharajan <Abhina.Sreeskantharajan at ibm.com>
Date: Wed, 19 Aug 2026 14:55:57 -0400
Subject: [PATCH 1/3] when piping output, use a text stream to enable
 autoconversion on z/OS

---
 llvm/utils/lit/lit/ShellEnvironment.py     |  6 +-----
 llvm/utils/lit/lit/TestRunner.py           |  2 +-
 llvm/utils/lit/lit/builtin_commands/cat.py | 18 +++++++++++++++---
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/llvm/utils/lit/lit/ShellEnvironment.py b/llvm/utils/lit/lit/ShellEnvironment.py
index e2cf602de96ff..3cf41c4ab2c6b 100644
--- a/llvm/utils/lit/lit/ShellEnvironment.py
+++ b/llvm/utils/lit/lit/ShellEnvironment.py
@@ -228,11 +228,7 @@ def as_binary_reader(stream: None | int | io.TextIOBase | BinaryIO) -> BinaryIO:
         # No real input to read.
         return io.BytesIO(b"")
     if isinstance(stream, io.TextIOBase):
-        buffer = getattr(stream, "buffer", None)
-        if buffer is not None:
-            return buffer
-        data = stream.read()
-        return io.BytesIO(data.encode() if isinstance(data, str) else data)
+        return stream
     # Already a binary reader.
     assert hasattr(stream, "read"), f"expected a binary reader, got {type(stream)!r}"
     return stream
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 30a39745d01b9..490f8f1f5c02b 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -403,7 +403,7 @@ def _make_out_sink(stdout: int | TextIO, is_last: bool) -> IO[bytes] | None:
         last stage or a non-pipe target, which don't need this sink.
     """
     if stdout == subprocess.PIPE and not is_last:
-        return tempfile.SpooledTemporaryFile(max_size=1 << 20)
+        return tempfile.SpooledTemporaryFile(max_size=1 << 20, mode="w+")
     return None
 
 
diff --git a/llvm/utils/lit/lit/builtin_commands/cat.py b/llvm/utils/lit/lit/builtin_commands/cat.py
index bfd6e86f46bdb..8d6204543b04a 100644
--- a/llvm/utils/lit/lit/builtin_commands/cat.py
+++ b/llvm/utils/lit/lit/builtin_commands/cat.py
@@ -90,9 +90,21 @@ def run(argv, stdin, stdout, stderr, cwd):
 
         if show_nonprinting:
             contents = convertToCaretAndMNotation(contents)
-        elif is_text:
-            contents = contents.encode()
-        stdout.write(contents)
+        # Determine if stdout expects text or binary
+        is_text_output = False
+        if hasattr(stdout, "mode"):
+            mode = getattr(stdout, "mode", "b")
+            is_text_output = "b" not in mode
+
+        if is_text_output:
+            if isinstance(contents, bytes):
+                contents = contents.decode()
+            stdout.write(contents)
+        else:
+            if isinstance(contents, str):
+                contents = contents.encode()
+            stdout.write(contents)
+
     return 0
 
 

>From b7fb2cf7d85380a384d3f8013a703473fb6b6941 Mon Sep 17 00:00:00 2001
From: Abhina Sreeskantharajan <Abhina.Sreeskantharajan at ibm.com>
Date: Thu, 20 Aug 2026 09:58:24 -0400
Subject: [PATCH 2/3] update diff.py and guard changes for z/OS

---
 llvm/utils/lit/lit/ShellEnvironment.py      |  6 +++++-
 llvm/utils/lit/lit/TestRunner.py            |  4 +++-
 llvm/utils/lit/lit/builtin_commands/cat.py  | 10 ++++------
 llvm/utils/lit/lit/builtin_commands/diff.py | 16 ++++++++++++++--
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/llvm/utils/lit/lit/ShellEnvironment.py b/llvm/utils/lit/lit/ShellEnvironment.py
index 3cf41c4ab2c6b..e2cf602de96ff 100644
--- a/llvm/utils/lit/lit/ShellEnvironment.py
+++ b/llvm/utils/lit/lit/ShellEnvironment.py
@@ -228,7 +228,11 @@ def as_binary_reader(stream: None | int | io.TextIOBase | BinaryIO) -> BinaryIO:
         # No real input to read.
         return io.BytesIO(b"")
     if isinstance(stream, io.TextIOBase):
-        return stream
+        buffer = getattr(stream, "buffer", None)
+        if buffer is not None:
+            return buffer
+        data = stream.read()
+        return io.BytesIO(data.encode() if isinstance(data, str) else data)
     # Already a binary reader.
     assert hasattr(stream, "read"), f"expected a binary reader, got {type(stream)!r}"
     return stream
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 490f8f1f5c02b..87e26b25a5fa8 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -4,6 +4,7 @@
 import io
 import os
 import pathlib
+import platform
 import re
 import shlex
 import signal
@@ -403,7 +404,8 @@ def _make_out_sink(stdout: int | TextIO, is_last: bool) -> IO[bytes] | None:
         last stage or a non-pipe target, which don't need this sink.
     """
     if stdout == subprocess.PIPE and not is_last:
-        return tempfile.SpooledTemporaryFile(max_size=1 << 20, mode="w+")
+        _mode = "w+" if platform.system() == "OS/390" else "w+b"
+        return tempfile.SpooledTemporaryFile(max_size=1 << 20, mode=_mode)
     return None
 
 
diff --git a/llvm/utils/lit/lit/builtin_commands/cat.py b/llvm/utils/lit/lit/builtin_commands/cat.py
index 8d6204543b04a..16d745fcfb442 100644
--- a/llvm/utils/lit/lit/builtin_commands/cat.py
+++ b/llvm/utils/lit/lit/builtin_commands/cat.py
@@ -90,20 +90,18 @@ def run(argv, stdin, stdout, stderr, cwd):
 
         if show_nonprinting:
             contents = convertToCaretAndMNotation(contents)
+
         # Determine if stdout expects text or binary
-        is_text_output = False
-        if hasattr(stdout, "mode"):
-            mode = getattr(stdout, "mode", "b")
-            is_text_output = "b" not in mode
+        mode = getattr(stdout, "mode", "b")
+        is_text_output = "b" not in mode
 
         if is_text_output:
             if isinstance(contents, bytes):
                 contents = contents.decode()
-            stdout.write(contents)
         else:
             if isinstance(contents, str):
                 contents = contents.encode()
-            stdout.write(contents)
+        stdout.write(contents)
 
     return 0
 
diff --git a/llvm/utils/lit/lit/builtin_commands/diff.py b/llvm/utils/lit/lit/builtin_commands/diff.py
index 3a85d2210705f..7f286fd5e16be 100644
--- a/llvm/utils/lit/lit/builtin_commands/diff.py
+++ b/llvm/utils/lit/lit/builtin_commands/diff.py
@@ -5,6 +5,7 @@
 import os
 import re
 import sys
+import platform
 
 # diff.py runs in two modes during the in-process migration:
 #   - In-process: imported as 'lit.builtin_commands.diff', so __package__ is
@@ -63,11 +64,22 @@ def getDirTree(path, basedir=""):
 def compareTwoFiles(flags, filepaths, stdin, stdout):
     filelines = []
     for file in filepaths:
+        is_text = False
         if file == "-":
             filelines.append(stdin.readlines())
         else:
-            with open(file, "rb") as file_bin:
-                filelines.append(file_bin.readlines())
+            if platform.system() == "OS/390":
+                try:
+                    with open(file, "r") as file_text:
+                        filelines.append(
+                            file_text.read().encode().splitlines(keepends=True)
+                        )
+                        is_text = True
+                except:
+                    pass
+            if not is_text:
+                with open(file, "rb") as file_bin:
+                    filelines.append(file_bin.readlines())
 
     try:
         return compareTwoTextFiles(

>From feba229abfada8efc283af742069583c9b2b002d Mon Sep 17 00:00:00 2001
From: Abhina Sreeskantharajan <Abhina.Sreeskantharajan at ibm.com>
Date: Fri, 21 Aug 2026 09:07:39 -0400
Subject: [PATCH 3/3] formatting

---
 llvm/utils/lit/lit/builtin_commands/cat.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/utils/lit/lit/builtin_commands/cat.py b/llvm/utils/lit/lit/builtin_commands/cat.py
index 16d745fcfb442..2882b79f572fd 100644
--- a/llvm/utils/lit/lit/builtin_commands/cat.py
+++ b/llvm/utils/lit/lit/builtin_commands/cat.py
@@ -102,7 +102,6 @@ def run(argv, stdin, stdout, stderr, cwd):
             if isinstance(contents, str):
                 contents = contents.encode()
         stdout.write(contents)
-
     return 0
 
 



More information about the llvm-commits mailing list