Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12287,24 +12287,39 @@ export function createTypeEvaluator(
skipUnknownArgCheck = true;
}

const paramDetails = getParamListDetails(type);
matchResults.argParams.forEach((argParam) => {
const a = argParam.argument;
if (
a.argCategory === ArgCategory.Simple &&
!a.name &&
a.valueExpression &&
a.valueExpression.nodeType === ParseNodeType.Name &&
argParam.paramCategory === ParamCategory.Simple &&
!argParam.mapsToVarArgList &&
argParam.paramName &&
!argParam.isParamNameSynthesized
) {
const passedName = (a.valueExpression as NameNode).d.value;
// Skip positional-only parameters
const paramIndex = paramDetails.params.findIndex((p) => p.param.name === argParam.paramName);
if (paramIndex >= 0 && paramIndex < paramDetails.positionOnlyParamCount) {
return;
}

const paramName = argParam.paramName;
if (passedName !== paramName) {
if (a.valueExpression.nodeType === ParseNodeType.Name) {
const passedName = (a.valueExpression as NameNode).d.value;
if (passedName !== paramName) {
addDiagnostic(
DiagnosticRule.reportPositionalArgumentNameMismatch,
`Argument "${passedName}" does not match parameter name "${paramName}" for function "${type.shared.name}"; pass as a keyword argument to avoid confusion`,
a.valueExpression
);
}
} else {
// Non-name expression passed positionally
addDiagnostic(
DiagnosticRule.reportPositionalArgumentNameMismatch,
`Positional argument "${passedName}" does not match parameter name "${paramName}"; pass as a keyword argument to avoid confusion`,
`Positional argument for parameter "${paramName}" in function "${type.shared.name}"; pass as a keyword argument to avoid confusion`,
a.valueExpression
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ test('it reports an error', () => {
line: 11,
code: DiagnosticRule.reportPositionalArgumentNameMismatch,
},
{
line: 25,
code: DiagnosticRule.reportPositionalArgumentNameMismatch,
},
{
line: 32,
code: DiagnosticRule.reportPositionalArgumentNameMismatch,
},
{
line: 33,
code: DiagnosticRule.reportPositionalArgumentNameMismatch,
},
],
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,15 @@ def foo(
height, # okay, matches
width=length, # okay, using keyword
)

foo(
1, # should display a warning, positional argument used
width=2, # okay, using keyword
)

len([]) # okay, built-in function with no keyword arguments

pow(
2, # should display a warning, positional argument used, built-in function
3, # should display a warning, positional argument used, built-in function
)
Loading