Python type inference not working.
Answered
After loading a project, I'm visiting every PsiFile using `PsiRecursiveVisitor`.
I would like to infer the type of expression / function return type.
For even a simple python file containing a single line:
expr = 1 + 2
I want to calculate the type of expr.
Using TypeEvalContext to calculate the type but TypeEvalContext::getType is always returning null.
@Override
public void visitPyAssignmentStatement(PyAssignmentStatement node) {
TypeEvalContext context = TypeEvalContext.codeCompletion(node.getProject(), node.getContainingFile());
PyExpression lhsElement = node.getLeftHandSideExpression();
if (lhsElement != null) {
PyType type = context.getType(lhsElement);
}
}
Am I missing something here?
What is the correct way to calculate type in python files?
Please sign in to leave a comment.
Please try using com.jetbrains.python.psi.types.TypeEvalContext#codeAnalysis instead
Yann Cebron
Tried using com.jetbrains.python.psi.types.TypeEvalContext#codeAnalysis too, but same results.
Yann Cebron
The TypeEvalContext::myEvaluated map also have null type for "str" and b.
Is Python interpreter configured for the inspected project?
Type inference for string literals can be debugged in `com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl#getType`, how do you develop the plugin? With https://github.com/JetBrains/gradle-intellij-plugin?
Please note that visiting every project file is performance-heavy operation, if you described the goal, I could suggest better approach if any.
Semyon Proshev
Yes, the python interpreter is configured for the inspected project (using virtual env).
Yes, developing using https://github.com/JetBrains/gradle-intellij-plugin (v1.0)
Tried debugging PyStringLiteralExpressionImpl#getType,
the above snippet is returning null in PyBuiltinCache::getUnicodeType.
I'm attaching the debugging stack trace here.
I'm running the plug-in in headless mode. The inspected project is in the local file system.
What did you mean by inspected project?
Do I have to add python interpreter in my plug-in external libraries?
Kindly please explain.
Semyon Proshev
I mean the project which PsiFiles you visit with your visitor.
What value is shown if you execute `com.jetbrains.python.sdk.PythonSdkUtil#findPythonSdk(com.intellij.psi.PsiElement)` during debug session?
Thanks for your response.
I am getting null after executing PythonSdkUtil::findPythonSdk(PsiElement), even com.jetbrains.python.sdk.PythonSdkUtil#getAllSdks is returning an empty list.
This is my inspected project's structure:
I am using this API to load my project from the disk (Project path is the path to project_name).
N.B.: I'm running the plugin in headless mode.
Semyon Proshev
Are you running IDEA + Python plugin or PyCharm in this mode?
appStarter
extension point. To run this on headless mode, we are using Gradle runIDE task. This task is executing the following command internally. not certain if this mode is the IDEA+Python plugin or PyCharm (Also no PyCharm UI, running this from IDEA using Gradle).Semyon Proshev
It is PyCharm, does the inspected project contain .idea directory and .idea/misc.xml inside?
Yes, it does.
This is the content inside .idea/misc.xml
Semyon Proshev
If an interpreter is specified in .idea/misc.xml PyCharm does not run its auto-configuration, possible options:
to options/jdk.table.xml in config directory, better to do it through PyCharm
After removing idea/misc.xml PythonSdkUtil::findPythonSdk(PsiElement) returned null again.
Tried updating my options/jdk.table.xml (updated contents: https://pastebin.com/heRftn40) inside ~/.config/JetBrains/IntelliJIdea2021.2/options/, still no luck.
I don't want to update the XML file for every new project I want to inspect.
I would like to use the interpreter used in the inspected project or fall back to some default interpreter.
Currently having no luck finding python SDK while running plugin.
Semyon Proshev
Based on
key in command line, `/workspace/idea/config/options/jdk.table.xml` should be updated.
Regarding first option, sorry, it should be changed to `remove .idea`.
If `.idea` is presented and interpreter is not listed in `config/options/jdk.table.xml`, feel free to set up interpreter in your plugin, don't hesitate to ask for helper methods.
Can you give me any example of how I can manually set up an interpreter in my plugin using helper methods?
I really appreciate your help.
N.B.: After removing .idea folder still found no SDK using PythonSdkUtil::findPythonSdk(PsiElement).
Semyon Proshev
Hello,
I'm using this approach to set up a python interpreter on the project.
And for testing, I'm using https://github.com/JetBrains/gradle-python-envs.
Kindly tell me is the right way? Is there any better approach than this? Semyon Proshev
Fine, PyCharm uses similar approach: https://github.com/JetBrains/intellij-community/blob/0e2aa4030ee763c9b0c828f0b5119f4cdcc66f35/python/ide/impl/src/com/jetbrains/python/PythonSdkConfigurator.kt#L109