mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22525 Fixed: PyCharm complains that typing.Iterable "does not define __getitem__"
PY-22642 Fixed: Static typecheck resolution of `typing.Generic` is to the first assignment, not the effective Mark `__getitem__` of `typing.Generic` itself and its descendants as ignored through PyTypingInspectionExtension.
This commit is contained in:
committed by
Semyon Proshev
parent
8a6de5742b
commit
bdccd01940
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -55,10 +55,32 @@ public abstract class PyInspectionExtension {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if unresolved member could be ignored.
|
||||
*
|
||||
* @param type type whose member will be checked
|
||||
* @param name member name
|
||||
* @return true if the unresolved member with the specified name could be ignored
|
||||
* @deprecated Use {@link PyInspectionExtension#ignoreUnresolvedMember(PyType, String, TypeEvalContext)} instead.
|
||||
* This method will be removed in 2018.1.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean ignoreUnresolvedMember(@NotNull PyType type, @NotNull String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if unresolved member could be ignored.
|
||||
*
|
||||
* @param type type whose member will be checked
|
||||
* @param name member name
|
||||
* @param context type evaluation context
|
||||
* @return true if the unresolved member with the specified name could be ignored
|
||||
*/
|
||||
public boolean ignoreUnresolvedMember(@NotNull PyType type, @NotNull String name, @NotNull TypeEvalContext context) {
|
||||
return ignoreUnresolvedMember(type, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if access to protected (the one started with "_") symbol should not be treated as violation.
|
||||
*
|
||||
|
||||
@@ -690,6 +690,7 @@
|
||||
<pyClassMembersProvider implementation="com.jetbrains.python.pyi.PyiClassMembersProvider"/>
|
||||
<visitorFilter language="PythonStub" implementationClass="com.jetbrains.python.pyi.PyiVisitorFilter"/>
|
||||
<inspectionExtension implementation="com.jetbrains.python.pyi.PyiInspectionExtension"/>
|
||||
<inspectionExtension implementation="com.jetbrains.python.codeInsight.typing.PyTypingInspectionExtension"/>
|
||||
<customPackageIdentifier implementation="com.jetbrains.python.pyi.PyiCustomPackageIdentifier"/>
|
||||
|
||||
<!-- User skeletons -->
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.codeInsight.typing
|
||||
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.inspections.PyInspectionExtension
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType
|
||||
import com.jetbrains.python.psi.types.PyType
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext
|
||||
|
||||
class PyTypingInspectionExtension : PyInspectionExtension() {
|
||||
|
||||
override fun ignoreUnresolvedMember(type: PyType, name: String, context: TypeEvalContext): Boolean {
|
||||
return name == PyNames.GETITEM && type is PyClassLikeType && type.isDefinition && isGenericItselfOrDescendant(type, context)
|
||||
}
|
||||
|
||||
private fun isGenericItselfOrDescendant(type: PyClassLikeType,
|
||||
context: TypeEvalContext): Boolean {
|
||||
return type.classQName == PyTypingTypeProvider.GENERIC ||
|
||||
type.getSuperClassTypes(context).any { it.classQName == PyTypingTypeProvider.GENERIC }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -61,6 +61,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
public static final String ASYNC_GENERATOR = "typing.AsyncGenerator";
|
||||
public static final String COROUTINE = "typing.Coroutine";
|
||||
public static final String NAMEDTUPLE = "typing.NamedTuple";
|
||||
public static final String GENERIC = "typing.Generic";
|
||||
|
||||
public static final Pattern TYPE_COMMENT_PATTERN = Pattern.compile("# *type: *(.*)");
|
||||
|
||||
@@ -80,7 +81,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
.build();
|
||||
|
||||
private static final ImmutableSet<String> GENERIC_CLASSES = ImmutableSet.<String>builder()
|
||||
.add("typing.Generic")
|
||||
.add(GENERIC)
|
||||
.add("typing.AbstractGeneric")
|
||||
.add("typing.Protocol")
|
||||
.build();
|
||||
@@ -89,7 +90,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
.add("typing.overload")
|
||||
.add("typing.Any")
|
||||
.add("typing.TypeVar")
|
||||
.add("typing.Generic")
|
||||
.add(GENERIC)
|
||||
.add("typing.Tuple")
|
||||
.add("typing.Callable")
|
||||
.add("typing.Type")
|
||||
@@ -107,7 +108,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) {
|
||||
// Check for the exact name in advance for performance reasons
|
||||
if ("Generic".equals(referenceExpression.getName())) {
|
||||
if (resolveToQualifiedNames(referenceExpression, context).contains("typing.Generic")) {
|
||||
if (resolveToQualifiedNames(referenceExpression, context).contains(GENERIC)) {
|
||||
return createTypingGenericType();
|
||||
}
|
||||
}
|
||||
@@ -219,7 +220,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
|
||||
@NotNull
|
||||
private static PyType createTypingGenericType() {
|
||||
return new PyCustomType("typing.Generic", null, false);
|
||||
return new PyCustomType(GENERIC, null, false);
|
||||
}
|
||||
|
||||
private static boolean omitFirstParamInTypeComment(@NotNull PyFunction func) {
|
||||
@@ -304,7 +305,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
if (referenceTarget instanceof PyTargetExpression) {
|
||||
final PyTargetExpression target = (PyTargetExpression)referenceTarget;
|
||||
// Depends on typing.Generic defined as a target expression
|
||||
if ("typing.Generic".equals(target.getQualifiedName())) {
|
||||
if (GENERIC.equals(target.getQualifiedName())) {
|
||||
return createTypingGenericType();
|
||||
}
|
||||
if (context.maySwitchToAST(target)) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -812,7 +812,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
|
||||
if (extension.ignoreUnresolvedMember(type, name)) {
|
||||
if (extension.ignoreUnresolvedMember(type, name, myTypeEvalContext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import typing
|
||||
|
||||
class MyClass(typing.Generic[str]):
|
||||
pass
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import typing
|
||||
|
||||
|
||||
def myfunc(seq: typing.Iterable[str]):
|
||||
pass
|
||||
+11
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -195,4 +195,14 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
public void testMockPatchObject() {
|
||||
doMultiFileTest(getTestName(true) + ".py");
|
||||
}
|
||||
|
||||
// PY-22525
|
||||
public void testTypingIterableDunderGetItem() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-22642
|
||||
public void testTypingGenericDunderGetItem() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user