mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Support typing.Supports* in PyABCUtil.
PY-24789, PY-23391, PY-24194, PY-23289 Fixed.
This commit is contained in:
@@ -183,6 +183,12 @@ public class PyNames {
|
||||
public static final String SIZEOF = "__sizeof__";
|
||||
public static final String INIT_SUBCLASS = "__init_subclass__";
|
||||
public static final String FSPATH = "__fspath__";
|
||||
public static final String COMPLEX = "__complex__";
|
||||
public static final String FLOAT = "__float__";
|
||||
public static final String INT = "__int__";
|
||||
public static final String BYTES = "__bytes__";
|
||||
public static final String ABS = "__abs__";
|
||||
public static final String ROUND = "__round__";
|
||||
|
||||
public static final String NAME = "__name__";
|
||||
public static final String ENTER = "__enter__";
|
||||
@@ -295,7 +301,7 @@ public class PyNames {
|
||||
private static final BuiltinDescription _exit_descr = new BuiltinDescription("(self, exc_type, exc_val, exc_tb)");
|
||||
|
||||
private static final ImmutableMap<String, BuiltinDescription> BuiltinMethods = ImmutableMap.<String, BuiltinDescription>builder()
|
||||
.put("__abs__", _only_self_descr)
|
||||
.put(ABS, _only_self_descr)
|
||||
.put("__add__", _self_other_descr)
|
||||
.put("__and__", _self_other_descr)
|
||||
//_BuiltinMethods.put("__all__", _only_self_descr);
|
||||
@@ -306,7 +312,7 @@ public class PyNames {
|
||||
//_BuiltinMethods.put("__class__", _only_self_descr);
|
||||
.put("__cmp__", _self_other_descr)
|
||||
.put("__coerce__", _self_other_descr)
|
||||
.put("__complex__", _only_self_descr)
|
||||
.put(COMPLEX, _only_self_descr)
|
||||
.put("__contains__", _self_item_descr)
|
||||
.put("__copy__", _only_self_descr)
|
||||
//_BuiltinMethods.put("__debug__", _only_self_descr);
|
||||
@@ -324,7 +330,7 @@ public class PyNames {
|
||||
.put("__exit__", _exit_descr)
|
||||
.put("__eq__", _self_other_descr)
|
||||
//_BuiltinMethods.put("__file__", _only_self_descr);
|
||||
.put("__float__", _only_self_descr)
|
||||
.put(FLOAT, _only_self_descr)
|
||||
.put("__floor__", _only_self_descr)
|
||||
.put("__floordiv__", _self_other_descr)
|
||||
//_BuiltinMethods.put("__future__", _only_self_descr);
|
||||
@@ -350,7 +356,7 @@ public class PyNames {
|
||||
.put("__imul__", _self_other_descr)
|
||||
.put("__index__", _only_self_descr)
|
||||
.put(INIT, _only_self_descr)
|
||||
.put("__int__", _only_self_descr)
|
||||
.put(INT, _only_self_descr)
|
||||
.put("__invert__", _only_self_descr)
|
||||
.put("__ior__", _self_other_descr)
|
||||
.put("__ipow__", _self_other_descr)
|
||||
@@ -425,11 +431,11 @@ public class PyNames {
|
||||
public static final ImmutableMap<String, BuiltinDescription> PY3_BUILTIN_METHODS = ImmutableMap.<String, BuiltinDescription>builder()
|
||||
.putAll(BuiltinMethods)
|
||||
.put("__bool__", _only_self_descr)
|
||||
.put("__bytes__", _only_self_descr)
|
||||
.put(BYTES, _only_self_descr)
|
||||
.put("__format__", new BuiltinDescription("(self, format_spec)"))
|
||||
.put("__instancecheck__", new BuiltinDescription("(self, instance)"))
|
||||
.put("__prepare__", new BuiltinDescription("(metacls, name, bases)"))
|
||||
.put("__round__", new BuiltinDescription("(self, n=None)"))
|
||||
.put(ROUND, new BuiltinDescription("(self, n=None)"))
|
||||
.put("__subclasscheck__", new BuiltinDescription("(self, subclass)"))
|
||||
.put(DUNDER_NEXT, _only_self_descr)
|
||||
.build();
|
||||
|
||||
@@ -75,6 +75,12 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
private static final String CALLABLE = "typing.Callable";
|
||||
|
||||
public static final String NAMEDTUPLE_SIMPLE = "NamedTuple";
|
||||
public static final String SUPPORTS_INT_SIMPLE = "SupportsInt";
|
||||
public static final String SUPPORTS_FLOAT_SIMPLE = "SupportsFloat";
|
||||
public static final String SUPPORTS_COMPLEX_SIMPLE = "SupportsComplex";
|
||||
public static final String SUPPORTS_BYTES_SIMPLE = "SupportsBytes";
|
||||
public static final String SUPPORTS_ABS_SIMPLE = "SupportsAbs";
|
||||
public static final String SUPPORTS_ROUND_SIMPLE = "SupportsRound";
|
||||
|
||||
public static final Pattern TYPE_COMMENT_PATTERN = Pattern.compile("# *type: *(.*)");
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.jetbrains.python.psi.types;
|
||||
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -82,14 +83,14 @@ public class PyABCUtil {
|
||||
hasMethod(subClass, "discard", inherited, context) &&
|
||||
hasMethod(subClass, "add", inherited, context);
|
||||
}
|
||||
if (PyNames.ABC_COMPLEX.equals(superClassName)) {
|
||||
return hasMethod(subClass, "__complex__", inherited, context);
|
||||
if (PyNames.ABC_COMPLEX.equals(superClassName) || PyTypingTypeProvider.SUPPORTS_COMPLEX_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.COMPLEX, inherited, context);
|
||||
}
|
||||
if (PyNames.ABC_REAL.equals(superClassName)) {
|
||||
return hasMethod(subClass, "__float__", inherited, context);
|
||||
if (PyNames.ABC_REAL.equals(superClassName) || PyTypingTypeProvider.SUPPORTS_FLOAT_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.FLOAT, inherited, context);
|
||||
}
|
||||
if (PyNames.ABC_INTEGRAL.equals(superClassName)) {
|
||||
return hasMethod(subClass, "__int__", inherited, context);
|
||||
if (PyNames.ABC_INTEGRAL.equals(superClassName) || PyTypingTypeProvider.SUPPORTS_INT_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.INT, inherited, context);
|
||||
}
|
||||
if (PyNames.ABC_NUMBER.equals(superClassName) && "Decimal".equals(subClass.getName())) {
|
||||
return true;
|
||||
@@ -100,6 +101,15 @@ public class PyABCUtil {
|
||||
if (PyNames.PATH_LIKE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.FSPATH, inherited, context);
|
||||
}
|
||||
if (PyTypingTypeProvider.SUPPORTS_BYTES_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.BYTES, inherited, context);
|
||||
}
|
||||
if (PyTypingTypeProvider.SUPPORTS_ABS_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.ABS, inherited, context);
|
||||
}
|
||||
if (PyTypingTypeProvider.SUPPORTS_ROUND_SIMPLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.ROUND, inherited, context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import typing
|
||||
|
||||
|
||||
def check_complex(p: typing.SupportsComplex):
|
||||
print(p.__complex__())
|
||||
|
||||
|
||||
class A:
|
||||
def __int__(self):
|
||||
return 5
|
||||
|
||||
|
||||
def __float__(self):
|
||||
return 5.0
|
||||
|
||||
|
||||
def __complex__(self):
|
||||
return complex(5.0, 0.0)
|
||||
|
||||
def __bytes__(self):
|
||||
return b'bytes'
|
||||
|
||||
def __abs__(self):
|
||||
return 5
|
||||
|
||||
def __round__(self, n=None):
|
||||
return 5
|
||||
|
||||
|
||||
a = A()
|
||||
print(int(a))
|
||||
print(float(a))
|
||||
check_complex(a)
|
||||
print(bytes(a))
|
||||
print(abs(a))
|
||||
print(round(a))
|
||||
|
||||
@@ -260,4 +260,12 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase {
|
||||
public void testUnionOfIntAndFloatShouldBeConsideredAsDividable() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-23289
|
||||
// PY-23391
|
||||
// PY-24194
|
||||
// PY-24789
|
||||
public void testTypingSupports() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON35, this::doTest);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user