Fix function call message change for small number of args (#21432)

Refs https://github.com/python/mypy/issues/21427

I used `2` as a magic number, because in my opinion it is easier to tell
the difference when all errors show up for the small number of args.

---------

Co-authored-by: hauntsaninja <hauntsaninja@gmail.com>
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
index 123c5f8..71ffa7c 100644
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -1787,6 +1787,7 @@
 
         might_have_shifted_args = (
             not self.msg.prefer_simple_messages()
+            and len(args) >= 2  # see gh-21427
             and all(k == ARG_POS for k in callee.arg_kinds)
             and all(k == ARG_POS for k in arg_kinds)
             and len(arg_kinds) == len(callee.arg_kinds) - 1
diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test
index bd2bf26..893eefb 100644
--- a/test-data/unit/check-functions.test
+++ b/test-data/unit/check-functions.test
@@ -3814,9 +3814,9 @@
 main:3: error: Missing positional argument "y" in call to "f"
 
 [case testMissingPositionalArgShiftDetectedFirst]
-def f(x: int, y: str, z: bytes) -> None: ...
+def f(x: int, y: str, z: bytes, last: float) -> None: ...
 
-f("hello", b'x')
+f("hello", b'x', 1.5)
 [builtins fixtures/primitives.pyi]
 [out]
 main:3: error: Missing positional argument "x" in call to "f"
@@ -3891,3 +3891,46 @@
 main:3: error: Missing positional argument "z" in call to "f"
 main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int"
 main:3: error: Argument 2 to "f" has incompatible type "bytes"; expected "str"
+
+[case testMissingPositionalArgNamesHigherN]
+# See https://github.com/python/mypy/issues/21427
+def convert2(first: int, second: str) -> None: ...
+
+# Possibly omitted arg, but we still issue two errors because there is only one argument
+convert2("hello")  # E: Missing positional argument "second" in call to "convert2" \
+                   # E: Argument 1 to "convert2" has incompatible type "str"; expected "int"
+
+# Other cases
+convert2()  # E: Missing positional arguments "first", "second" in call to "convert2"
+
+convert2("hello", 1)  # E: Argument 1 to "convert2" has incompatible type "str"; expected "int" \
+                      # E: Argument 2 to "convert2" has incompatible type "int"; expected "str"
+
+def convert3(first: int, second: str, third: float) -> None: ...
+
+# Possibly omitted arg, but we now only issue one error
+convert3("hello", 3.15)  # E: Missing positional argument "first" in call to "convert3"
+
+# Other cases
+convert3("hello")  # E: Missing positional arguments "second", "third" in call to "convert3" \
+                   # E: Argument 1 to "convert3" has incompatible type "str"; expected "int"
+
+convert3(3.15, "hello")  # E: Missing positional argument "third" in call to "convert3" \
+                         # E: Argument 1 to "convert3" has incompatible type "float"; expected "int"
+
+def convert4(first: int, second: str, third: float, fourth: bytes) -> None: ...
+
+# Possibly omitted arg, but we now only issue one error
+convert4("hello", 3.15, b'')  # E: Missing positional argument "first" in call to "convert4"
+
+# Other cases
+convert4("hello")  # E: Missing positional arguments "second", "third", "fourth" in call to "convert4" \
+                   # E: Argument 1 to "convert4" has incompatible type "str"; expected "int"
+
+convert4("hello", 3.15)  # E: Missing positional arguments "third", "fourth" in call to "convert4" \
+                         # E: Argument 1 to "convert4" has incompatible type "str"; expected "int" \
+                         # E: Argument 2 to "convert4" has incompatible type "float"; expected "str"
+
+convert4(b'', "hello", 3.15)  # E: Missing positional argument "fourth" in call to "convert4" \
+                              # E: Argument 1 to "convert4" has incompatible type "bytes"; expected "int"
+[builtins fixtures/primitives.pyi]