From c1762c00ede77895e6d4d396403cf2281515769e Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 25 Mar 2023 17:26:24 -0700 Subject: [PATCH 1/3] Improve bytes formatting error Fixes #11806 This error message was last changed in #11139 to make it more applicable to f-strings. Since users are still getting confused, it makes sense to be more explicit about what the recommended fix is. There was also an extra set of quotes and a mention of Python 3 that didn't help. --- mypy/checkstrformat.py | 10 ++++------ mypyc/test-data/run-strings.test | 3 +-- test-data/unit/check-errorcodes.test | 4 ++-- test-data/unit/check-formatting.test | 20 ++++++++++---------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index e7602f33095d9..65b67f955e926 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -435,9 +435,8 @@ def perform_special_format_checks( actual_type, "__str__" ): self.msg.fail( - 'On Python 3 formatting "b\'abc\'" with "{}" ' - 'produces "b\'abc\'", not "abc"; ' - 'use "{!r}" if this is desired behavior', + 'If "x = b\'abc\'" then f"{x}" or "{}".format(x) produces "b\'abc\'", ' + 'not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x)', call, code=codes.STR_BYTES_PY3, ) @@ -946,9 +945,8 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont # Couple special cases for string formatting. if has_type_component(typ, "builtins.bytes"): self.msg.fail( - 'On Python 3 formatting "b\'abc\'" with "%s" ' - 'produces "b\'abc\'", not "abc"; ' - 'use "%r" if this is desired behavior', + 'If "x = b\'abc\'" then "%s" % x produces "b\'abc\'", not "abc"; ' + 'if this is desired behavior use "%r" % x', context, code=codes.STR_BYTES_PY3, ) diff --git a/mypyc/test-data/run-strings.test b/mypyc/test-data/run-strings.test index 4a20c13ce7899..d736983815187 100644 --- a/mypyc/test-data/run-strings.test +++ b/mypyc/test-data/run-strings.test @@ -232,8 +232,7 @@ def test_fstring_basics() -> None: x = bytes([1, 2, 3, 4]) # assert f'bytes: {x}' == "bytes: b'\\x01\\x02\\x03\\x04'" - # error: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; - # use "{!r}" if this is desired behavior behavior + # error: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) float_num = 123.4 assert f'{float_num}' == '123.4' diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 124d6952fe5fc..f58e6c1e409a0 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -638,8 +638,8 @@ def g() -> int: '%d' % 'no' # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]") [str-format] '%d + %d' % (1, 2, 3) # E: Not all arguments converted during string formatting [str-format] -'{}'.format(b'abc') # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior [str-bytes-safe] -'%s' % b'abc' # E: On Python 3 formatting "b'abc'" with "%s" produces "b'abc'", not "abc"; use "%r" if this is desired behavior [str-bytes-safe] +'{}'.format(b'abc') # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) [str-bytes-safe] +'%s' % b'abc' # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x [str-bytes-safe] [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] diff --git a/test-data/unit/check-formatting.test b/test-data/unit/check-formatting.test index 5c0d0ed652925..71433f90a8964 100644 --- a/test-data/unit/check-formatting.test +++ b/test-data/unit/check-formatting.test @@ -30,8 +30,8 @@ xb: bytes xs: str '%s' % xs # OK -'%s' % xb # E: On Python 3 formatting "b'abc'" with "%s" produces "b'abc'", not "abc"; use "%r" if this is desired behavior -'%(name)s' % {'name': b'value'} # E: On Python 3 formatting "b'abc'" with "%s" produces "b'abc'", not "abc"; use "%r" if this is desired behavior +'%s' % xb # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x +'%(name)s' % {'name': b'value'} # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x [builtins fixtures/primitives.pyi] [case testStringInterpolationCount] @@ -435,21 +435,21 @@ N = NewType('N', bytes) n: N '{}'.format(a) -'{}'.format(b) # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior -'{}'.format(x) # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior -'{}'.format(n) # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior +'{}'.format(b) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +'{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +'{}'.format(n) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) -f'{b}' # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior -f'{x}' # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior -f'{n}' # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior +f'{b}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +f'{x}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +f'{n}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) class C(Generic[B]): x: B def meth(self) -> None: - '{}'.format(self.x) # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior + '{}'.format(self.x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) def func(x: A) -> A: - '{}'.format(x) # E: On Python 3 formatting "b'abc'" with "{}" produces "b'abc'", not "abc"; use "{!r}" if this is desired behavior + '{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) return x '{!r}'.format(a) From 13f7678fd06f1fd45da1817dbb080bc95f9c2200 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 25 Mar 2023 17:44:45 -0700 Subject: [PATCH 2/3] more --- mypy/checkstrformat.py | 7 ++++--- mypyc/test-data/run-strings.test | 2 +- test-data/unit/check-errorcodes.test | 4 ++-- test-data/unit/check-formatting.test | 20 ++++++++++---------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index 65b67f955e926..fb2dec3c79602 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -436,7 +436,8 @@ def perform_special_format_checks( ): self.msg.fail( 'If "x = b\'abc\'" then f"{x}" or "{}".format(x) produces "b\'abc\'", ' - 'not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x)', + 'not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). ' + "Otherwise, decode the bytes", call, code=codes.STR_BYTES_PY3, ) @@ -945,8 +946,8 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont # Couple special cases for string formatting. if has_type_component(typ, "builtins.bytes"): self.msg.fail( - 'If "x = b\'abc\'" then "%s" % x produces "b\'abc\'", not "abc"; ' - 'if this is desired behavior use "%r" % x', + 'If "x = b\'abc\'" then "%s" % x produces "b\'abc\'", not "abc". ' + 'If this is desired behavior use "%r" % x. Otherwise, decode the bytes', context, code=codes.STR_BYTES_PY3, ) diff --git a/mypyc/test-data/run-strings.test b/mypyc/test-data/run-strings.test index d736983815187..538e5b7698c8c 100644 --- a/mypyc/test-data/run-strings.test +++ b/mypyc/test-data/run-strings.test @@ -232,7 +232,7 @@ def test_fstring_basics() -> None: x = bytes([1, 2, 3, 4]) # assert f'bytes: {x}' == "bytes: b'\\x01\\x02\\x03\\x04'" - # error: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) + # error: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes float_num = 123.4 assert f'{float_num}' == '123.4' diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index f58e6c1e409a0..4830e50dab15c 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -638,8 +638,8 @@ def g() -> int: '%d' % 'no' # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]") [str-format] '%d + %d' % (1, 2, 3) # E: Not all arguments converted during string formatting [str-format] -'{}'.format(b'abc') # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) [str-bytes-safe] -'%s' % b'abc' # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x [str-bytes-safe] +'{}'.format(b'abc') # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes [str-bytes-safe] +'%s' % b'abc' # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes [str-bytes-safe] [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] diff --git a/test-data/unit/check-formatting.test b/test-data/unit/check-formatting.test index 71433f90a8964..b1f02aaa48152 100644 --- a/test-data/unit/check-formatting.test +++ b/test-data/unit/check-formatting.test @@ -30,8 +30,8 @@ xb: bytes xs: str '%s' % xs # OK -'%s' % xb # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x -'%(name)s' % {'name': b'value'} # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc"; if this is desired behavior use "%r" % x +'%s' % xb # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes +'%(name)s' % {'name': b'value'} # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes [builtins fixtures/primitives.pyi] [case testStringInterpolationCount] @@ -435,21 +435,21 @@ N = NewType('N', bytes) n: N '{}'.format(a) -'{}'.format(b) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) -'{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) -'{}'.format(n) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +'{}'.format(b) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +'{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +'{}'.format(n) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -f'{b}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) -f'{x}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) -f'{n}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) +f'{b}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +f'{x}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +f'{n}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes class C(Generic[B]): x: B def meth(self) -> None: - '{}'.format(self.x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) + '{}'.format(self.x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes def func(x: A) -> A: - '{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x) + '{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes return x '{!r}'.format(a) From 4b7b1e81649100f6e69ee949a121c30f927d3147 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 25 Mar 2023 17:48:24 -0700 Subject: [PATCH 3/3] more --- mypy/checkstrformat.py | 4 ++-- mypyc/test-data/run-strings.test | 2 +- test-data/unit/check-errorcodes.test | 4 ++-- test-data/unit/check-formatting.test | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index fb2dec3c79602..40af0e6d648df 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -435,7 +435,7 @@ def perform_special_format_checks( actual_type, "__str__" ): self.msg.fail( - 'If "x = b\'abc\'" then f"{x}" or "{}".format(x) produces "b\'abc\'", ' + 'If x = b\'abc\' then f"{x}" or "{}".format(x) produces "b\'abc\'", ' 'not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). ' "Otherwise, decode the bytes", call, @@ -946,7 +946,7 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont # Couple special cases for string formatting. if has_type_component(typ, "builtins.bytes"): self.msg.fail( - 'If "x = b\'abc\'" then "%s" % x produces "b\'abc\'", not "abc". ' + 'If x = b\'abc\' then "%s" % x produces "b\'abc\'", not "abc". ' 'If this is desired behavior use "%r" % x. Otherwise, decode the bytes', context, code=codes.STR_BYTES_PY3, diff --git a/mypyc/test-data/run-strings.test b/mypyc/test-data/run-strings.test index 538e5b7698c8c..be668435d073f 100644 --- a/mypyc/test-data/run-strings.test +++ b/mypyc/test-data/run-strings.test @@ -232,7 +232,7 @@ def test_fstring_basics() -> None: x = bytes([1, 2, 3, 4]) # assert f'bytes: {x}' == "bytes: b'\\x01\\x02\\x03\\x04'" - # error: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes + # error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes float_num = 123.4 assert f'{float_num}' == '123.4' diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 4830e50dab15c..88b78e54f2119 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -638,8 +638,8 @@ def g() -> int: '%d' % 'no' # E: Incompatible types in string interpolation (expression has type "str", placeholder has type "Union[int, float, SupportsInt]") [str-format] '%d + %d' % (1, 2, 3) # E: Not all arguments converted during string formatting [str-format] -'{}'.format(b'abc') # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes [str-bytes-safe] -'%s' % b'abc' # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes [str-bytes-safe] +'{}'.format(b'abc') # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes [str-bytes-safe] +'%s' % b'abc' # E: If x = b'abc' then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes [str-bytes-safe] [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] diff --git a/test-data/unit/check-formatting.test b/test-data/unit/check-formatting.test index b1f02aaa48152..f5bb4c85ab3d5 100644 --- a/test-data/unit/check-formatting.test +++ b/test-data/unit/check-formatting.test @@ -30,8 +30,8 @@ xb: bytes xs: str '%s' % xs # OK -'%s' % xb # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes -'%(name)s' % {'name': b'value'} # E: If "x = b'abc'" then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes +'%s' % xb # E: If x = b'abc' then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes +'%(name)s' % {'name': b'value'} # E: If x = b'abc' then "%s" % x produces "b'abc'", not "abc". If this is desired behavior use "%r" % x. Otherwise, decode the bytes [builtins fixtures/primitives.pyi] [case testStringInterpolationCount] @@ -435,21 +435,21 @@ N = NewType('N', bytes) n: N '{}'.format(a) -'{}'.format(b) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -'{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -'{}'.format(n) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +'{}'.format(b) # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +'{}'.format(x) # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +'{}'.format(n) # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -f'{b}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -f'{x}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes -f'{n}' # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +f'{b}' # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +f'{x}' # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes +f'{n}' # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes class C(Generic[B]): x: B def meth(self) -> None: - '{}'.format(self.x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes + '{}'.format(self.x) # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes def func(x: A) -> A: - '{}'.format(x) # E: If "x = b'abc'" then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes + '{}'.format(x) # E: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes return x '{!r}'.format(a)