Collection<String> (PyExpression expression) { Collection<String> candidates = new LinkedHashSet<>() { @Override public boolean add(String s) { if (PyNames.isReserved(s)) { return false; } return super.add(s); } }; String text = PyPsiUtils.getStringValue(expression); final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE); if (selection != null) { text = selection.getSecond().substring(selection.getFirst().getText()); } if (expression instanceof PyCallExpression) { final PyExpression callee = ((PyCallExpression)expression).getCallee(); if (callee != null) { text = callee.getText(); } } if (text != null) { candidates.addAll(NameSuggesterUtil.generateNames(text)); } final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getProject(), expression.getContainingFile()); PyType type = context.getType(expression); if (type != null && type != PyNoneType.INSTANCE) { String typeName = type.getName(); if (typeName != null) { if (type instanceof PyLiteralStringType) { // we don't want to suggest "L" for inferred LiteralStrings typeName = "s"; } else if (type.isBuiltin()) { typeName = typeName.substring(0, 1); } candidates.addAll(NameSuggesterUtil.generateNamesByType(typeName)); } } final PyKeywordArgument kwArg = PsiTreeUtil.getParentOfType(expression, PyKeywordArgument.class); if (kwArg != null && kwArg.getValueExpression() == expression) { candidates.add(kwArg.getKeyword()); } Optional .ofNullable(PsiTreeUtil.getParentOfType(expression, PyArgumentList.class)) .map(PyArgumentList::getCallExpression) .ifPresent( call -> StreamEx .of(call.multiMapArguments(PyResolveContext.defaultContext(context))) .map(mapping -> mapping.getMappedParameters().get(expression)) .nonNull() .map(PyCallableParameter::getName) .nonNull() .forEach(candidates::add) ); return candidates; }