void (@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiFile file = descriptor.getPsiElement().getContainingFile(); if (file == null) return; final PsiElement descriptorElement = descriptor.getPsiElement(); if (!(descriptorElement instanceof PyBinaryExpression expression)) return; final List<String> types = collectUnionTypes(expression); final LanguageLevel languageLevel = LanguageLevel.forElement(file); final AddImportHelper.ImportPriority priority = languageLevel.isAtLeast(LanguageLevel.PYTHON35) ? AddImportHelper.ImportPriority.BUILTIN : AddImportHelper.ImportPriority.THIRD_PARTY; final PyCallExpression call = PsiTreeUtil.getParentOfType(expression, PyCallExpression.class); if (call != null && call.isCalleeText(PyNames.ISINSTANCE, PyNames.ISSUBCLASS)) { replaceOldExpressionWith(project, languageLevel, expression, "(" + StringUtil.join(types, ", ") + ")"); } else { if (types.size() == 2 && types.contains(PyNames.NONE)) { final String notNoneType = PyNames.NONE.equals(types.get(0)) ? types.get(1) : types.get(0); AddImportHelper.addOrUpdateFromImportStatement(file, "typing", "Optional", null, priority, expression); replaceOldExpressionWith(project, languageLevel, expression, "Optional[" + notNoneType + "]"); } else { AddImportHelper.addOrUpdateFromImportStatement(file, "typing", "Union", null, priority, expression); replaceOldExpressionWith(project, languageLevel, expression, "Union[" + StringUtil.join(types, ", ") + "]"); } } }