mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-CR-68177 PY-36610 Parameter info doesn't work in Python Console
GitOrigin-RevId: f60d65180234eca86488aba5911b033333e04642
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0b64e38bc
commit
31f33fd175
@@ -46,7 +46,7 @@ def get_description(obj):
|
||||
|
||||
if isinstance(obj, type) or type(obj).__name__ == 'classobj':
|
||||
fob = getattr(obj, '__init__', lambda: None)
|
||||
if not isinstance(fob, (types.FunctionType, types.MethodType)):
|
||||
if not callable(fob):
|
||||
fob = obj
|
||||
elif is_bound_method(ob_call):
|
||||
fob = ob_call
|
||||
@@ -54,9 +54,8 @@ def get_description(obj):
|
||||
fob = obj
|
||||
|
||||
argspec = ""
|
||||
fn_name = None
|
||||
fn_class = None
|
||||
if isinstance(fob, (types.FunctionType, types.MethodType)):
|
||||
if callable(fob):
|
||||
spec_info = inspect.getfullargspec(fob) if IS_PY3K else inspect.getargspec(fob)
|
||||
argspec = inspect.formatargspec(*spec_info)
|
||||
fn_name = getattr(fob, '__name__', None)
|
||||
|
||||
+17
-3
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.completion.CompletionUtilCoreImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -12,6 +13,7 @@ import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonRuntimeService;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
|
||||
@@ -104,8 +106,7 @@ public final class PyCallExpressionHelper {
|
||||
* please obtain its result via {@link TypeEvalContext#getType} with {@code call.getCallee()} as an argument.
|
||||
*/
|
||||
static @Nullable PyType getCalleeType(@NotNull PyCallExpression call,
|
||||
@NotNull PyResolveContext resolveContext,
|
||||
@SuppressWarnings("unused") @NotNull TypeEvalContext.Key key) {
|
||||
@NotNull PyResolveContext resolveContext) {
|
||||
final List<PyType> callableTypes = new ArrayList<>();
|
||||
final TypeEvalContext context = resolveContext.getTypeEvalContext();
|
||||
|
||||
@@ -189,7 +190,10 @@ public final class PyCallExpressionHelper {
|
||||
return PyUtil.getParameterizedCachedValue(
|
||||
call,
|
||||
resolveContext,
|
||||
it -> ContainerUtil.concat(getExplicitResolveResults(call, it), getImplicitResolveResults(call, it))
|
||||
it -> ContainerUtil.concat(
|
||||
getExplicitResolveResults(call, it),
|
||||
getImplicitResolveResults(call, it),
|
||||
getRemoteResolveResults(call, it))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -277,6 +281,16 @@ public final class PyCallExpressionHelper {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<@NotNull PyCallableType> getRemoteResolveResults(@NotNull PyCallExpression call,
|
||||
@NotNull PyResolveContext resolveContext) {
|
||||
if (!resolveContext.allowRemote()) return Collections.emptyList();
|
||||
PsiFile file = call.getContainingFile();
|
||||
if (file == null || !PythonRuntimeService.getInstance().isInPydevConsole(file)) return Collections.emptyList();
|
||||
PyType calleeType = getCalleeType(call, resolveContext);
|
||||
return PyTypeUtil.toStream(calleeType).select(PyCallableType.class).toList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<@NotNull PyCallableType> selectCallableTypes(@NotNull List<PsiElement> resolveResults,
|
||||
@NotNull TypeEvalContext context) {
|
||||
|
||||
+1
-1
@@ -249,7 +249,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
private PyType getCallableType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
|
||||
PyCallExpression callExpression = PyCallExpressionNavigator.getPyCallExpressionByCallee(this);
|
||||
if (callExpression != null) {
|
||||
return getCalleeType(callExpression, PyResolveContext.defaultContext().withTypeEvalContext(context), key);
|
||||
return getCalleeType(callExpression, PyResolveContext.defaultContext().withTypeEvalContext(context));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ public abstract class PydevConsoleCommunication extends AbstractConsoleCommunica
|
||||
// add temporary value to avoid repeated requests for the same expression
|
||||
myPrevNameToDescription = Pair.create(text, "");
|
||||
}
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread() && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
throw new PyDebuggerException("Documentation in Python Console shouldn't be called from Dispatch Thread!");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList;
|
||||
import com.jetbrains.env.PyExecutionFixtureTestTask;
|
||||
@@ -438,6 +439,10 @@ public class PyConsoleTask extends PyExecutionFixtureTestTask {
|
||||
});
|
||||
}
|
||||
|
||||
public PsiFile getConsoleFile() {
|
||||
return myConsoleView.getFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.jetbrains.env.debug;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
|
||||
import com.jetbrains.env.PyEnvTestCase;
|
||||
import com.jetbrains.python.console.pydev.PydevCompletionVariant;
|
||||
@@ -20,6 +21,7 @@ import java.util.function.Predicate;
|
||||
import static com.intellij.testFramework.UsefulTestCase.assertContainsElements;
|
||||
import static com.jetbrains.env.debug.PyBaseDebuggerTask.findCompletionVariantByName;
|
||||
import static com.jetbrains.env.debug.PyBaseDebuggerTask.findDebugValueByName;
|
||||
import static com.jetbrains.python.PyParameterInfoTest.checkParameters;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PythonConsoleTest extends PyEnvTestCase {
|
||||
@@ -284,4 +286,20 @@ public class PythonConsoleTest extends PyEnvTestCase {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameterInfo() {
|
||||
runPythonTest(new PyConsoleTask("/debug") {
|
||||
@Override
|
||||
public void testing() throws Exception {
|
||||
exec("from os import getenv");
|
||||
exec("print(\"Hi\")");
|
||||
waitForOutput("Hi");
|
||||
addTextToEditor("getenv()");
|
||||
ApplicationManager.getApplication().invokeAndWait(() -> {
|
||||
checkParameters(7, getConsoleFile(), "key, default=None", new String[]{"key, "});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1150,16 +1150,22 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collector feignCtrlP(int offset) {
|
||||
return feignCtrlP(offset, myFixture.getFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Imitates pressing of Ctrl+P; fails if results are not as expected.
|
||||
*
|
||||
* @param offset offset of 'cursor' where Ctrl+P is pressed.
|
||||
* @return a {@link Collector} with collected hint info.
|
||||
*/
|
||||
@NotNull
|
||||
private Collector feignCtrlP(int offset) {
|
||||
private static Collector feignCtrlP(int offset, @NotNull PsiFile file) {
|
||||
final PyParameterInfoHandler handler = new PyParameterInfoHandler();
|
||||
|
||||
final Collector collector = new Collector(myFixture.getFile(), offset);
|
||||
final Collector collector = new Collector(file, offset);
|
||||
collector.setParameterOwner(handler.findElementForParameterInfo(collector));
|
||||
|
||||
if (collector.getParameterOwner() != null) {
|
||||
@@ -1174,6 +1180,11 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
return collector;
|
||||
}
|
||||
|
||||
public static void checkParameters(int offset, @NotNull PsiFile file, @NotNull String text, String @NotNull [] highlighted) {
|
||||
Collector collector = feignCtrlP(offset, file);
|
||||
collector.check(text, highlighted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imitates the normal UI contexts to the extent we use it. Collects highlighting.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user