Fix false positive in PyStringFormatInspection for keyword substitution in % string with dictionary argument #PY-18725

This commit is contained in:
Valentina Kiryushkina
2016-04-07 20:48:17 +03:00
parent 6f3a0596f4
commit cdc22c48e3
2 changed files with 37 additions and 20 deletions
@@ -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}