Provide type for pathlib._PurePathBase until PY-34617 is fixed (PY-30747)

GitOrigin-RevId: 25a707348036715ebb67280ea650a298cf882f4e
This commit is contained in:
Semyon Proshev
2020-06-16 17:08:14 +03:00
committed by intellij-monorepo-bot
parent 188092153b
commit ed160cbeeb
2 changed files with 46 additions and 0 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -50,6 +51,10 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
if (type != null) {
return Ref.create(type);
}
type = getPathlibPurePathBaseType(referenceTarget);
if (type != null) {
return Ref.create(type);
}
return null;
}
@@ -129,6 +134,31 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
return null;
}
@Nullable
private static PyType getPathlibPurePathBaseType(@NotNull PsiElement referenceTarget) {
if (referenceTarget instanceof PyTargetExpression &&
"pathlib._PurePathBase".equals(((PyTargetExpression)referenceTarget).getQualifiedName())) {
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(referenceTarget);
if (LanguageLevel.forElement(referenceTarget).isOlderThan(LanguageLevel.PYTHON36)) {
final PyClassType objectType = builtinCache.getObjectType();
if (objectType != null) {
return objectType.toClass();
}
}
final PyClassType pathLikeType = builtinCache.getObjectType(PyNames.BUILTIN_PATH_LIKE);
final PyClassType strType = builtinCache.getStrType();
if (pathLikeType != null) {
return strType == null
? pathLikeType.toClass()
: new PyCollectionTypeImpl(pathLikeType.getPyClass(), true, Collections.singletonList(strType));
}
}
return null;
}
@Nullable
@Override
public Ref<PyType> getCallType(@NotNull PyFunction function, @NotNull PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
@@ -418,4 +418,20 @@ public class Py3TypeCheckerInspectionTest extends PyInspectionTestCase {
public void testParametrizedBuiltinTypeAndTypingTypeAreEquivalent() {
doTest();
}
// PY-30747
public void testPathlibPathMatchingOsPathLike() {
doTestByText(
"import pathlib\n" +
"import os\n" +
"\n" +
"def foo(p: pathlib.Path):\n" +
" with open(p) as file:\n" +
" pass\n" +
"\n" +
"p1: pathlib.Path\n" +
"p2: os.PathLike[bytes] = p1 # false negative, see PyTypeChecker.matchGenerics\n" +
"p3: os.PathLike[str] = p1"
);
}
}