summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-08-17 22:35:28 +0300
committercpopa <devnull@localhost>2014-08-17 22:35:28 +0300
commit7c50e98ba61dc650e995eb0c106ba2487e6e359f (patch)
tree2a90fb6059f6c738637955bbbd05fe2b3c40d888
parent91af7c933718f518c819fd9eb9f3aa3dd967f43b (diff)
downloadpylint-7c50e98ba61dc650e995eb0c106ba2487e6e359f.tar.gz
Check that a class has an explicitly defined metaclass before emitting 'old-style-class' for Python 2.
This can catch metaclasses defined at module level, using `__metaclass__ = ...` syntax, which transforms all old style classes to newstyle. Also, look for the .newstyle attribute instead of bases.
-rw-r--r--ChangeLog3
-rw-r--r--checkers/newstyle.py10
-rw-r--r--test/functional/old_style_class_py27.py17
-rw-r--r--test/functional/old_style_class_py27.rc2
-rw-r--r--test/functional/old_style_class_py27.txt2
-rw-r--r--test/functional/undefined_variable.py2
6 files changed, 30 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index c6b9b03..dc85ee4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -68,6 +68,9 @@ ChangeLog for Pylint
* Detect calls of the parent's __init__, through a binded super() call.
+ * Check that a class has an explicitly defined metaclass before
+ emitting 'old-style-class' for Python 2.
+
2014-07-26 -- 1.3.0
diff --git a/checkers/newstyle.py b/checkers/newstyle.py
index cc8f640..532f3f1 100644
--- a/checkers/newstyle.py
+++ b/checkers/newstyle.py
@@ -74,14 +74,14 @@ class NewStyleConflictChecker(BaseChecker):
@check_messages('slots-on-old-class', 'old-style-class')
def visit_class(self, node):
- """check __slots__ usage
+ """ Check __slots__ in old style classes and old
+ style class definition.
"""
if '__slots__' in node and not node.newstyle:
self.add_message('slots-on-old-class', node=node)
- # The node type could be class, exception, metaclass, or
- # interface. Presumably, the non-class-type nodes would always
- # have an explicit base class anyway.
- if not node.bases and node.type == 'class':
+ # If the class node is not marked as newstyle and it has no explicitly
+ # defined metaclass, then it's an old style class.
+ if not node.newstyle and node.type == 'class' and not node.metaclass():
self.add_message('old-style-class', node=node)
@check_messages('property-on-old-class')
diff --git a/test/functional/old_style_class_py27.py b/test/functional/old_style_class_py27.py
new file mode 100644
index 0000000..4073c73
--- /dev/null
+++ b/test/functional/old_style_class_py27.py
@@ -0,0 +1,17 @@
+""" Tests for old style classes. """
+# pylint: disable=no-init, too-few-public-methods, invalid-name
+
+class Old: # [old-style-class]
+ """ old style class """
+
+class Child(Old): # [old-style-class]
+ """ still an old style class """
+
+__metaclass__ = type
+
+class NotOldStyle:
+ """ Because I have a metaclass at global level. """
+
+class NotOldStyle2:
+ """ Because I have a metaclass at class level. """
+ __metaclass__ = type
diff --git a/test/functional/old_style_class_py27.rc b/test/functional/old_style_class_py27.rc
new file mode 100644
index 0000000..a650233
--- /dev/null
+++ b/test/functional/old_style_class_py27.rc
@@ -0,0 +1,2 @@
+[testoptions]
+max_pyver=3.0
diff --git a/test/functional/old_style_class_py27.txt b/test/functional/old_style_class_py27.txt
new file mode 100644
index 0000000..223233e
--- /dev/null
+++ b/test/functional/old_style_class_py27.txt
@@ -0,0 +1,2 @@
+old-style-class:4::Old-style class defined.
+old-style-class:7::Old-style class defined.
diff --git a/test/functional/undefined_variable.py b/test/functional/undefined_variable.py
index 25f0145..003708c 100644
--- a/test/functional/undefined_variable.py
+++ b/test/functional/undefined_variable.py
@@ -1,5 +1,5 @@
"""Test warnings about access to undefined variables."""
-# pylint: disable=too-few-public-methods, no-init, no-self-use
+# pylint: disable=too-few-public-methods, no-init, no-self-use, old-style-class
DEFINED = 1