[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