mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Support attr aliases for classes and fields (PY-26354)
This commit is contained in:
+3
-188
@@ -207,191 +207,6 @@ def get_run_validators() -> bool: ...
|
||||
|
||||
# aliases --
|
||||
|
||||
# FIXME: there is a bug in PyCharm with creating aliases to overloads.
|
||||
# Use the aliases instead of the duplicated overloads when the bug is fixed:
|
||||
# https://youtrack.jetbrains.com/issue/PY-27788
|
||||
|
||||
# s = attributes = attrs
|
||||
# ib = attr = attrib
|
||||
# dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;)
|
||||
|
||||
|
||||
@overload
|
||||
def ib(default: None = ...,
|
||||
validator: None = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: None = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: None = ...,
|
||||
converter: None = ...,
|
||||
factory: None = ...,
|
||||
) -> Any: ...
|
||||
@overload
|
||||
def ib(default: None = ...,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: Optional[Type[_T]] = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> _T: ...
|
||||
@overload
|
||||
def ib(default: _T,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: Optional[Type[_T]] = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> _T: ...
|
||||
@overload
|
||||
def ib(default: Optional[_T] = ...,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: object = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> Any: ...
|
||||
|
||||
@overload
|
||||
def attr(default: None = ...,
|
||||
validator: None = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: None = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: None = ...,
|
||||
converter: None = ...,
|
||||
factory: None = ...,
|
||||
) -> Any: ...
|
||||
@overload
|
||||
def attr(default: None = ...,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: Optional[Type[_T]] = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> _T: ...
|
||||
@overload
|
||||
def attr(default: _T,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: Optional[Type[_T]] = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> _T: ...
|
||||
@overload
|
||||
def attr(default: Optional[_T] = ...,
|
||||
validator: Optional[_ValidatorArgType[_T]] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
convert: Optional[_ConverterType[_T]] = ...,
|
||||
metadata: Optional[Mapping[Any, Any]] = ...,
|
||||
type: object = ...,
|
||||
converter: Optional[_ConverterType[_T]] = ...,
|
||||
factory: Optional[Callable[[], _T]] = ...,
|
||||
) -> Any: ...
|
||||
|
||||
@overload
|
||||
def attributes(maybe_cls: _C,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...,
|
||||
auto_attribs: bool = ...) -> _C: ...
|
||||
@overload
|
||||
def attributes(maybe_cls: None = ...,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...,
|
||||
auto_attribs: bool = ...) -> Callable[[_C], _C]: ...
|
||||
|
||||
@overload
|
||||
def s(maybe_cls: _C,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...,
|
||||
auto_attribs: bool = ...) -> _C: ...
|
||||
@overload
|
||||
def s(maybe_cls: None = ...,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...,
|
||||
auto_attribs: bool = ...) -> Callable[[_C], _C]: ...
|
||||
|
||||
# same as above, but with auto_attrib=True
|
||||
@overload
|
||||
def dataclass(maybe_cls: _C,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...) -> _C: ...
|
||||
@overload
|
||||
def dataclass(maybe_cls: None = ...,
|
||||
these: Optional[Dict[str, Any]] = ...,
|
||||
repr_ns: Optional[str] = ...,
|
||||
repr: bool = ...,
|
||||
cmp: bool = ...,
|
||||
hash: Optional[bool] = ...,
|
||||
init: bool = ...,
|
||||
slots: bool = ...,
|
||||
frozen: bool = ...,
|
||||
str: bool = ...) -> Callable[[_C], _C]: ...
|
||||
s = attributes = attrs
|
||||
ib = attr = attrib
|
||||
dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;)
|
||||
|
||||
@@ -27,7 +27,10 @@ fun parseDataclassParameters(cls: PyClass, context: TypeEvalContext): PyDataclas
|
||||
context,
|
||||
mapOf(
|
||||
KnownDecorator.DATACLASSES_DATACLASS to PyDataclassParameters.Type.STD,
|
||||
KnownDecorator.ATTR_S to PyDataclassParameters.Type.ATTRS
|
||||
KnownDecorator.ATTR_S to PyDataclassParameters.Type.ATTRS,
|
||||
KnownDecorator.ATTR_ATTRS to PyDataclassParameters.Type.ATTRS,
|
||||
KnownDecorator.ATTR_ATTRIBUTES to PyDataclassParameters.Type.ATTRS,
|
||||
KnownDecorator.ATTR_DATACLASS to PyDataclassParameters.Type.ATTRS
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -71,7 +71,10 @@ public class PyKnownDecoratorUtil {
|
||||
KOMBU_UTILS_CACHED_PROPERTY("kombu.utils.cached_property"),
|
||||
|
||||
DATACLASSES_DATACLASS("dataclasses.dataclass"),
|
||||
ATTR_S("attr.__init__.s");
|
||||
ATTR_S("attr.__init__.s"),
|
||||
ATTR_ATTRS("attr.__init__.attrs"),
|
||||
ATTR_ATTRIBUTES("attr.__init__.attributes"),
|
||||
ATTR_DATACLASS("attr.__init__.dataclass");
|
||||
|
||||
private final QualifiedName myQualifiedName;
|
||||
|
||||
|
||||
@@ -45,11 +45,13 @@ class PyDataclassFieldStubImpl private constructor(private val calleeName: Quali
|
||||
|
||||
val dataclassesField = QualifiedName.fromComponents("dataclasses", "field")
|
||||
val attrIb = QualifiedName.fromComponents("attr", "ib")
|
||||
val attrAttr = QualifiedName.fromComponents("attr", "attr")
|
||||
val attrAttrib = QualifiedName.fromComponents("attr", "attrib")
|
||||
|
||||
for (originalQName in PyResolveUtil.resolveImportedElementQNameLocally(callee)) {
|
||||
when (originalQName) {
|
||||
dataclassesField -> return qualifiedName to PyDataclassParameters.Type.STD
|
||||
attrIb -> return qualifiedName to PyDataclassParameters.Type.ATTRS
|
||||
attrIb, attrAttr, attrAttrib -> return qualifiedName to PyDataclassParameters.Type.ATTRS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,3 +35,18 @@ class B1:
|
||||
|
||||
B1(<arg4>)
|
||||
|
||||
|
||||
@attr.attrs
|
||||
class C1:
|
||||
x = attr.ib()
|
||||
y = attr.attr(default=0)
|
||||
|
||||
C1(<arg5>)
|
||||
|
||||
|
||||
@attr.attributes
|
||||
class C2:
|
||||
x = attr.attr()
|
||||
y = attr.attrib(default="0")
|
||||
|
||||
C2(<arg6>)
|
||||
|
||||
@@ -47,4 +47,12 @@ class C1:
|
||||
a: typing.ClassVar[int]
|
||||
b: int
|
||||
|
||||
C1(<arg5>)
|
||||
C1(<arg5>)
|
||||
|
||||
|
||||
@attr.dataclass
|
||||
class D1:
|
||||
x: int
|
||||
y: str = "0"
|
||||
|
||||
D1(<arg6>)
|
||||
@@ -756,7 +756,7 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
runWithLanguageLevel(
|
||||
LanguageLevel.PYTHON36,
|
||||
() -> {
|
||||
final Map<String, PsiElement> marks = loadTest(5);
|
||||
final Map<String, PsiElement> marks = loadTest(6);
|
||||
|
||||
feignCtrlP(marks.get("<arg1>").getTextOffset()).check("x: int, y: str, z: float=0.0", new String[]{"x: int, "});
|
||||
feignCtrlP(marks.get("<arg2>").getTextOffset()).check("x: int, y: str, z: float=0.0", new String[]{"x: int, "});
|
||||
@@ -769,6 +769,7 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
|
||||
feignCtrlP(marks.get("<arg4>").getTextOffset()).check("self: B2, x: int", new String[]{"x: int"}, new String[]{"self: B2, "});
|
||||
feignCtrlP(marks.get("<arg5>").getTextOffset()).check("b: int", new String[]{"b: int"});
|
||||
feignCtrlP(marks.get("<arg6>").getTextOffset()).check("x: int, y: str=\"0\"", new String[]{"x: int, "});
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -778,12 +779,14 @@ public class PyParameterInfoTest extends LightMarkedTestCase {
|
||||
runWithLanguageLevel(
|
||||
LanguageLevel.PYTHON36,
|
||||
() -> {
|
||||
final Map<String, PsiElement> marks = loadTest(4);
|
||||
final Map<String, PsiElement> marks = loadTest(6);
|
||||
|
||||
feignCtrlP(marks.get("<arg1>").getTextOffset()).check("x, y, z: int=...", new String[]{"x, "});
|
||||
feignCtrlP(marks.get("<arg2>").getTextOffset()).check("x, y, z: int=...", new String[]{"x, "});
|
||||
feignCtrlP(marks.get("<arg3>").getTextOffset()).check("x, z: int=...", new String[]{"x, "});
|
||||
feignCtrlP(marks.get("<arg4>").getTextOffset()).check("x, y, z: list=...", new String[]{"x, "});
|
||||
feignCtrlP(marks.get("<arg5>").getTextOffset()).check("x, y: int=...", new String[]{"x, "});
|
||||
feignCtrlP(marks.get("<arg6>").getTextOffset()).check("x, y: str=...", new String[]{"x, "});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user