mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-19130 Fixed: Type inference: decorators behaving oddly
If class is decorated, PyArgumentListInspection doesn't check its constructor arguments
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -21,6 +21,8 @@ import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
@@ -35,7 +37,9 @@ import com.jetbrains.python.psi.types.PyTypeChecker;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -115,9 +119,13 @@ public class PyArgumentListInspection extends PyInspection {
|
||||
final PyCallExpression.PyMarkedCallee callee = mapping.getMarkedCallee();
|
||||
if (callee != null) {
|
||||
final PyCallable callable = callee.getCallable();
|
||||
// Decorate functions may have different parameter lists. We don't match arguments with parameters of decorators yet
|
||||
if (callable instanceof PyFunction && PyUtil.hasCustomDecorators((PyFunction)callable)) {
|
||||
return;
|
||||
if (callable instanceof PyFunction) {
|
||||
final PyFunction function = (PyFunction)callable;
|
||||
|
||||
// Decorate functions may have different parameter lists. We don't match arguments with parameters of decorators yet
|
||||
if (PyUtil.hasCustomDecorators(function) || decoratedClassInitCall(callExpr.getCallee(), function)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
highlightParametersMismatch(node, holder, mapping);
|
||||
@@ -128,6 +136,19 @@ public class PyArgumentListInspection extends PyInspection {
|
||||
inspectPyArgumentList(node, holder, context, 0);
|
||||
}
|
||||
|
||||
private static boolean decoratedClassInitCall(@Nullable PyExpression callee, @NotNull PyFunction function) {
|
||||
if (callee instanceof PyReferenceExpression && PyUtil.isInit(function)) {
|
||||
final PsiPolyVariantReference classReference = ((PyReferenceExpression)callee).getReference();
|
||||
|
||||
return Arrays
|
||||
.stream(classReference.multiResolve(false))
|
||||
.map(ResolveResult::getElement)
|
||||
.anyMatch(element -> element instanceof PyClass && PyUtil.hasCustomDecorators((PyClass)element));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void highlightStarArgumentTypeMismatch(PyArgumentList node, ProblemsHolder holder, TypeEvalContext context) {
|
||||
for (PyExpression arg : node.getArguments()) {
|
||||
if (arg instanceof PyStarArgument) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import attr
|
||||
|
||||
class A(object):
|
||||
a = attr.ib()
|
||||
|
||||
A = attr.s(A)
|
||||
|
||||
A(a="test")
|
||||
@@ -0,0 +1,7 @@
|
||||
import attr
|
||||
|
||||
@attr.s
|
||||
class A(object):
|
||||
a = attr.ib()
|
||||
|
||||
A(a="test")
|
||||
@@ -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.
|
||||
@@ -44,6 +44,16 @@ public class PyArgumentListInspectionTest extends PyTestCase {
|
||||
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null);
|
||||
}
|
||||
}
|
||||
|
||||
// PY-19130
|
||||
public void testClassDecoratedThroughDecorator() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-19130
|
||||
public void testClassDecoratedThroughCall() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTupleVsLiteralList() {
|
||||
doTest();
|
||||
|
||||
Reference in New Issue
Block a user