mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Parse references to assigned 'typing' expressions inside docstrings (PY-16303)
This commit is contained in:
@@ -236,6 +236,11 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
@Nullable
|
||||
private static PyType getType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
|
||||
final PsiElement resolved = tryResolving(expression, context);
|
||||
return getTypeForResolvedElement(resolved, context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyType getTypeForResolvedElement(@NotNull PsiElement resolved, @NotNull TypeEvalContext context) {
|
||||
final PyType unionType = getUnionType(resolved, context);
|
||||
if (unionType != null) {
|
||||
return unionType;
|
||||
@@ -294,6 +299,13 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType getTypeFromTargetExpression(@NotNull PyTargetExpression expression, @NotNull TypeEvalContext context) {
|
||||
// XXX: Requires switching from stub to AST
|
||||
final PyExpression assignedValue = expression.findAssignedValue();
|
||||
return assignedValue != null ? getTypeForResolvedElement(assignedValue, context) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Ref<PyType> getClassType(@NotNull PsiElement element, @NotNull TypeEvalContext context) {
|
||||
if (element instanceof PyTypedElement) {
|
||||
|
||||
@@ -441,31 +441,34 @@ public class PyTypeParser {
|
||||
PsiElement resolved = file.getElementNamed(firstText);
|
||||
if (resolved != null) {
|
||||
// Local or imported name
|
||||
if (resolved instanceof PyTypedElement) {
|
||||
if (resolved instanceof PyTargetExpression) {
|
||||
type = PyTypingTypeProvider.getTypeFromTargetExpression((PyTargetExpression)resolved, context);
|
||||
}
|
||||
if (type == null && resolved instanceof PyTypedElement) {
|
||||
type = context.getType((PyTypedElement)resolved);
|
||||
if (type != null) {
|
||||
tokens.remove(0);
|
||||
if (!allowResolveToType(type)) {
|
||||
return null;
|
||||
}
|
||||
if (type instanceof PyClassLikeType) {
|
||||
type = ((PyClassLikeType)type).toInstance();
|
||||
}
|
||||
types.put(firstRange, type);
|
||||
fullRanges.put(type, firstRange);
|
||||
for (PyFromImportStatement fromImportStatement : file.getFromImports()) {
|
||||
for (PyImportElement importElement : fromImportStatement.getImportElements()) {
|
||||
if (firstText.equals(importElement.getVisibleName())) {
|
||||
imports.put(type, importElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PyImportElement importElement : file.getImportTargets()) {
|
||||
}
|
||||
if (type != null) {
|
||||
tokens.remove(0);
|
||||
if (!allowResolveToType(type)) {
|
||||
return null;
|
||||
}
|
||||
if (type instanceof PyClassLikeType) {
|
||||
type = ((PyClassLikeType)type).toInstance();
|
||||
}
|
||||
types.put(firstRange, type);
|
||||
fullRanges.put(type, firstRange);
|
||||
for (PyFromImportStatement fromImportStatement : file.getFromImports()) {
|
||||
for (PyImportElement importElement : fromImportStatement.getImportElements()) {
|
||||
if (firstText.equals(importElement.getVisibleName())) {
|
||||
imports.put(type, importElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PyImportElement importElement : file.getImportTargets()) {
|
||||
if (firstText.equals(importElement.getVisibleName())) {
|
||||
imports.put(type, importElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -497,7 +500,8 @@ public class PyTypeParser {
|
||||
}
|
||||
|
||||
private static boolean allowResolveToType(@NotNull PyType type) {
|
||||
return type instanceof PyClassLikeType || type instanceof PyModuleType || type instanceof PyImportedModuleType;
|
||||
return type instanceof PyClassLikeType || type instanceof PyModuleType || type instanceof PyImportedModuleType ||
|
||||
type instanceof PyGenericType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def ones(shape, dtype=None, order='C')
|
||||
Inferred type: (shape: Union[<a href="psi_element://#typename#int">int</a>, Iterable[<a href="psi_element://#typename#int">int</a>]], dtype: Optional[<a href="psi_element://#typename#object">object</a>], order: Optional[<a href="psi_element://#typename#str">str</a>]) -> ndarray<br>
|
||||
Inferred type: (shape: Union[<a href="psi_element://#typename#int">int</a>, Iterable[<a href="psi_element://#typename#int">int</a>]], dtype: Optional[<a href="psi_element://#typename#object">object</a>], order: Optional[<a href="psi_element://#typename#str">str</a>]) -> <a href="psi_element://#typename#ndarray">ndarray</a><br>
|
||||
**Test docstring**
|
||||
Return a new array of given shape and type, filled with ones.
|
||||
|
||||
@@ -377,6 +377,48 @@ public class PyTypingTest extends PyTestCase {
|
||||
" pass\n");
|
||||
}
|
||||
|
||||
// PY-16303
|
||||
public void testAssignedTypeInDocstring() {
|
||||
doTest("list[int]",
|
||||
"from typing import List\n" +
|
||||
"\n" +
|
||||
"IntList = List[int]\n" +
|
||||
"\n" +
|
||||
"def foo(expr):\n" +
|
||||
" '''\n" +
|
||||
" :type expr: IntList\n" +
|
||||
" '''\n" +
|
||||
" pass\n");
|
||||
}
|
||||
|
||||
// PY-16303
|
||||
public void testParameterAssignedTypeInDocstring() {
|
||||
doTest("Union[int, list[int]]",
|
||||
"from typing import List, Union\n" +
|
||||
"\n" +
|
||||
"IntList = List[int]\n" +
|
||||
"\n" +
|
||||
"def foo(expr):\n" +
|
||||
" '''\n" +
|
||||
" :type expr: Union[int, IntList]\n" +
|
||||
" '''\n" +
|
||||
" pass\n");
|
||||
}
|
||||
|
||||
// PY-16303
|
||||
public void testTypeVarInDocstring() {
|
||||
doTest("TypeVar('TV')",
|
||||
"from typing import TypeVar\n" +
|
||||
"\n" +
|
||||
"TV = TypeVar('TV')\n" +
|
||||
"\n" +
|
||||
"def foo(expr):\n" +
|
||||
" '''\n" +
|
||||
" :type expr: TV\n" +
|
||||
" '''\n" +
|
||||
" pass\n");
|
||||
}
|
||||
|
||||
private void doTestNoInjectedText(@NotNull String text) {
|
||||
myFixture.configureByText(PythonFileType.INSTANCE, text);
|
||||
final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject());
|
||||
|
||||
Reference in New Issue
Block a user