diff --git a/Lib/test/test_zipapp.py b/Lib/test/test_zipapp.py index 8fb0a68deba535c..9d354bb52ce6a06 100644 --- a/Lib/test/test_zipapp.py +++ b/Lib/test/test_zipapp.py @@ -279,6 +279,12 @@ def test_read_missing_shebang(self): zipapp.create_archive(str(source), str(target)) self.assertEqual(zipapp.get_interpreter(str(target)), None) + def test_read_invalid_shebang(self): + # Test that an undecodable shebang is treated as having no interpreter. + target = self.tmpdir / 'source.pyz' + target.write_bytes(b'#!\xff\xfe\xff\xfe\nx') + self.assertIsNone(zipapp.get_interpreter(str(target))) + def test_modify_shebang(self): # Test that we can change the shebang of a file. source = self.tmpdir / 'source' diff --git a/Lib/zipapp.py b/Lib/zipapp.py index a1cef18ada9d05d..7399c50a8b22cf7 100644 --- a/Lib/zipapp.py +++ b/Lib/zipapp.py @@ -175,7 +175,10 @@ def create_archive(source, target=None, interpreter=None, main=None, def get_interpreter(archive): with _maybe_open(archive, 'rb') as f: if f.read(2) == b'#!': - return f.readline().strip().decode(shebang_encoding) + try: + return f.readline().strip().decode(shebang_encoding) + except UnicodeDecodeError: + return None def main(args=None): diff --git a/Misc/NEWS.d/next/Library/2026-10-01-05-01-08.gh-issue-158546.RtKp9M.rst b/Misc/NEWS.d/next/Library/2026-10-01-05-01-08.gh-issue-158546.RtKp9M.rst new file mode 100644 index 000000000000000..5cfce8733eb70be --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-01-05-01-08.gh-issue-158546.RtKp9M.rst @@ -0,0 +1 @@ +Treat an undecodable zipapp shebang as having no interpreter.