Mercurial > hg
changeset 51310:f0e7d51bb454 stable
pycompat: fix bytestr(bytes) in Python 3.11
In Python 3.10, the `bytes` type itself does not have a `__bytes__`
attribute, but it does in 3.11. Yet `bytes(bytes)` does not give
the wished output, so we have to add an exceptional case.
The added case in the doctest reproduces the problem with Python 3.11.
Impact: error treatment in expressions such as `repo[b'invalid']` gets
broken.
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Wed, 03 Jan 2024 18:33:39 +0100 |
parents | 9b44b25dece1 |
children | 136902b3a95d |
files | mercurial/pycompat.py |
diffstat | 1 files changed, 10 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/pycompat.py Thu Jan 04 14:45:31 2024 -0500 +++ b/mercurial/pycompat.py Wed Jan 03 18:33:39 2024 +0100 @@ -203,6 +203,13 @@ >>> bytestr(bytesable()) 'bytes' + ...unless the argument is the bytes *type* itself: it gets a + __bytes__() method in Python 3.11, which cannot be used as in an instance + of bytes: + + >>> bytestr(bytes) + "<class 'bytes'>" + There's no implicit conversion from non-ascii str as its encoding is unknown: @@ -252,10 +259,9 @@ def __new__(cls: Type[_Tbytestr], s: object = b'') -> _Tbytestr: if isinstance(s, bytestr): return s - if not isinstance( - s, (bytes, bytearray) - ) and not builtins.hasattr( # hasattr-py3-only - s, u'__bytes__' + if not isinstance(s, (bytes, bytearray)) and ( + isinstance(s, type) + or not builtins.hasattr(s, u'__bytes__') # hasattr-py3-only ): s = str(s).encode('ascii') return bytes.__new__(cls, s)