From e4e36f7920fd55955948d7e30235cdc12b8dcd02 Mon Sep 17 00:00:00 2001 From: Ageev Maxim Date: Sat, 5 Apr 2025 11:30:16 +0300 Subject: [PATCH 1/4] gh-131015: Add test for bytes formatting errors (#131881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> (cherry picked from commit 05557788f3c284ede73e6f94810ec796bb9d3721) --- Lib/test/test_bytes.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index a3804a945f2e3a..851fdee4f2fb6f 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -737,6 +737,36 @@ def check(fmt, vals, result): check(b'%i%b %*.*b', (10, b'3', 5, 3, b'abc',), b'103 abc') check(b'%c', b'a', b'a') + class PseudoFloat: + def __init__(self, value): + self.value = float(value) + def __int__(self): + return int(self.value) + + pi = PseudoFloat(3.1415) + + exceptions_params = [ + ('%x format: an integer is required, not float', b'%x', 3.14), + ('%X format: an integer is required, not float', b'%X', 2.11), + ('%o format: an integer is required, not float', b'%o', 1.79), + ('%x format: an integer is required, not PseudoFloat', b'%x', pi), + ('%x format: an integer is required, not complex', b'%x', 3j), + ('%X format: an integer is required, not complex', b'%X', 2j), + ('%o format: an integer is required, not complex', b'%o', 1j), + ('%u format: a real number is required, not complex', b'%u', 3j), + ('%i format: a real number is required, not complex', b'%i', 2j), + ('%d format: a real number is required, not complex', b'%d', 2j), + ( + r'%c requires an integer in range\(256\)' + r' or a single byte, not .*\.PseudoFloat', + b'%c', pi + ), + ] + + for msg, format_bytes, value in exceptions_params: + with self.assertRaisesRegex(TypeError, msg): + operator.mod(format_bytes, value) + def test_imod(self): b = self.type2test(b'hello, %b!') orig = b From 6186bd00833243d5f3e7f0b363d7ad176037b9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:45:14 +0200 Subject: [PATCH 2/4] fixup --- Lib/test/test_bytes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 851fdee4f2fb6f..1c69697e81050c 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -10,6 +10,7 @@ import sys import copy import functools +import operator import pickle import tempfile import textwrap From 5604768444d8d4991ca48cdce009cbb6a5b18fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:59:12 +0200 Subject: [PATCH 3/4] fixup --- Lib/test/test_bytes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 1c69697e81050c..07139004a81dee 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -755,7 +755,9 @@ def __int__(self): ('%X format: an integer is required, not complex', b'%X', 2j), ('%o format: an integer is required, not complex', b'%o', 1j), ('%u format: a real number is required, not complex', b'%u', 3j), - ('%i format: a real number is required, not complex', b'%i', 2j), + # See https://github.com/python/cpython/issues/130928 as for why + # the exception message contains '%d' instead of '%i'. + ('%d format: a real number is required, not complex', b'%i', 2j), ('%d format: a real number is required, not complex', b'%d', 2j), ( r'%c requires an integer in range\(256\)' From 2a88993f6b66501fb54015fbb08ec6b6f1218117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 5 Apr 2025 11:01:37 +0200 Subject: [PATCH 4/4] fixup --- Lib/test/test_bytes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 07139004a81dee..b27d43695eef77 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -760,8 +760,7 @@ def __int__(self): ('%d format: a real number is required, not complex', b'%i', 2j), ('%d format: a real number is required, not complex', b'%d', 2j), ( - r'%c requires an integer in range\(256\)' - r' or a single byte, not .*\.PseudoFloat', + r'%c requires an integer in range\(256\) or a single byte', b'%c', pi ), ]