summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-04-25 00:41:40 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-04-25 00:41:40 +0300
commitd2ce43982a4eea760effcb32df752aa0aa396d8d (patch)
treeecfe1403f1f4f9db858c136416477698a08e901c
parent6ea091d1a2d2d25b8b53734909931eb793105beb (diff)
downloadpylint-d2ce43982a4eea760effcb32df752aa0aa396d8d.tar.gz
Lookup in the implicit metaclass when checking for no-member.
If the class in question has an implicit metaclass, which is True for new style classes, then we can look into in when we are doing a dot access on it. Closes issue #438.
-rw-r--r--ChangeLog4
-rw-r--r--pylint/checkers/typecheck.py2
-rw-r--r--pylint/test/functional/class_members_py27.py10
-rw-r--r--pylint/test/functional/class_members_py27.txt1
-rw-r--r--pylint/test/functional/class_members_py30.py10
-rw-r--r--pylint/test/functional/class_members_py30.txt1
6 files changed, 25 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 8b356b1..6db44aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -70,6 +70,10 @@ ChangeLog for Pylint
Since we don't know what those bases might add, we simply ignore
the error in this case.
+ * Lookup in the implicit metaclass when checking for no-member,
+ if the class in question has an implicit metaclass, which is
+ True for new style classes. Closes issue #438.
+
2015-03-14 -- 1.4.3
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
index ed3c901..c8eed30 100644
--- a/pylint/checkers/typecheck.py
+++ b/pylint/checkers/typecheck.py
@@ -126,7 +126,7 @@ def _emit_no_member(owner, owner_name, attrname,
# of methods accessible from the metaclass itself
# and/or subclasses only is too complicated for little to
# no benefit.
- metaclass = owner.metaclass()
+ metaclass = owner.metaclass() or owner.implicit_metaclass()
try:
if metaclass and metaclass.getattr(attrname):
return False
diff --git a/pylint/test/functional/class_members_py27.py b/pylint/test/functional/class_members_py27.py
index 5bbbb65..415a890 100644
--- a/pylint/test/functional/class_members_py27.py
+++ b/pylint/test/functional/class_members_py27.py
@@ -1,5 +1,5 @@
""" Various tests for class members access. """
-# pylint: disable=R0903,print-statement,no-absolute-import, metaclass-assignment,import-error,no-init
+# pylint: disable=R0903,print-statement,no-absolute-import, metaclass-assignment,import-error,no-init,missing-docstring
from missing import Missing
class MyClass(object):
"""class docstring"""
@@ -55,3 +55,11 @@ class NoKnownBases(Missing):
"""Don't emit no-member if we don't know the bases of a class."""
NoKnownBases().lalala()
+
+
+class MetaClass(object):
+ """Look some methods in the implicit metaclass."""
+
+ @classmethod
+ def whatever(cls):
+ return cls.mro() + cls.missing() # [no-member]
diff --git a/pylint/test/functional/class_members_py27.txt b/pylint/test/functional/class_members_py27.txt
index e5e6005..3a3be0e 100644
--- a/pylint/test/functional/class_members_py27.txt
+++ b/pylint/test/functional/class_members_py27.txt
@@ -4,3 +4,4 @@ no-member:16:MyClass.test:Instance of 'MyClass' has no 'nonexistent1' member:INF
no-member:17:MyClass.test:Instance of 'MyClass' has no 'nonexistent2' member:INFERENCE
no-member:50::Instance of 'TestMetaclass' has no 'register' member:INFERENCE
no-member:51::Instance of 'UsingMetaclass' has no 'test' member:INFERENCE
+no-member:65:MetaClass.whatever:Class 'MetaClass' has no 'missing' member:INFERENCE
diff --git a/pylint/test/functional/class_members_py30.py b/pylint/test/functional/class_members_py30.py
index b8bc109..8c27703 100644
--- a/pylint/test/functional/class_members_py30.py
+++ b/pylint/test/functional/class_members_py30.py
@@ -1,5 +1,5 @@
""" Various tests for class members access. """
-# pylint: disable=R0903,import-error,no-init
+# pylint: disable=R0903,import-error,no-init,missing-docstring
from missing import Missing
class MyClass(object):
"""class docstring"""
@@ -53,3 +53,11 @@ class NoKnownBases(Missing):
"""Don't emit no-member if we don't know the bases of a class."""
NoKnownBases().lalala()
+
+
+class MetaClass(object):
+ """Look some methods in the implicit metaclass."""
+
+ @classmethod
+ def whatever(cls):
+ return cls.mro() + cls.missing() # [no-member]
diff --git a/pylint/test/functional/class_members_py30.txt b/pylint/test/functional/class_members_py30.txt
index 4696579..d9163ec 100644
--- a/pylint/test/functional/class_members_py30.txt
+++ b/pylint/test/functional/class_members_py30.txt
@@ -4,3 +4,4 @@ no-member:16:MyClass.test:Instance of 'MyClass' has no 'nonexistent1' member:INF
no-member:17:MyClass.test:Instance of 'MyClass' has no 'nonexistent2' member:INFERENCE
no-member:48::Instance of 'TestMetaclass' has no 'register' member:INFERENCE
no-member:49::Instance of 'UsingMetaclass' has no 'test' member:INFERENCE
+no-member:63:MetaClass.whatever:Class 'MetaClass' has no 'missing' member:INFERENCE \ No newline at end of file