mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'python-fixes'
This commit is contained in:
@@ -176,6 +176,21 @@ public class PyCallExpressionHelper {
|
||||
else if (PyNames.STATICMETHOD.equals(wrapper_name)) wrappedModifier = PyFunction.Modifier.STATICMETHOD;
|
||||
}
|
||||
}
|
||||
final List<PyExpression> qualifiers = resolveResult != null ? resolveResult.getQualifiers() : Collections.<PyExpression>emptyList();
|
||||
final TypeEvalContext context = resolveContext.getTypeEvalContext();
|
||||
if (resolved instanceof PyFunction) {
|
||||
final PyFunction function = (PyFunction)resolved;
|
||||
final Property property = function.getProperty();
|
||||
if (property != null && isQualifiedByInstance(function, qualifiers, context)) {
|
||||
final PyType type = function.getReturnType(context, null);
|
||||
if (type instanceof PyFunctionType) {
|
||||
resolved = ((PyFunctionType)type).getCallable();
|
||||
}
|
||||
else {
|
||||
resolved = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resolved instanceof Callable) {
|
||||
PyFunction.Modifier modifier = resolved instanceof PyFunction
|
||||
? ((PyFunction)resolved).getModifier()
|
||||
@@ -183,12 +198,10 @@ public class PyCallExpressionHelper {
|
||||
if (modifier == null && wrappedModifier != null) {
|
||||
modifier = wrappedModifier;
|
||||
}
|
||||
List<PyExpression> qualifiers = resolveResult != null ? resolveResult.getQualifiers() : Collections.<PyExpression>emptyList();
|
||||
boolean isByInstance = isConstructorCall ||
|
||||
isQualifiedByInstance((Callable)resolved, qualifiers, resolveContext.getTypeEvalContext())
|
||||
|| resolved instanceof PyBoundFunction;
|
||||
boolean isByInstance = isConstructorCall || isQualifiedByInstance((Callable)resolved, qualifiers, context)
|
||||
|| resolved instanceof PyBoundFunction;
|
||||
PyExpression lastQualifier = qualifiers != null && qualifiers.isEmpty() ? null : qualifiers.get(qualifiers.size()-1);
|
||||
boolean isByClass = lastQualifier == null ? false : isQualifiedByClass((Callable)resolved, lastQualifier, resolveContext.getTypeEvalContext());
|
||||
boolean isByClass = lastQualifier == null ? false : isQualifiedByClass((Callable)resolved, lastQualifier, context);
|
||||
final Callable callable = (Callable)resolved;
|
||||
|
||||
implicitOffset += getImplicitArgumentCount(callable, modifier, isConstructorCall, isByInstance, isByClass);
|
||||
@@ -408,6 +421,12 @@ public class PyCallExpressionHelper {
|
||||
if (t != null && !(t instanceof PyNoneType)) {
|
||||
return t;
|
||||
}
|
||||
if (cls != null && t == null) {
|
||||
final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true);
|
||||
if (newMethod != null && !PyBuiltinCache.getInstance(call).hasInBuiltins(newMethod)) {
|
||||
return PyUnionType.createWeakType(new PyClassTypeImpl(cls, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cls != null) {
|
||||
return new PyClassTypeImpl(cls, false);
|
||||
|
||||
@@ -165,7 +165,26 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
|
||||
PyParameterList parameterList = (PyParameterList)parent;
|
||||
PyFunction func = parameterList.getContainingFunction();
|
||||
if (func != null) {
|
||||
final PyFunction.Modifier modifier = func.getModifier();
|
||||
PyAnnotation anno = getAnnotation();
|
||||
if (anno != null) {
|
||||
final PyClass pyClass = anno.resolveToClass();
|
||||
if (pyClass != null) {
|
||||
return new PyClassTypeImpl(pyClass, false);
|
||||
}
|
||||
}
|
||||
StructuredDocString docString = func.getStructuredDocString();
|
||||
if (PyNames.INIT.equals(func.getName()) && docString == null) {
|
||||
PyClass pyClass = func.getContainingClass();
|
||||
if (pyClass != null) {
|
||||
docString = pyClass.getStructuredDocString();
|
||||
}
|
||||
}
|
||||
if (docString != null) {
|
||||
String typeName = docString.getParamType(getName());
|
||||
if (typeName != null) {
|
||||
return PyTypeParser.getTypeByName(this, typeName);
|
||||
}
|
||||
}
|
||||
if (isSelf()) {
|
||||
// must be 'self' or 'cls'
|
||||
final PyClass containingClass = func.getContainingClass();
|
||||
@@ -190,6 +209,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
|
||||
if (initType != null && !(initType instanceof PyNoneType)) {
|
||||
return initType;
|
||||
}
|
||||
final PyFunction.Modifier modifier = func.getModifier();
|
||||
return new PyClassTypeImpl(containingClass, modifier == PyFunction.Modifier.CLASSMETHOD);
|
||||
}
|
||||
}
|
||||
@@ -199,27 +219,6 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
|
||||
if (isPositionalContainer()) {
|
||||
return PyBuiltinCache.getInstance(this).getTupleType();
|
||||
}
|
||||
PyAnnotation anno = getAnnotation();
|
||||
if (anno != null) {
|
||||
final PyClass pyClass = anno.resolveToClass();
|
||||
if (pyClass != null) {
|
||||
return new PyClassTypeImpl(pyClass, false);
|
||||
}
|
||||
}
|
||||
|
||||
StructuredDocString docString = func.getStructuredDocString();
|
||||
if (PyNames.INIT.equals(func.getName()) && docString == null) {
|
||||
PyClass pyClass = func.getContainingClass();
|
||||
if (pyClass != null) {
|
||||
docString = pyClass.getStructuredDocString();
|
||||
}
|
||||
}
|
||||
if (docString != null) {
|
||||
String typeName = docString.getParamType(getName());
|
||||
if (typeName != null) {
|
||||
return PyTypeParser.getTypeByName(this, typeName);
|
||||
}
|
||||
}
|
||||
for(PyTypeProvider provider: Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
|
||||
PyType result = provider.getParameterType(this, func, context);
|
||||
if (result != null) return result;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class C(object):
|
||||
@property
|
||||
def f(self):
|
||||
return lambda x, y: (x, y)
|
||||
|
||||
|
||||
c = C()
|
||||
c.f(1, 2)
|
||||
c.f(<warning descr="Parameter 'x' unfilled"><warning descr="Parameter 'y' unfilled">)</warning></warning>
|
||||
c.f(1, 2, <warning descr="Unexpected argument">3</warning>)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
from b import C
|
||||
|
||||
c = C()
|
||||
c.foo()
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class C(object):
|
||||
def __new__(cls):
|
||||
return D()
|
||||
|
||||
|
||||
class D(object):
|
||||
def foo(self):
|
||||
pass
|
||||
@@ -760,6 +760,30 @@ public class PyTypeTest extends PyTestCase {
|
||||
" print(expr)\n");
|
||||
}
|
||||
|
||||
// PY-8953
|
||||
public void testSelfInDocString() {
|
||||
doTest("int",
|
||||
"class C(object):\n" +
|
||||
" def foo(self):\n" +
|
||||
" '''\n" +
|
||||
" :type self: int\n" +
|
||||
" '''\n" +
|
||||
" expr = self\n");
|
||||
}
|
||||
|
||||
// PY-9605
|
||||
public void testPropertyReturnsCallable() {
|
||||
doTest("() -> int",
|
||||
"class C(object):\n" +
|
||||
" @property\n" +
|
||||
" def foo(self):\n" +
|
||||
" return lambda: 0\n" +
|
||||
"\n" +
|
||||
|
||||
"c = C()\n" +
|
||||
"expr = c.foo\n");
|
||||
}
|
||||
|
||||
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
|
||||
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
|
||||
}
|
||||
|
||||
@@ -138,4 +138,9 @@ public class PyArgumentListInspectionTest extends PyTestCase {
|
||||
public void testDecoratedChangedParameters() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-9605
|
||||
public void testPropertyReturnsCallable() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -298,6 +298,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
doMultiFileTest("a.py");
|
||||
}
|
||||
|
||||
// PY-10893
|
||||
public void testCustomNewReturnInAnotherModule() {
|
||||
doMultiFileTest("a.py");
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
|
||||
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
|
||||
|
||||
Reference in New Issue
Block a user