mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22769 Fixed: Wrong inspection "Expected type 'bytes', got 'str' instead" for replacement function of os.path.abspath object
PY-22512 Fixed: False positive: expected Optional[bytes] got str for os.path.realpath(...).rstrip('_')
PY-22475 Fixed: Switch multi-parameters handling to multi-resolved functions API
Use PyCallExpression.multiResolveRatedCalleeFunction in PyTypeChecker and drop PyUtil.getOverloadedParametersSet
This commit is contained in:
committed by
Semyon Proshev
parent
96dd05d4d0
commit
77ee34ea5c
@@ -181,7 +181,7 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCallSite(@Nullable PyCallSiteExpression callSite) {
|
||||
private void checkCallSite(@NotNull PyCallSiteExpression callSite) {
|
||||
final List<PyTypeChecker.AnalyzeCallResults> resultsSet = PyTypeChecker.analyzeCallSite(callSite, myTypeEvalContext);
|
||||
final List<Map<PyExpression, Pair<String, ProblemHighlightType>>> problemsSet =
|
||||
new ArrayList<>();
|
||||
|
||||
@@ -1522,64 +1522,6 @@ public class PyUtil {
|
||||
return element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<List<PyParameter>> getOverloadedParametersSet(@NotNull PyCallable callable, @NotNull TypeEvalContext context) {
|
||||
final List<List<PyParameter>> parametersSet = getOverloadedParametersSet(context.getType(callable), context);
|
||||
return parametersSet != null ? parametersSet : Collections.singletonList(Arrays.asList(callable.getParameterList().getParameters()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<PyParameter> getParametersOfCallableType(@NotNull PyCallableType type, @NotNull TypeEvalContext context) {
|
||||
final List<PyCallableParameter> callableTypeParameters = type.getParameters(context);
|
||||
if (callableTypeParameters != null) {
|
||||
boolean allParametersDefined = true;
|
||||
final List<PyParameter> parameters = new ArrayList<>();
|
||||
for (PyCallableParameter callableParameter : callableTypeParameters) {
|
||||
final PyParameter parameter = callableParameter.getParameter();
|
||||
if (parameter == null) {
|
||||
allParametersDefined = false;
|
||||
break;
|
||||
}
|
||||
parameters.add(parameter);
|
||||
}
|
||||
if (allParametersDefined) {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<List<PyParameter>> getOverloadedParametersSet(@Nullable PyType type, @NotNull TypeEvalContext context) {
|
||||
if (type instanceof PyUnionType) {
|
||||
type = ((PyUnionType)type).excludeNull(context);
|
||||
}
|
||||
|
||||
if (type instanceof PyCallableType) {
|
||||
final List<PyParameter> results = getParametersOfCallableType((PyCallableType)type, context);
|
||||
if (results != null) {
|
||||
return Collections.singletonList(results);
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyUnionType) {
|
||||
final List<List<PyParameter>> results = new ArrayList<>();
|
||||
final Collection<PyType> members = ((PyUnionType)type).getMembers();
|
||||
for (PyType member : members) {
|
||||
if (member instanceof PyCallableType) {
|
||||
final List<PyParameter> parameters = getParametersOfCallableType((PyCallableType)member, context);
|
||||
if (parameters != null) {
|
||||
results.add(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!results.isEmpty()) {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PyParameter> getParameters(@NotNull PyCallable callable, @NotNull TypeEvalContext context) {
|
||||
return Optional
|
||||
|
||||
@@ -615,28 +615,22 @@ public class PyTypeChecker {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<AnalyzeCallResults> analyzeCallSite(@Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
|
||||
if (callSite != null) {
|
||||
final List<AnalyzeCallResults> results = new ArrayList<>();
|
||||
for (PyCallable callable : resolveCallee(callSite, context)) {
|
||||
final PyExpression receiver = getReceiver(callSite, callable);
|
||||
for (List<PyParameter> parameters : PyUtil.getOverloadedParametersSet(callable, context)) {
|
||||
final Map<PyExpression, PyNamedParameter> mapping = PyCallExpressionHelper.mapArguments(callSite, callable, parameters, context);
|
||||
results.add(new AnalyzeCallResults(callable, receiver, mapping));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
public static List<AnalyzeCallResults> analyzeCallSite(@NotNull PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
|
||||
final List<AnalyzeCallResults> results = new ArrayList<>();
|
||||
for (PyCallable callable : multiResolveCallee(callSite, context)) {
|
||||
final PyExpression receiver = getReceiver(callSite, callable);
|
||||
final Map<PyExpression, PyNamedParameter> mapping = PyCallExpressionHelper.mapArguments(callSite, callable, context);
|
||||
results.add(new AnalyzeCallResults(callable, receiver, mapping));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
return results;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PyCallable> resolveCallee(@NotNull PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
|
||||
private static List<PyCallable> multiResolveCallee(@NotNull PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
|
||||
if (callSite instanceof PyCallExpression) {
|
||||
final PyCallExpression callExpr = (PyCallExpression)callSite;
|
||||
final PyCallExpression.PyMarkedCallee callee = callExpr.resolveCallee(resolveContext);
|
||||
return callee != null ? Collections.singletonList(callee.getCallable()) : Collections.emptyList();
|
||||
final List<PyCallExpression.PyRatedCallee> ratedCallees = ((PyCallExpression)callSite).multiResolveRatedCalleeFunction(resolveContext);
|
||||
return ContainerUtil.map(PyUtil.filterTopPriorityResults(ratedCallees), PyCallExpression.PyRatedCallee::getElement);
|
||||
}
|
||||
else if (callSite instanceof PySubscriptionExpression || callSite instanceof PyBinaryExpression) {
|
||||
final List<PyCallable> results = new ArrayList<>();
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
from typing import Union
|
||||
|
||||
|
||||
def foo(path: Union[bytes, str]) -> None:
|
||||
path.replace("/", "\\")
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -198,7 +198,7 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase {
|
||||
public void testBuiltinInputPy3() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
// PY-200057
|
||||
public void testClassObjectType() {
|
||||
doTest();
|
||||
@@ -218,4 +218,9 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase {
|
||||
public void testOptionalOfBoundTypeVarInWarnings() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-22769
|
||||
public void testReplaceCalledOnUnionOfStrAndBytesWithStrArguments() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user