PY-76816 Conformance test failure: enums_definition.py

GitOrigin-RevId: 7881511a5cef928fbb28523e3c1db32460f30eb7
This commit is contained in:
Petr
2024-10-22 09:44:27 +02:00
committed by intellij-monorepo-bot
parent b2ff207d30
commit 85be2f6d8e
6 changed files with 59 additions and 22 deletions

View File

@@ -49,6 +49,7 @@ public final @NonNls class PyNames {
public static final String TYPE_BYTEARRAY = "bytearray";
public static final String TYPE_ENUM = "enum.Enum";
public static final String TYPE_ENUM_META = "enum.EnumMeta";
public static final String PYTHON_SDK_ID_NAME = "Python SDK";
public static final String VERBOSE_REG_EXP_LANGUAGE_ID = "PythonVerboseRegExp";

View File

@@ -12,6 +12,7 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyTypeProvider;
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -83,13 +84,9 @@ public final class PyStdlibTypeProvider extends PyTypeProviderBase {
if (referenceTarget instanceof PyTargetExpression target) {
final ScopeOwner owner = ScopeUtil.getScopeOwner(target);
if (owner instanceof PyClass cls) {
final List<PyClassLikeType> types = cls.getAncestorTypes(context);
for (PyClassLikeType type : types) {
if (type != null && PyNames.TYPE_ENUM.equals(type.getClassQName())) {
final PyType classType = context.getType(cls);
if (classType instanceof PyClassType) {
return Ref.create(((PyClassType)classType).toInstance());
}
if (isEnum(cls, context)) {
if (context.getType(cls) instanceof PyClassType classType) {
return Ref.create(classType.toInstance());
}
}
}
@@ -134,6 +131,12 @@ public final class PyStdlibTypeProvider extends PyTypeProviderBase {
return null;
}
@ApiStatus.Internal
public static boolean isEnum(@NotNull PyClass cls, @NotNull TypeEvalContext context) {
return cls.getMetaClassType(true, context) instanceof PyClassType metaClassType &&
metaClassType.getPyClass().isSubclass(PyNames.TYPE_ENUM_META, context);
}
@Nullable
private static PyType getEnumAutoConstructorType(@NotNull PsiElement target,
@NotNull TypeEvalContext context,

View File

@@ -5,6 +5,7 @@ import com.intellij.openapi.util.Ref
import com.jetbrains.python.PyNames
import com.jetbrains.python.PyTokenTypes
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil
import com.jetbrains.python.codeInsight.stdlib.PyStdlibTypeProvider
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.psi.*
import com.jetbrains.python.psi.impl.PyEvaluator
@@ -126,7 +127,7 @@ class PyLiteralType private constructor(cls: PyClass, val expression: PyExpressi
.asSequence()
.filterIsInstance<PyTargetExpression>()
.mapNotNull { ScopeUtil.getScopeOwner(it) as? PyClass }
.firstOrNull { owner -> owner.getAncestorTypes(context).any { it?.classQName == "enum.Enum" } }
.firstOrNull { owner -> PyStdlibTypeProvider.isEnum(owner, context) }
?.let {
val type = context.getType(it)
return if (type is PyInstantiableType<*>) type.toInstance() else type

View File

@@ -1,2 +0,0 @@
class Enum:
pass

View File

@@ -1604,6 +1604,41 @@ public class Py3TypeTest extends PyTestCase {
pass""");
}
// PY-76816
public void testEnumDefinitionUsingEnumSubclass() {
doTest("Color",
"""
from enum import Enum
class CustomEnum(Enum):
pass
class Color(CustomEnum):
RED = 1
expr = Color.RED
""");
}
// PY-76816
public void testEnumDefinitionUsingEnumTypeMetaclass() {
doTest("Color",
"""
from enum import EnumType
class CustomEnumType(EnumType):
pass
class CustomEnum(metaclass=CustomEnumType):
pass
class Color(CustomEnum):
RED = 1
expr = Color.RED
""");
}
// PY-55734
public void testEnumValueType() {
doTest("int",

View File

@@ -4166,20 +4166,19 @@ public class PyTypeTest extends PyTestCase {
// PY-35235
public void testTypingLiteralEnum() {
// we don't support using `typing.Literal` with enums :(
runWithLanguageLevel(
LanguageLevel.PYTHON35,
() -> doMultiFileTest("A",
"""
from typing_extensions import Literal
from enum import Enum
class A(Enum):
V1 = 1
V2 = 2
expr: Literal[A.V1] = undefined""")
() -> doTest("A",
"""
from typing_extensions import Literal
from enum import Enum
class A(Enum):
V1 = 1
V2 = 2
expr: Literal[A.V1] = undefined""")
);
}