diff --git a/Lib/encodings/base64_codec.py b/Lib/encodings/base64_codec.py index 8e7703b3b6072d..e740d2bd1c8a1c 100644 --- a/Lib/encodings/base64_codec.py +++ b/Lib/encodings/base64_codec.py @@ -11,11 +11,13 @@ ### Codec APIs def base64_encode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') return (base64.encodebytes(input), len(input)) def base64_decode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') return (base64.decodebytes(input), len(input)) class Codec(codecs.Codec): diff --git a/Lib/encodings/bz2_codec.py b/Lib/encodings/bz2_codec.py index fd9495e341baee..2f732d9344ac75 100644 --- a/Lib/encodings/bz2_codec.py +++ b/Lib/encodings/bz2_codec.py @@ -10,14 +10,20 @@ import codecs import bz2 # this codec needs the optional bz2 module ! +### Codec Helpers + +def _assert_strict(errors): + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') + ### Codec APIs def bz2_encode(input, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) return (bz2.compress(input), len(input)) def bz2_decode(input, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) return (bz2.decompress(input), len(input)) class Codec(codecs.Codec): @@ -28,7 +34,7 @@ def decode(self, input, errors='strict'): class IncrementalEncoder(codecs.IncrementalEncoder): def __init__(self, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) self.errors = errors self.compressobj = bz2.BZ2Compressor() @@ -44,7 +50,7 @@ def reset(self): class IncrementalDecoder(codecs.IncrementalDecoder): def __init__(self, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) self.errors = errors self.decompressobj = bz2.BZ2Decompressor() diff --git a/Lib/encodings/hex_codec.py b/Lib/encodings/hex_codec.py index 9fb1072804456a..ae227833a80083 100644 --- a/Lib/encodings/hex_codec.py +++ b/Lib/encodings/hex_codec.py @@ -11,11 +11,13 @@ ### Codec APIs def hex_encode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') return (binascii.b2a_hex(input), len(input)) def hex_decode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') return (binascii.a2b_hex(input), len(input)) class Codec(codecs.Codec): diff --git a/Lib/encodings/quopri_codec.py b/Lib/encodings/quopri_codec.py index 496cb7655d032d..9af22662881f83 100644 --- a/Lib/encodings/quopri_codec.py +++ b/Lib/encodings/quopri_codec.py @@ -8,14 +8,16 @@ from io import BytesIO def quopri_encode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') f = BytesIO(input) g = BytesIO() quopri.encode(f, g, quotetabs=True) return (g.getvalue(), len(input)) def quopri_decode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') f = BytesIO(input) g = BytesIO() quopri.decode(f, g) diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index 4e58c62fe9ef0f..4e9b57c8de9c84 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -14,7 +14,8 @@ ### Codec APIs def uu_encode(input, errors='strict', filename='', mode=0o666): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') infile = BytesIO(input) outfile = BytesIO() read = infile.read @@ -35,7 +36,8 @@ def uu_encode(input, errors='strict', filename='', mode=0o666): return (outfile.getvalue(), len(input)) def uu_decode(input, errors='strict'): - assert errors == 'strict' + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') infile = BytesIO(input) outfile = BytesIO() readline = infile.readline diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py index 95908a4b4a13a1..807d8b41ce40b2 100644 --- a/Lib/encodings/zlib_codec.py +++ b/Lib/encodings/zlib_codec.py @@ -8,14 +8,20 @@ import codecs import zlib # this codec needs the optional zlib module ! +### Codec Helpers + +def _assert_strict(errors): + if errors != 'strict': + raise ValueError(f'Unsupported error handling mode: "{errors}" - must be "strict"') + ### Codec APIs def zlib_encode(input, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) return (zlib.compress(input), len(input)) def zlib_decode(input, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) return (zlib.decompress(input), len(input)) class Codec(codecs.Codec): @@ -26,7 +32,7 @@ def decode(self, input, errors='strict'): class IncrementalEncoder(codecs.IncrementalEncoder): def __init__(self, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) self.errors = errors self.compressobj = zlib.compressobj() @@ -42,7 +48,7 @@ def reset(self): class IncrementalDecoder(codecs.IncrementalDecoder): def __init__(self, errors='strict'): - assert errors == 'strict' + _assert_strict(errors) self.errors = errors self.decompressobj = zlib.decompressobj() diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index d8666f7290e72e..9b64888b082df8 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3128,6 +3128,18 @@ def test_uu_invalid(self): # Missing "begin" line self.assertRaises(ValueError, codecs.decode, b"", "uu-codec") + def test_invalid_error_input(self): + # decoders/encoders require errors == 'strict' + + for encoding in bytes_transform_encodings: + with self.subTest(encoding=encoding): + encoder = codecs.getencoder(encoding) + decoder = codecs.getdecoder(encoding) + + self.assertRaises(ValueError, encoder, 'in', errors='notstrict') + self.assertRaises(ValueError, decoder, 'in', errors='notstrict') + + # The codec system tries to add notes to exceptions in order to ensure # the error mentions the operation being performed and the codec involved. diff --git a/Misc/NEWS.d/next/Library/2025-07-13-07-54-49.gh-issue-62040.jryEkb.rst b/Misc/NEWS.d/next/Library/2025-07-13-07-54-49.gh-issue-62040.jryEkb.rst new file mode 100644 index 00000000000000..19fe8636b2d3f0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-13-07-54-49.gh-issue-62040.jryEkb.rst @@ -0,0 +1,4 @@ +The ``base64_codec``, ``uu_codec``, ``quopri_codec``, ``hex_codec``, +``zlib_codec`` and ``bz2_codec`` now raise a :exc:`ValueError` when their +decoder/encoder is provided an *errors* parameter that is not equal to +``'strict'``.