From 698e9eaad27dec9555002f81054ebb8d4b28a45d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 27 Aug 2026 01:00:05 +0300 Subject: [PATCH] gh-109714: Omit redundant arguments when raising OSError subclasses errno now defaults to the error code which corresponds to the exception class, and strerror is derived from it, so passing them explicitly adds nothing in _pyio, _pyrepl, multiprocessing and shutil. BlockingIOError in _pyio now passes the number of characters written by keyword, and FileExistsError in multiprocessing passes only the Windows error code, from which both errno and strerror are derived. Co-Authored-By: Claude Opus 5 (1M context) --- Lib/_pyio.py | 7 +++---- Lib/_pyrepl/terminfo.py | 3 +-- Lib/multiprocessing/shared_memory.py | 7 ++----- Lib/shutil.py | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Lib/_pyio.py b/Lib/_pyio.py index cf4ef04f37d26c..5a9d232b183ca6 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1325,8 +1325,8 @@ def _flush_unlocked(self): "should not raise BlockingIOError") if n is None: raise BlockingIOError( - errno.EAGAIN, - "write could not complete without blocking", 0) + "write could not complete without blocking", + characters_written=0) if n > len(self._write_buf) or n < 0: raise OSError("write() returned incorrect number of bytes") del self._write_buf[:n] @@ -1629,8 +1629,7 @@ def __init__(self, file, mode='r', closefd=True, opener=None): self._stat_atopen = os.fstat(fd) try: if stat.S_ISDIR(self._stat_atopen.st_mode): - raise IsADirectoryError(errno.EISDIR, - os.strerror(errno.EISDIR), file) + raise IsADirectoryError(filename=file) except AttributeError: # Ignore the AttributeError if stat.S_ISDIR or errno.EISDIR # don't exist. diff --git a/Lib/_pyrepl/terminfo.py b/Lib/_pyrepl/terminfo.py index d02ef69cce0bd8..5ba91d6ecbf116 100644 --- a/Lib/_pyrepl/terminfo.py +++ b/Lib/_pyrepl/terminfo.py @@ -1,7 +1,6 @@ """Pure Python curses-like terminal capability queries.""" from dataclasses import dataclass, field -import errno import os from pathlib import Path import re @@ -151,7 +150,7 @@ def _read_terminfo_file(terminal_name: str) -> bytes: if path.is_file(): return path.read_bytes() - raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), filename) + raise FileNotFoundError(filename=filename) # Hard-coded terminal capabilities for common terminals diff --git a/Lib/multiprocessing/shared_memory.py b/Lib/multiprocessing/shared_memory.py index 99a8ce3320ad4e..9af2eb41afdcad 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -11,7 +11,6 @@ from functools import partial import mmap import os -import errno import struct import secrets import types @@ -143,10 +142,8 @@ def __init__(self, name=None, create=False, size=0, *, track=True): if last_error_code == _winapi.ERROR_ALREADY_EXISTS: if name is not None: raise FileExistsError( - errno.EEXIST, - os.strerror(errno.EEXIST), - name, - _winapi.ERROR_ALREADY_EXISTS + filename=name, + winerror=_winapi.ERROR_ALREADY_EXISTS ) else: continue diff --git a/Lib/shutil.py b/Lib/shutil.py index ab75ba9da8894b..2dc437092f5c9f 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1245,7 +1245,7 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, root_dir = os.fspath(root_dir) stmd = os.stat(root_dir).st_mode if not stat.S_ISDIR(stmd): - raise NotADirectoryError(errno.ENOTDIR, 'Not a directory', root_dir) + raise NotADirectoryError(filename=root_dir) if supports_root_dir: kwargs['root_dir'] = root_dir