diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibDocumentationLinkProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibDocumentationLinkProvider.java index 4fdf6859c7e2..811f391646a5 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibDocumentationLinkProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibDocumentationLinkProvider.java @@ -987,8 +987,12 @@ public class PyStdlibDocumentationLinkProvider implements PythonDocumentationLin private String getStdlibUrlFor(PsiElement element, QualifiedName moduleName, Sdk sdk) { StringBuilder urlBuilder = new StringBuilder(getExternalDocumentationRoot(sdk)); String qnameString = moduleName.toString(); + String moduleNameStr = moduleName.toString(); if (qnameString.equals("ntpath") || qnameString.equals("posixpath")) { qnameString = "os.path"; + } else if (qnameString.equals("genericpath")) { + qnameString = "os.path"; + moduleNameStr = ""; } else if (qnameString.equals("nt")) { qnameString = "os"; @@ -1012,15 +1016,15 @@ public class PyStdlibDocumentationLinkProvider implements PythonDocumentationLin final String name2 = "__init__".equals(name) ? "" : name; final String qName = name == null ? null : className + (!"".equals(className) && !"".equals(name2) ? "." : "") + name2; final String webpageName2 = isBuiltin ? stdlibObjectsToWebpage.get(qName) : webpageName; - final boolean foundModule = webpageName2 != null; - if (foundModule) { - urlBuilder.append(webpageName2 + ".html"); + + if (webpageName2 != null) { + urlBuilder.append(webpageName2).append(".html"); } - if (foundModule && element instanceof PsiNamedElement && !(element instanceof PyFile)) { + if (webpageName2 != null && element instanceof PsiNamedElement && !(element instanceof PyFile)) { urlBuilder.append('#'); if (!isBuiltin) { - urlBuilder.append(moduleName).append("."); + urlBuilder.append(moduleNameStr).append("."); } urlBuilder.append(qName); } diff --git a/python/testSrc/com/jetbrains/python/PyExternalDocTest.kt b/python/testSrc/com/jetbrains/python/PyExternalDocTest.kt index d4fefa88b053..1478b7571cf9 100644 --- a/python/testSrc/com/jetbrains/python/PyExternalDocTest.kt +++ b/python/testSrc/com/jetbrains/python/PyExternalDocTest.kt @@ -11,7 +11,7 @@ import junit.framework.TestCase class PyExternalDocTest : PyTestCase() { - private val pythonDocsLibrary = "https://docs.python.org/3.4 Mock SDK/library" + private val pythonDocsLibrary = "https://docs.python.org/3.7 Mock SDK/library" fun testBuiltins() { // PY-9061 val pythonBuiltinsHelp = "$pythonDocsLibrary/functions.html" @@ -20,20 +20,43 @@ class PyExternalDocTest : PyTestCase() { } fun testUnittestMock() { // PY-29887 - doTest("from unittest.mock import Mock", "$pythonDocsLibrary/unittest.mock.html#unittest.mock.Mock") } + fun testOsPath() { // PY-31223 + doTest("import os.path\n" + + "\n" + + "print(os.path.islink)", "") + + doTest("import os\n" + + "print(os.path.isfile)", "") + } + private fun doTest(text: String, expectedUrl: String) { myFixture.configureByText(getTestName(false) + ".py", text) - TestCase.assertEquals(expectedUrl, getDocUrl(myFixture.elementAtCaret)) + val originalElement = myFixture.file.findElementAt(myFixture.caretOffset) + + var element: PsiElement? + val ref = myFixture.getReferenceAtCaretPosition() + if (ref != null) { + element = ref.resolve() + + if (element == null) { + element = ref.element + } + } else { + element = originalElement + } + + + TestCase.assertEquals(expectedUrl, getDocUrl(element!!, originalElement!!)) } - private fun getDocUrl(element: PsiElement): String? { + private fun getDocUrl(element: PsiElement, originalElement: PsiElement): String? { val provider = DocumentationManager.getProviderFromElement(element) - val urls = provider.getUrlFor(element, element) + val urls = provider.getUrlFor(element, originalElement) TestCase.assertEquals(1, urls!!.size) return urls[0]