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)