mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
PY-76149 Support descriptor types as annotations for dataclass fields
(cherry picked from commit 78a127e1a0083ece810ad996124ad6ea65887da2) GitOrigin-RevId: 0c33fe51f5f13116f773577056317c537cbc83ef
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4ad6f08f45
commit
c653a43cab
@@ -254,6 +254,12 @@ class PyDataclassTypeProvider : PyTypeProviderBase() {
|
||||
if (type is PyCollectionType && type.classQName == Dataclasses.DATACLASSES_INITVAR) {
|
||||
return type.elementTypes.firstOrNull()
|
||||
}
|
||||
if (type is PyClassLikeType) {
|
||||
val expectedConstructorArgumentTypeRef = PyDescriptorTypeUtil.getExpectedValueTypeForDunderSet(field, type, context)
|
||||
if (expectedConstructorArgumentTypeRef != null) {
|
||||
return Ref.deref(expectedConstructorArgumentTypeRef)
|
||||
}
|
||||
}
|
||||
|
||||
if (type == null && dataclassType.asPredefinedType == PyDataclassParameters.PredefinedType.ATTRS) {
|
||||
methodDecoratedAsAttributeDefault(cls, field.name)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
from typing import dataclass_transform, TypeVar, Generic
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@dataclass_transform()
|
||||
def deco(cls):
|
||||
...
|
||||
|
||||
class MyDescriptor(Generic[T]):
|
||||
def __set__(self, obj: object, value: T) -> None:
|
||||
...
|
||||
|
||||
@deco
|
||||
class MyClass:
|
||||
id: MyDescriptor[int]
|
||||
name: MyDescriptor[str]
|
||||
year: MyDescriptor[int]
|
||||
new: MyDescriptor[bool]
|
||||
|
||||
MyClass(<arg1>)
|
||||
@@ -1345,6 +1345,12 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
feignCtrlPWithHintsForHighlightedOnly(marks.get("<arg1>").getTextOffset()).check("a, b, c: str = \"default\"", new String[]{"c: str = \"default\""});
|
||||
}
|
||||
|
||||
// PY-76149
|
||||
public void testDataclassTransformConstructorSignatureWithFieldsAnnotatedWithGenericDescriptor() {
|
||||
final Map<String, PsiElement> marks = loadTest(1);
|
||||
feignCtrlP(marks.get("<arg1>").getTextOffset()).check("id: int, name: str, year: int, new: bool", new String[]{"id: int, "});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collector feignCtrlP(int offset) {
|
||||
return feignCtrlP(offset, myFixture.getFile(), true, myFixture.getEditor());
|
||||
|
||||
@@ -5970,6 +5970,86 @@ public class PyTypingTest extends PyTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
// PY-76149
|
||||
public void testDataclassTransformConstructorSignatureWithFieldsAnnotatedWithDescriptor() {
|
||||
doTestExpressionUnderCaret("(id: int, name: str) -> MyClass", """
|
||||
from typing import dataclass_transform
|
||||
|
||||
@dataclass_transform()
|
||||
def deco(cls):
|
||||
...
|
||||
|
||||
class MyIdDescriptor:
|
||||
def __set__(self, obj: object, value: int) -> None:
|
||||
...
|
||||
|
||||
class MyNameDescriptor:
|
||||
def __set__(self, obj: object, value: str) -> None:
|
||||
...
|
||||
|
||||
@deco
|
||||
class MyClass:
|
||||
id: MyIdDescriptor
|
||||
name: MyNameDescriptor
|
||||
|
||||
MyCl<caret>ass()
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-76149
|
||||
public void testDataclassTransformConstructorSignatureWithFieldsAnnotatedWithGenericDescriptor() {
|
||||
doTestExpressionUnderCaret("(id: int, name: str) -> MyClass", """
|
||||
from typing import dataclass_transform, TypeVar, Generic
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@dataclass_transform()
|
||||
def deco(cls):
|
||||
...
|
||||
|
||||
class MyDescriptor(Generic[T]):
|
||||
def __set__(self, obj: object, value: T) -> None:
|
||||
...
|
||||
|
||||
@deco
|
||||
class MyClass:
|
||||
id: MyDescriptor[int]
|
||||
name: MyDescriptor[str]
|
||||
|
||||
MyCl<caret>ass()
|
||||
""");
|
||||
}
|
||||
|
||||
// PY-76149
|
||||
public void testDataclassTransformConstructorSignatureWithFieldsAnnotatedWitExplicitAny() {
|
||||
doTestExpressionUnderCaret("(id: int, name: str, payload: Any, payload_length: int) -> MyClass", """
|
||||
from typing import dataclass_transform, TypeVar, Generic, Any
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@dataclass_transform()
|
||||
def deco(cls):
|
||||
...
|
||||
|
||||
class MyDescriptor(Generic[T]):
|
||||
def __set__(self, obj: object, value: T) -> None:
|
||||
...
|
||||
|
||||
class Anything:
|
||||
def __set__(self, obj: object, value: Any) -> None:
|
||||
...
|
||||
|
||||
@deco
|
||||
class MyClass:
|
||||
id: MyDescriptor[int]
|
||||
name: MyDescriptor[str]
|
||||
payload: Anything
|
||||
payload_length: MyDescriptor[int]
|
||||
|
||||
My<caret>Class()
|
||||
""");
|
||||
}
|
||||
|
||||
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