PyType (@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PsiElement parent = getParentByStub(); if (parent instanceof PyParameterList) { PyFunction func = getContainingFunction((PyParameterList)parent); if (func != null) { for (PyTypeProvider provider : PyTypeProvider.EP_NAME.getExtensionList()) { final Ref<PyType> resultRef = provider.getParameterType(this, func, context); if (resultRef != null) { return resultRef.get(); } } if (isSelf()) { // must be 'self' or 'cls' final PyClass containingClass = func.getContainingClass(); if (containingClass != null) { final boolean isDefinition = PyUtil.isNewMethod(func) || func.getModifier() == PyFunction.Modifier.CLASSMETHOD; final PyCollectionType genericType = PyTypeChecker.findGenericDefinitionType(containingClass, context); if (genericType != null) { return isDefinition ? genericType.toClass() : genericType; } return new PyClassTypeImpl(containingClass, isDefinition); } } if (isKeywordContainer()) { return PyTypeUtil.toKeywordContainerType(this, null); } if (isPositionalContainer()) { return PyTypeUtil.toPositionalContainerType(this, null); } if (context.maySwitchToAST(this)) { final PyExpression defaultValue = getDefaultValue(); if (defaultValue != null) { final PyType type = context.getType(defaultValue); if (type != null && !(type instanceof PyNoneType)) { if (type instanceof PyTupleType) { return PyUnionType.createWeakType(type); } return type; } } } // Guess the type from file-local calls if (context.allowCallContext(this)) { final List<PyType> types = new ArrayList<>(); final PyResolveContext resolveContext = PyResolveContext.defaultContext(context); final PyCallableParameter parameter = PyCallableParameterImpl.psi(this); processLocalCalls( func, call -> { StreamEx .of(call.multiMapArguments(resolveContext)) .flatCollection(mapping -> mapping.getMappedParameters().entrySet()) .filter(entry -> parameter.equals(entry.getValue())) .map(Map.Entry::getKey) .nonNull() .map(context::getType) .nonNull() .forEach(types::add); return true; } ); if (!types.isEmpty()) { return PyUnionType.createWeakType(PyUnionType.union(types)); } } if (context.maySwitchToAST(this)) { final PyType typeFromUsages = getTypeFromUsages(context); if (typeFromUsages != null) { return typeFromUsages; } } } } return null; }