GeezerVison is showing github.com — zipapp.get_interpreter() raises UnicodeDecodeError on invalid shebang bytes · Issue #158546 · python/cpython
zipapp.get_interpreter() raises UnicodeDecodeError on invalid shebang bytes #158546Descriptionzipapp.get_interpreter() raises UnicodeDecodeError when the shebang
line contains bytes that aren't valid in shebang_encoding, instead of
returning None.
Reproducer:
import zipapp, tempfile, os
d = tempfile.mkdtemp()
p = os.path.join(d, "a.pyz")
with open(p, "wb") as f:
f.write(b"#!\xff\xfe\xff\xfe\nx")
print(repr(zipapp.get_interpreter(p)))
Actual:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Expected:
None (treat undecodable shebang as "no interpreter")
The function already returns None for "no shebang", so returning
None for an undecodable shebang is consistent. The CLI renders
None as <none>.
Tested on: main.
Linked PRs
Activitypicnixz commented on Oct 1, 2026
The function already returns None for "no shebang", so returning
None for an undecodable shebang is consistent. The CLI renders
None as .
I don't know in this case. The shebang encoding is determined as follows:
# The Windows launcher defaults to UTF-8 when parsing shebang lines if the
# file has no BOM. So use UTF-8 on Windows.
# On Unix, use the filesystem encoding.
if sys.platform.startswith('win'):
shebang_encoding = 'utf-8'
else:
shebang_encoding = sys.getfilesystemencoding()
So we can assume that undecodable shebang should raise an error somehow. I'm ok with ignoring it though but the docs say:
An optional shebang line, containing the characters b'#!' followed by an interpreter name, and then a newline (b'\n') character. The interpreter name can be anything acceptable to the OS “shebang” processing, or the Python launcher on Windows. The interpreter should be encoded in UTF-8 on Windows, and in sys.getfilesystemencoding() on POSIX.
I think it's more likely for a shebang-like line to be considered a shebang and then loudly fail otherwise. Tony123-tech commented on Oct 11, 2026 ContributorAuthor More actions Thanks for taking a look.
I see the argument for loud failure: the encoding is well-defined, so
undecodable bytes indicate a malformed file. But I'd lean toward
returning None for a few reasons:
-
get_interpreter() already returns None when there's no shebang
line at all. A shebang line that isn't decodable is, from the
caller's perspective, equally "no usable interpreter" — there's
nothing the caller can do with the bytes.
-
The CLI renders None as , which is a reasonable user-facing
outcome for a broken shebang.
-
Raising UnicodeDecodeError leaks an encoding detail into an API
whose contract is "return the interpreter name or None". Callers
currently have to catch UnicodeDecodeError to use the function
safely on untrusted archives.
If the consensus is that this should raise, I'm happy to change the
PR to do that instead — just let me know which behavior the maintainers
prefer.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|