-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
When the % operator is used to format a bytes string with a placeholder of %b (bytes) and an argument of type bytearray the interpolation will succeed as bytearray has a __bytes__ method as per PEP 0461. The same is also true of memoryview objects as well as any type with a __bytes__ method.
MyPy will not flag an error for bytearray or memoryview objects but will for classes with a __bytes__ method. If --disable-bytearray-promotion or --disable-memoryview-promotion are used then these string interpolations will be flagged as a str-format error - presumably is it stops silently treating these classes as equivalent to bytes.
PEP 0461 states that %b should be correct for any class with a __bytes__ method.
%b will insert a series of bytes. These bytes are collected in one of two ways:
To Reproduce
MyPy reports no errors with this code by default.
a = b"foo"
b = bytearray(a)
c = memoryview(a)
x = b"%b" % a
y = b"%b" % b
z = b"%b" % cWith --disable-bytearray-promotion it reports
/tmp/test.py:6: error: Incompatible types in string interpolation (expression has type "bytearray", placeholder has type "bytes") [str-format]
Similarly
class X:
def __bytes__(self) -> bytes:
return b"X"
m = b"%b" % X()Will produce the error
/tmp/test.py:6: error: Incompatible types in string interpolation (expression has type "X", placeholder has type "bytes") [str-format]
Both of these samples run without error and with the expected behaviour.
Expected Behavior
No str-format error reported for interpolating %b placeholder in bytes string for objects with a __bytes__ method.
Your Environment
- Mypy version used: 1.17.1
- Mypy command-line flags: Defaults or --disable-bytearrary-promotion or --disable-memoryview-promotion
- Mypy configuration options from
mypy.ini(and other config files): - Python version used: 3.13.2