PY-19723 Fixed: Type hinting of arbitrary argument lists and default argument values

Update PyDocStringTypeProvider to correctly handle `:type args: T1` and `:type kwargs: T2`, and wrap their types to `Tuple[T1, ...]` and `Dict[str, T2]`.
This commit is contained in:
Semyon Proshev
2016-11-25 19:02:42 +03:00
parent 5e214c4b4a
commit 45e473cac8
4 changed files with 36 additions and 9 deletions
+2 -2
View File
@@ -7,7 +7,7 @@ import os
class PurePath(object):
def __new__(cls, *pathsegments):
"""
:type pathsegments: tuple[str | bytes | os.PathLike]
:type pathsegments: str | bytes | os.PathLike
:rtype: pathlib.PurePath
"""
return cls.__new__(*pathsegments)
@@ -149,7 +149,7 @@ class PureWindowsPath(pathlib.PurePath):
class Path(pathlib.PurePath):
def __new__(cls, *pathsegments):
"""
:type pathsegments: tuple[str | bytes | os.PathLike]
:type pathsegments: str | bytes | os.PathLike
:rtype: pathlib.Path
"""
return cls.__new__(*pathsegments)
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -19,10 +19,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.PyTypeParser;
import com.jetbrains.python.psi.types.PyTypeProviderBase;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,7 +39,17 @@ public class PyDocStringTypeProvider extends PyTypeProviderBase {
if (docString != null) {
final String typeText = docString.getParamType(param.getName());
if (StringUtil.isNotEmpty(typeText)) {
return parseType(func, typeText);
final Ref<PyType> typeRef = parseType(func, typeText);
if (param.isPositionalContainer()) {
return Ref.create(PyTypeUtil.toPositionalContainerType(param, typeRef.get()));
}
if (param.isKeywordContainer()) {
return Ref.create(PyTypeUtil.toKeywordContainerType(param, typeRef.get()));
}
return typeRef;
}
}
return null;
@@ -1,6 +1,6 @@
def foo(*args):
"""
:type args: tuple[str]
:type args: str
"""
pass
@@ -1428,6 +1428,26 @@ public class PyTypeTest extends PyTestCase {
"expr = raw_input()");
}
// PY-19723
public void testPositionalArgs() {
doTest("Tuple[int, ...]",
"def foo(*args):\n" +
" \"\"\"\n" +
" :type args: int\n" +
" \"\"\"\n" +
" expr = args");
}
// PY-19723
public void testKeywordArgs() {
doTest("Dict[str, int]",
"def foo(**kwargs):\n" +
" \"\"\"\n" +
" :type kwargs: int\n" +
" \"\"\"\n" +
" expr = kwargs");
}
private static List<TypeEvalContext> getTypeEvalContexts(@NotNull PyExpression element) {
return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(),
TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing());