From 51b976da439be272db8c044c7ba8856bca1399ff Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:27:02 +0300 Subject: [PATCH] gh-132631: Fix "I/O operation on closed file" when parsing JSON Lines file (GH-132632) (cherry picked from commit 42d645a7e81e0a5e6e0d35e222a8520450ac28ef) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Brian Schubert --- Lib/json/tool.py | 3 ++- Lib/test/test_json/json_lines.jsonl | 2 ++ Lib/test/test_json/test_tool.py | 9 +++++++++ .../2025-04-17-15-26-35.gh-issue-132631.IDFZfb.rst | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Lib/test/test_json/json_lines.jsonl create mode 100644 Misc/NEWS.d/next/Library/2025-04-17-15-26-35.gh-issue-132631.IDFZfb.rst diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 1967817add8abc..0cabbdba85a155 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -88,7 +88,8 @@ def main(): infile = open(options.infile, encoding='utf-8') try: if options.json_lines: - objs = (json.loads(line) for line in infile) + lines = infile.readlines() + objs = (json.loads(line) for line in lines) else: objs = (json.load(infile),) finally: diff --git a/Lib/test/test_json/json_lines.jsonl b/Lib/test/test_json/json_lines.jsonl new file mode 100644 index 00000000000000..d2f292111956f3 --- /dev/null +++ b/Lib/test/test_json/json_lines.jsonl @@ -0,0 +1,2 @@ +{"ingredients":["frog", "water", "chocolate", "glucose"]} +{"ingredients":["chocolate","steel bolts"]} diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 7b5d217a21558c..0a96b318b15b1c 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -1,4 +1,5 @@ import errno +import pathlib import os import sys import textwrap @@ -157,6 +158,14 @@ def test_jsonlines(self): self.assertEqual(process.stdout, self.jsonlines_expect) self.assertEqual(process.stderr, '') + @force_not_colorized + def test_jsonlines_from_file(self): + jsonl = pathlib.Path(__file__).parent / 'json_lines.jsonl' + args = sys.executable, '-m', self.module, '--json-lines', jsonl + process = subprocess.run(args, capture_output=True, text=True, check=True) + self.assertEqual(process.stdout, self.jsonlines_expect) + self.assertEqual(process.stderr, '') + def test_help_flag(self): rc, out, err = assert_python_ok('-m', self.module, '-h', PYTHON_COLORS='0') diff --git a/Misc/NEWS.d/next/Library/2025-04-17-15-26-35.gh-issue-132631.IDFZfb.rst b/Misc/NEWS.d/next/Library/2025-04-17-15-26-35.gh-issue-132631.IDFZfb.rst new file mode 100644 index 00000000000000..9cc1d5a389c085 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-17-15-26-35.gh-issue-132631.IDFZfb.rst @@ -0,0 +1,2 @@ +Fix "I/O operation on closed file" when parsing JSON Lines file with +:mod:`JSON CLI `.