PY-19491 Fixed: *args, **kwargs should not trigger PyUnusedLocal inspection our should be different inspection

Don't mark *args and **kwargs params in overridden __init__ as possibly unused while collecting write instructions
This commit is contained in:
Semyon Proshev
2016-10-27 20:50:51 +03:00
parent 06d9cf6e3a
commit 5d0cb4f64d
3 changed files with 40 additions and 8 deletions
@@ -224,10 +224,10 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
}
}
private void analyzeReadsInScope(@NotNull String name,
private void analyzeReadsInScope(@NotNull String name,
@NotNull ScopeOwner owner,
@NotNull Instruction[] instructions,
int startInstruction,
int startInstruction,
@Nullable PsiElement scopeAnchor) {
// Check if the element is declared out of scope, mark all out of scope write accesses as used
if (scopeAnchor != null) {
@@ -343,10 +343,8 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
if (paramList != null && paramList.getParent() instanceof PyFunction) {
final PyFunction func = (PyFunction) paramList.getParent();
containingClass = func.getContainingClass();
if (PyNames.INIT.equals(func.getName()) && containingClass != null) {
if (!namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) {
mayBeField = true;
}
if (PyNames.INIT.equals(func.getName()) && containingClass != null && !namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) {
mayBeField = true;
}
else if (ignoreUnusedParameters(func, functionsWithInheritors)) {
continue;
@@ -412,7 +410,7 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
if (functionsWithInheritors.contains(func)) {
return true;
}
if (PySuperMethodsSearch.search(func, myTypeEvalContext).findFirst() != null ||
if (!PyNames.INIT.equals(func.getName()) && PySuperMethodsSearch.search(func, myTypeEvalContext).findFirst() != null ||
PyOverridingMethodsSearch.search(func, true).findFirst() != null) {
functionsWithInheritors.add(func);
return true;
@@ -0,0 +1,30 @@
# PY-19491
class A(object):
def __init__(self, <weak_warning descr="Parameter 'args' value is not used">*args</weak_warning>, <weak_warning descr="Parameter 'kwargs' value is not used">**kwargs</weak_warning>):
self.foo = "foo"
# PY-19491
class B(object):
def __init__(self, <weak_warning descr="Parameter 'args' value is not used">*args</weak_warning>, <weak_warning descr="Parameter 'kwargs' value is not used">**kwargs</weak_warning>):
self.foo = "foo"
# PY-19491
class C(B):
pass
# PY-19491
class D(object):
def __init__(self, *args, **kwargs):
self.foo = "foo"
# PY-19491
class E(D):
def __init__(self, *args, **kwargs):
super(E, self).__init__(*args, **kwargs)
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -114,6 +114,10 @@ public class PythonInspectionsTest extends PyTestCase {
doHighlightingTest(PyUnusedLocalInspection.class, LanguageLevel.PYTHON34);
}
public void testPyUnusedParameterInspection() {
doHighlightingTest(PyUnusedLocalInspection.class);
}
// PY-20805
public void testUnusedLocalFStringReferences() {
doHighlightingTest(PyUnusedLocalInspection.class, LanguageLevel.PYTHON36);