diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index c28e78734eae..efb514fd594c 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -247,9 +247,24 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference // Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment final PsiElement realContext = PyPsiUtils.getRealContext(myElement); - PsiElement roof = findResolveRoof(referencedName, realContext); + final PsiElement roof = findResolveRoof(referencedName, realContext); PyResolveUtil.scopeCrawlUp(processor, myElement, referencedName, roof); - return getResultsFromProcessor(referencedName, processor, realContext, roof); + + final List resultsFromProcessor = getResultsFromProcessor(referencedName, processor, realContext, roof); + + // resolve to module __doc__ + if (resultsFromProcessor.isEmpty() && referencedName.equals(PyNames.DOC)) { + ret.addAll( + Optional + .ofNullable(PyBuiltinCache.getInstance(myElement).getObjectType()) + .map(type -> type.resolveMember(referencedName, myElement, AccessDirection.of(myElement), myContext)) + .orElse(Collections.emptyList()) + ); + + return ret; + } + + return resultsFromProcessor; } protected List getResultsFromProcessor(@NotNull String referencedName, diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 3660c809f15f..58db62114614 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -199,6 +199,13 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { return ResolveResultList.to(classMember); } + if (PyNames.DOC.equals(name)) { + return Optional + .ofNullable(PyBuiltinCache.getInstance(myClass).getObjectType()) + .map(type -> type.resolveMember(name, location, direction, resolveContext)) + .orElse(Collections.emptyList()); + } + classMember = resolveByOverridingAncestorsMembersProviders(this, name, location); if (classMember != null) { final ResolveResultList list = new ResolveResultList();