From 563d7b821b85d75b53f3522b2aa5850f1382dc2e Mon Sep 17 00:00:00 2001 From: Jack Strang Date: Thu, 13 Mar 2025 11:21:07 -0400 Subject: [PATCH 1/6] feat: type check alignment format specifiers --- mypy/checkstrformat.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index 289961523b1d..91cc9263ae99 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -1073,6 +1073,14 @@ def conversion_type( return UnionType( [self.named_type("builtins.int"), self.named_type("builtins.str")] ) + elif p in ["<", ">", "=", "^"]: + return UnionType( + [ + self.named_type("builtins.int"), + self.named_type("builtins.float"), + self.named_type("builtins.str") + ] + ) else: self.msg.unsupported_placeholder(p, context) return None From 67d23de2d6cf8aa0cefd88a9e2299b1970ecdad2 Mon Sep 17 00:00:00 2001 From: Jack Strang Date: Thu, 13 Mar 2025 11:29:42 -0400 Subject: [PATCH 2/6] fix and add test case --- mypy/checkstrformat.py | 2 +- test-data/unit/check-errorcodes.test | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index 91cc9263ae99..ddc2bff3122d 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -1073,7 +1073,7 @@ def conversion_type( return UnionType( [self.named_type("builtins.int"), self.named_type("builtins.str")] ) - elif p in ["<", ">", "=", "^"]: + elif p.startswith(("<", ">", "=", "^")): return UnionType( [ self.named_type("builtins.int"), diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 6ec246fb3a13..afb8818aa219 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -645,6 +645,7 @@ def g() -> int: '{}'.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] +'{:>2}'.format(None) [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] From 89b370071f19fe3bf095b33ca859a175818c30eb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:32:43 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/checkstrformat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index ddc2bff3122d..54e370fd58e6 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -1076,9 +1076,9 @@ def conversion_type( elif p.startswith(("<", ">", "=", "^")): return UnionType( [ - self.named_type("builtins.int"), - self.named_type("builtins.float"), - self.named_type("builtins.str") + self.named_type("builtins.int"), + self.named_type("builtins.float"), + self.named_type("builtins.str"), ] ) else: From 2ba0d8462739c56da67a87fad60a0f69c3adf52a Mon Sep 17 00:00:00 2001 From: Jack Strang Date: Thu, 13 Mar 2025 11:39:38 -0400 Subject: [PATCH 4/6] set test to desired --- test-data/unit/check-errorcodes.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index afb8818aa219..d6d9ada0a5c6 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -645,7 +645,8 @@ def g() -> int: '{}'.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] -'{:>2}'.format(None) +'{:>2}'.format(None) # E: alignment types do not support string formatting [str-format] + [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] From 6c85e5f0b27f409b6978520aa11128934d8606b1 Mon Sep 17 00:00:00 2001 From: Jack Strang Date: Thu, 13 Mar 2025 11:58:11 -0400 Subject: [PATCH 5/6] improve comment in tests --- test-data/unit/check-errorcodes.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index d6d9ada0a5c6..aeb15bd66ef4 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -645,7 +645,7 @@ def g() -> int: '{}'.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] -'{:>2}'.format(None) # E: alignment types do not support string formatting [str-format] +'{:>2}'.format(None) # E: alignment format specs are not supported on NoneType [str-format] [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] From 6439b1310b981e23415dde64cf93b59fbfa462ba Mon Sep 17 00:00:00 2001 From: Jack Strang Date: Thu, 13 Mar 2025 11:59:03 -0400 Subject: [PATCH 6/6] add inline comment --- mypy/checkstrformat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index 54e370fd58e6..09758e7d990a 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -1074,6 +1074,7 @@ def conversion_type( [self.named_type("builtins.int"), self.named_type("builtins.str")] ) elif p.startswith(("<", ">", "=", "^")): + # THIS CODE IS WRONG return UnionType( [ self.named_type("builtins.int"),