mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix false positive in PyStringFormatInspection for keyword substitution in % string with dictionary argument #PY-18725
This commit is contained in:
@@ -277,39 +277,49 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int referenceKeyNumber = 0;
|
||||
for (PyKeyValueExpression expression : expressions) {
|
||||
final PyExpression key = expression.getKey();
|
||||
final PyExpression value = expression.getValue();
|
||||
if (key instanceof PyStringLiteralExpression) {
|
||||
final String name = ((PyStringLiteralExpression)key).getStringValue();
|
||||
if (myUsedMappingKeys.get(name) != null) {
|
||||
myUsedMappingKeys.put(name, true);
|
||||
final PyExpression value = expression.getValue();
|
||||
if (value != null) {
|
||||
checkExpressionType(value, myFormatSpec.get(name), problemTarget);
|
||||
}
|
||||
}
|
||||
resolveMappingKey(problemTarget, (PyStringLiteralExpression)key, value);
|
||||
}
|
||||
else if (key instanceof PyReferenceExpression) {
|
||||
referenceKeyNumber ++;
|
||||
}
|
||||
}
|
||||
for (Map.Entry<PyExpression, PyExpression> expression : additionalExpressions.entrySet()) {
|
||||
final PyExpression key = expression.getKey();
|
||||
final PyExpression value = expression.getValue();
|
||||
if (key instanceof PyStringLiteralExpression) {
|
||||
final String name = ((PyStringLiteralExpression)key).getStringValue();
|
||||
if (myUsedMappingKeys.get(name) != null) {
|
||||
myUsedMappingKeys.put(name, true);
|
||||
final PyExpression value = expression.getValue();
|
||||
if (value != null) {
|
||||
checkExpressionType(value, myFormatSpec.get(name), problemTarget);
|
||||
}
|
||||
resolveMappingKey(problemTarget, (PyStringLiteralExpression)key, value);
|
||||
}
|
||||
else if (key instanceof PyReferenceExpression) {
|
||||
referenceKeyNumber ++;
|
||||
}
|
||||
}
|
||||
|
||||
int unresolved = 0;
|
||||
for (String key : myUsedMappingKeys.keySet()) {
|
||||
if (!myUsedMappingKeys.get(key).booleanValue()) {
|
||||
unresolved++;
|
||||
if (unresolved > referenceKeyNumber) {
|
||||
registerProblem(problemTarget, PyBundle.message("INSP.key.$0.has.no.arg", key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String key : myUsedMappingKeys.keySet()) {
|
||||
if (!myUsedMappingKeys.get(key).booleanValue()) {
|
||||
registerProblem(problemTarget, PyBundle.message("INSP.key.$0.has.no.arg", key));
|
||||
break;
|
||||
return (expressions.length + additionalExpressions.size());
|
||||
}
|
||||
|
||||
private void resolveMappingKey(PsiElement problemTarget, PyStringLiteralExpression key, PyExpression value) {
|
||||
final String name = key.getStringValue();
|
||||
if (myUsedMappingKeys.get(name) != null) {
|
||||
myUsedMappingKeys.put(name, true);
|
||||
if (value != null) {
|
||||
checkExpressionType(value, myFormatSpec.get(name), problemTarget);
|
||||
}
|
||||
}
|
||||
return (expressions.length + additionalExpressions.size());
|
||||
}
|
||||
|
||||
private void registerProblem(@NotNull PsiElement problemTarget, @NotNull final String message, @NotNull LocalQuickFix quickFix) {
|
||||
|
||||
@@ -10,3 +10,10 @@ my_dict['tmp'] = 'classes %(claz)s' % <warning descr="Key 'claz' has no followin
|
||||
|
||||
|
||||
"%s" % {"a": 1}
|
||||
|
||||
f = "fst"
|
||||
s = "snd"
|
||||
"first is %(fst)s, second is %(snd)s" % {f: 1, s: 2}
|
||||
|
||||
snd = "snd"
|
||||
"%(f)s %(snd)s" % {"f": 2, snd: 2}
|
||||
Reference in New Issue
Block a user