Skip to content

Mark varargs as pos-only #19022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 5, 2025
Merged

Conversation

A5rocks
Copy link
Collaborator

@A5rocks A5rocks commented May 3, 2025

Fixes #19019. This PR marks *args as positional only, as you cannot pass the argument by its name.

@asottile
Copy link
Contributor

asottile commented May 3, 2025

ah neat -- I also tried to fix this but in a different way (with a lot less churn in the error messages maybe?)

commit b451101791055aa88b26b8be417e2cce3d912630
Author: anthony sottile <asottile@umich.edu>
Date:   Sat May 3 12:19:14 2025 -0400

    produce error when passing a named argument to a vararg

diff --git a/mypy/argmap.py b/mypy/argmap.py
index a1c4ef72e..28fad1f09 100644
--- a/mypy/argmap.py
+++ b/mypy/argmap.py
@@ -78,7 +78,7 @@ def map_actuals_to_formals(
         elif actual_kind.is_named():
             assert actual_names is not None, "Internal error: named kinds without names given"
             name = actual_names[ai]
-            if name in formal_names:
+            if name in formal_names and formal_kinds[formal_names.index(name)] != nodes.ARG_STAR:
                 formal_to_actual[formal_names.index(name)].append(ai)
             elif nodes.ARG_STAR2 in formal_kinds:
                 formal_to_actual[formal_kinds.index(nodes.ARG_STAR2)].append(ai)
diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test
index 65bbd8456..ec6d4a19c 100644
--- a/test-data/unit/check-varargs.test
+++ b/test-data/unit/check-varargs.test
@@ -145,6 +145,11 @@ f(*it1, 1, *it2, 2)  # E: Argument 3 to "f" has incompatible type "*Tuple[str]";
 f(*it1, '') # E: Argument 2 to "f" has incompatible type "str"; expected "int"
 [builtins fixtures/for.pyi]
 
+[case testCallVarArgsWithMatchingNamedArgument]
+def f(*x: int) -> None: pass  # N: "f" defined here
+f(x=1)  # E: Unexpected keyword argument "x" for "f"
+[builtins fixtures/for.pyi]
+
 
 -- Calling varargs function + type inference
 -- -----------------------------------------
@A5rocks
Copy link
Collaborator Author

A5rocks commented May 3, 2025

ah neat -- I also tried to fix this but in a different way (with a lot less churn in the error messages maybe?)

Yeah that's also an approach, I figured solving this at a lower level (i.e. parsing) would be better because it would solve more related issues like, well I can't think of any so maybe the error churn isn't worth it.

(sorry I included an issue that diff would fix)

@asottile
Copy link
Contributor

asottile commented May 3, 2025

I like your approach better -- though it would be nice if there were symmetry in the error message (*Any, **Any) in a few places but shrugs!

@sterliakov
Copy link
Collaborator

sterliakov commented May 3, 2025

Looks great! To remove the significant errors change, perhaps just handle that in formatting logic (mypy.messages.format_callable_args)? IMO showing the vararg name is helpful for humans, *Any is less clear than *constraints: Any. That part shouldn't be hot, we only format callables in error messages, so another case shouldn't harm.

The bug itself is rather scary, I'm surprised we didn't have any such snippet in the test suite. Please try to get this into the next release!

This comment has been minimized.

@A5rocks
Copy link
Collaborator Author

A5rocks commented May 3, 2025

To remove the significant errors change, perhaps just handle that in formatting logic

Well this change completely removes any knowledge mypy has of the name, so.... to avoid this, I could use @asottile's approach.

it would be nice if there were symmetry in the error message (*Any, **Any) in a few places but shrugs!

I agree. (plus kwarg name doesn't matter either)

Given that this changes stubgen, it may make sense to have a more
targeted fix.

This comment has been minimized.

Copy link
Collaborator

@sterliakov sterliakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG! This may break typing tests for someone, but should be trivial to fix.

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the error message regression here isn't ideal. I'd vote we do asottile's approach or just hack the formatting to assume the name is args

A5rocks and others added 2 commits May 5, 2025 11:16
Co-authored-by: Anthony Sottile <asottile@umich.edu>
Copy link
Contributor

github-actions bot commented May 5, 2025

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@hauntsaninja hauntsaninja merged commit db752bb into python:master May 5, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants