diff --git a/python/src/META-INF/python-plugin-core.xml b/python/src/META-INF/python-plugin-core.xml
index 8858ffbac17e..5919af8f1e17 100644
--- a/python/src/META-INF/python-plugin-core.xml
+++ b/python/src/META-INF/python-plugin-core.xml
@@ -558,6 +558,7 @@
+
diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
new file mode 100644
index 000000000000..0e5fc718f412
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
@@ -0,0 +1,82 @@
+package com.jetbrains.python.codeInsight.userSkeletons;
+
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.codeInsight.PyDynamicMember;
+import com.jetbrains.python.psi.PyClass;
+import com.jetbrains.python.psi.PyFunction;
+import com.jetbrains.python.psi.PyTargetExpression;
+import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
+import com.jetbrains.python.psi.types.PyClassType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author vlan
+ */
+public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase {
+ @NotNull
+ @Override
+ public Collection getMembers(@NotNull PyClassType classType, PsiElement location) {
+ final PyClass cls = classType.getPyClass();
+ final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
+ if (skeleton != null) {
+ return getClassMembers(skeleton);
+ }
+ return Collections.emptyList();
+ }
+
+ @Nullable
+ @Override
+ public PsiElement resolveMember(@NotNull PyClassType classType, @NotNull String name, PsiElement location) {
+ final PyClass cls = classType.getPyClass();
+ final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
+ if (skeleton != null) {
+ return findClassMember(skeleton, name);
+ }
+ return null;
+ }
+
+ private static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name) {
+ final PyFunction function = cls.findMethodByName(name, false);
+ if (function != null) {
+ return function;
+ }
+ final PyTargetExpression instanceAttribute = cls.findInstanceAttribute(name, false);
+ if (instanceAttribute != null) {
+ return instanceAttribute;
+ }
+ final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
+ if (classAttribute != null) {
+ return classAttribute;
+ }
+ return null;
+ }
+
+ private static Collection getClassMembers(@NotNull PyClass cls) {
+ final List result = new ArrayList();
+ for (PyFunction function : cls.getMethods()) {
+ final String name = function.getName();
+ if (name != null) {
+ result.add(new PyDynamicMember(name, function));
+ }
+ }
+ for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
+ final String name = attribute.getName();
+ if (name != null) {
+ result.add(new PyDynamicMember(name, attribute));
+ }
+ }
+ for (PyTargetExpression attribute : cls.getClassAttributes()) {
+ final String name = attribute.getName();
+ if (name != null) {
+ result.add(new PyDynamicMember(name, attribute));
+ }
+ }
+ return result;
+ }
+}
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/a.py
new file mode 100644
index 000000000000..0a96e561c370
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/a.py
@@ -0,0 +1,5 @@
+from datetime import date
+
+print(date.today)
+print(date.max)
+print(date.foo)
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/datetime.py b/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/datetime.py
new file mode 100644
index 000000000000..162a9f6043c7
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection3K/DatetimeDateAttributesOutsideClass/datetime.py
@@ -0,0 +1,4 @@
+class date(object):
+ @classmethod
+ def today(cls):
+ return date(0, 0, 0)
diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
index 7d8b659c4b82..5c51dafc860c 100644
--- a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
@@ -58,6 +58,11 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
+ // PY-9011
+ public void testDatetimeDateAttributesOutsideClass() {
+ doMultiFileTest("a.py");
+ }
+
public void testObjectNewAttributes() {
doTest();
}