mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'python-fixes'
Conflicts: python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
This commit is contained in:
@@ -328,6 +328,7 @@ INSP.empty.docstring=Empty docstring
|
||||
|
||||
# PyStatementEffectInspection
|
||||
INSP.NAME.statement.effect=Statement has no effect
|
||||
INSP.NAME.statement.message=Statement seems to have no effect
|
||||
|
||||
# PySimplifyBooleanCheckInspection
|
||||
INSP.NAME.check.can.be.simplified=Boolean variable check can be simplified
|
||||
|
||||
@@ -97,7 +97,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
return describeDecorators(cls, LSame2, ", ", LSame1).add(describeClass(cls, LSame2, false, false)).toString() + "\n" + summary;
|
||||
}
|
||||
else if (element instanceof PyTargetExpression || element instanceof PyNamedParameter) {
|
||||
return describeExpression((PyExpression)element, originalElement);
|
||||
return describeExpression((PyExpression)element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String describeExpression(PyExpression expr, PsiElement originalElement) {
|
||||
private static String describeExpression(PyExpression expr) {
|
||||
final String name = expr.getName();
|
||||
if (name != null) {
|
||||
StringBuilder result = new StringBuilder((expr instanceof PyNamedParameter) ? "parameter" : "variable");
|
||||
@@ -138,9 +138,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
result.append(String.format(" \"%s\"", function.getName()));
|
||||
}
|
||||
}
|
||||
if (originalElement instanceof PyExpression && originalElement.isValid()) {
|
||||
result.append("\n").append(describeExpressionType((PyExpression)originalElement));
|
||||
}
|
||||
result.append("\n").append(describeExpressionType(expr));
|
||||
return result.toString();
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -62,10 +62,15 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (checkStringLiteral(expression))
|
||||
if (checkStringLiteral(expression)) {
|
||||
return;
|
||||
registerProblem(expression, "Statement seems to have no effect",
|
||||
new StatementEffectIntroduceVariableQuickFix());
|
||||
}
|
||||
if (expression instanceof PyReferenceExpression && ((PyReferenceExpression)expression).getQualifier() == null) {
|
||||
registerProblem(expression, PyBundle.message("INSP.NAME.statement.message"));
|
||||
}
|
||||
else {
|
||||
registerProblem(expression, PyBundle.message("INSP.NAME.statement.message"), new StatementEffectIntroduceVariableQuickFix());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkStringLiteral(PyExpression expression) {
|
||||
|
||||
@@ -266,8 +266,7 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
|
||||
if (paramList != null && paramList.getParent() instanceof PyFunction) {
|
||||
final PyFunction func = (PyFunction) paramList.getParent();
|
||||
containingClass = func.getContainingClass();
|
||||
final String funcName = func.getName();
|
||||
if (PyNames.INIT.equals(funcName) && containingClass != null) {
|
||||
if (PyNames.INIT.equals(func.getName()) && containingClass != null) {
|
||||
if (!namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) {
|
||||
mayBeField = true;
|
||||
}
|
||||
@@ -276,9 +275,6 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
|
||||
continue;
|
||||
}
|
||||
if (func.asMethod() != null) {
|
||||
if (funcName != null && isSpecialName(funcName) && !PyNames.INIT.equals(funcName) && !PyNames.NEW.equals(funcName)) {
|
||||
continue;
|
||||
}
|
||||
Boolean isEmpty = emptyFunctions.get(func);
|
||||
if (isEmpty == null) {
|
||||
isEmpty = isEmptyFunction(func);
|
||||
@@ -313,11 +309,6 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSpecialName(@NotNull String name) {
|
||||
final String dunder = "__";
|
||||
return name.startsWith(dunder) && name.endsWith(dunder) && name.length() > (dunder.length() * 2);
|
||||
}
|
||||
|
||||
private boolean isRangeIteration(PyForStatement forStatement) {
|
||||
final PyExpression source = forStatement.getForPart().getSource();
|
||||
if (!(source instanceof PyCallExpression)) {
|
||||
|
||||
@@ -178,9 +178,16 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
final PyType exprType = expression.getType(context);
|
||||
if (exprType instanceof PyClassType) {
|
||||
final PyClass cls = ((PyClassType)exprType).getPyClass();
|
||||
final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
|
||||
if (enter != null) {
|
||||
return enter.getReturnType(context, null);
|
||||
if (cls != null) {
|
||||
final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
|
||||
if (enter != null) {
|
||||
final PyType enterType = enter.getReturnType(context, null);
|
||||
if (enterType != null) {
|
||||
return enterType;
|
||||
}
|
||||
// Guess the return type of __enter__
|
||||
return PyUnionType.createWeakType(exprType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +282,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
type = ((PyCollectionType)sourceType).getElementType(context);
|
||||
if (sourceType instanceof PyClassType) {
|
||||
final PyClass cls = ((PyClassType)sourceType).getPyClass();
|
||||
if (type instanceof PyTupleType && PyABCUtil.isSubclass(cls, PyNames.MAPPING)) {
|
||||
if (cls != null && type instanceof PyTupleType && PyABCUtil.isSubclass(cls, PyNames.MAPPING)) {
|
||||
final PyTupleType mappingType = (PyTupleType)type;
|
||||
if (mappingType.getElementCount() == 2) {
|
||||
return mappingType.getElementType(0);
|
||||
@@ -285,30 +292,32 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
}
|
||||
else if (sourceType instanceof PyClassType) {
|
||||
final PyClass pyClass = ((PyClassType)sourceType).getPyClass();
|
||||
for (PyTypeProvider provider: Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
|
||||
final PyType iterType = provider.getIterationType(pyClass);
|
||||
if (iterType != null) {
|
||||
type = iterType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (PyABCUtil.isSubclass(pyClass, PyNames.ITERATOR)) {
|
||||
final PyFunction iter = pyClass.findMethodByName(PyNames.ITER, true);
|
||||
PyType iterMethodType = null;
|
||||
if (iter != null) {
|
||||
iterMethodType = getContextSensitiveType(iter, context, source);
|
||||
}
|
||||
if (iterMethodType instanceof PyCollectionType) {
|
||||
final PyCollectionType collectionType = (PyCollectionType)iterMethodType;
|
||||
type = collectionType.getElementType(context);
|
||||
}
|
||||
if (type == null) {
|
||||
PyFunction next = pyClass.findMethodByName(PyNames.NEXT, true);
|
||||
if (next == null) {
|
||||
next = pyClass.findMethodByName(PyNames.DUNDER_NEXT, true);
|
||||
if (pyClass != null) {
|
||||
for (PyTypeProvider provider: Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
|
||||
final PyType iterType = provider.getIterationType(pyClass);
|
||||
if (iterType != null) {
|
||||
type = iterType;
|
||||
break;
|
||||
}
|
||||
if (next != null) {
|
||||
type = getContextSensitiveType(next, context, source);
|
||||
}
|
||||
if (PyABCUtil.isSubclass(pyClass, PyNames.ITERATOR)) {
|
||||
final PyFunction iter = pyClass.findMethodByName(PyNames.ITER, true);
|
||||
PyType iterMethodType = null;
|
||||
if (iter != null) {
|
||||
iterMethodType = getContextSensitiveType(iter, context, source);
|
||||
}
|
||||
if (iterMethodType instanceof PyCollectionType) {
|
||||
final PyCollectionType collectionType = (PyCollectionType)iterMethodType;
|
||||
type = collectionType.getElementType(context);
|
||||
}
|
||||
if (type == null) {
|
||||
PyFunction next = pyClass.findMethodByName(PyNames.NEXT, true);
|
||||
if (next == null) {
|
||||
next = pyClass.findMethodByName(PyNames.DUNDER_NEXT, true);
|
||||
}
|
||||
if (next != null) {
|
||||
type = getContextSensitiveType(next, context, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,7 +446,10 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
return stub.getInitializer();
|
||||
}
|
||||
else if (initializerType == PyTargetExpressionStub.InitializerType.Custom) {
|
||||
return stub.getCustomStub(CustomTargetExpressionStub.class).getCalleeName();
|
||||
final CustomTargetExpressionStub customStub = stub.getCustomStub(CustomTargetExpressionStub.class);
|
||||
if (customStub != null) {
|
||||
return customStub.getCalleeName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
|
||||
@NotNull private final PyFile myModule;
|
||||
@Nullable private final PyImportedModule myImportedModule;
|
||||
|
||||
protected static ImmutableSet<String> ourPossibleFields = ImmutableSet.of("__name__", "__file__", "__path__", "__doc__", "__dict__");
|
||||
protected static ImmutableSet<String> ourPossibleFields = ImmutableSet.of("__name__", "__file__", "__path__", "__doc__", "__dict__", "__package__");
|
||||
|
||||
public PyModuleType(@NotNull PyFile source) {
|
||||
this(source, null);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__package__ #pass
|
||||
@@ -286,9 +286,3 @@ class C:
|
||||
# PY-7126
|
||||
def test_unused_empty_function(<weak_warning descr="Parameter 'x' value is not used">x</weak_warning>):
|
||||
pass
|
||||
|
||||
|
||||
# PY-7178
|
||||
class C(object):
|
||||
def __getattr__(self, name): # pass
|
||||
return 42
|
||||
|
||||
+5
@@ -165,6 +165,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-7043
|
||||
public void testDunderPackage() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
|
||||
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
|
||||
|
||||
Reference in New Issue
Block a user