summaryrefslogtreecommitdiff
path: root/pylint/test
diff options
context:
space:
mode:
Diffstat (limited to 'pylint/test')
-rw-r--r--pylint/test/functional/iterable_context.py141
-rw-r--r--pylint/test/functional/iterable_context.txt10
-rw-r--r--pylint/test/functional/iterable_context_py2.py18
-rw-r--r--pylint/test/functional/iterable_context_py2.rc3
-rw-r--r--pylint/test/functional/iterable_context_py2.txt1
-rw-r--r--pylint/test/functional/iterable_context_py3.py18
-rw-r--r--pylint/test/functional/iterable_context_py3.rc3
-rw-r--r--pylint/test/functional/iterable_context_py3.txt1
-rw-r--r--pylint/test/functional/mapping_context.py59
-rw-r--r--pylint/test/functional/mapping_context.txt2
-rw-r--r--pylint/test/functional/mapping_context_py2.py19
-rw-r--r--pylint/test/functional/mapping_context_py2.rc3
-rw-r--r--pylint/test/functional/mapping_context_py2.txt1
-rw-r--r--pylint/test/functional/mapping_context_py3.py19
-rw-r--r--pylint/test/functional/mapping_context_py3.rc3
-rw-r--r--pylint/test/functional/mapping_context_py3.txt1
-rw-r--r--pylint/test/functional/yield_from_iterable_py33.py7
-rw-r--r--pylint/test/functional/yield_from_iterable_py33.rc2
-rw-r--r--pylint/test/functional/yield_from_iterable_py33.txt1
-rw-r--r--pylint/test/unittest_checker_base.py1
-rw-r--r--pylint/test/unittest_checker_typecheck.py1
21 files changed, 313 insertions, 1 deletions
diff --git a/pylint/test/functional/iterable_context.py b/pylint/test/functional/iterable_context.py
new file mode 100644
index 0000000..8dfcbbe
--- /dev/null
+++ b/pylint/test/functional/iterable_context.py
@@ -0,0 +1,141 @@
+"""
+Checks that primitive values are not used in an
+iterating/mapping context.
+"""
+# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-init,no-self-use,import-error,unused-argument,bad-mcs-method-argument
+from __future__ import print_function
+
+# primitives
+numbers = [1, 2, 3]
+
+for i in numbers:
+ pass
+
+for i in iter(numbers):
+ pass
+
+for i in "123":
+ pass
+
+for i in u"123":
+ pass
+
+for i in b"123":
+ pass
+
+for i in bytearray(b"123"):
+ pass
+
+for i in set(numbers):
+ pass
+
+for i in frozenset(numbers):
+ pass
+
+for i in dict(a=1, b=2):
+ pass
+
+# comprehensions
+for i in [x for x in range(10)]:
+ pass
+
+for i in {x for x in range(1, 100, 2)}:
+ pass
+
+for i in {x: 10 - x for x in range(10)}:
+ pass
+
+# generators
+def powers_of_two():
+ k = 0
+ while k < 10:
+ yield 2 ** k
+ k += 1
+
+for i in powers_of_two():
+ pass
+
+for i in powers_of_two: # [not-an-iterable]
+ pass
+
+# check for custom iterators
+class A(object):
+ pass
+
+class B(object):
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return 1
+
+ def next(self):
+ return 1
+
+class C(object):
+ "old-style iterator"
+ def __getitem__(self, k):
+ if k > 10:
+ raise IndexError
+ return k + 1
+
+ def __len__(self):
+ return 10
+
+for i in C():
+ print(i)
+
+
+def test(*args):
+ print(args)
+
+
+test(*A()) # [not-an-iterable]
+test(*B())
+test(*B) # [not-an-iterable]
+for i in A(): # [not-an-iterable]
+ pass
+for i in B():
+ pass
+for i in B: # [not-an-iterable]
+ pass
+
+for i in range: # [not-an-iterable]
+ pass
+
+# check that primitive non-iterable types are catched
+for i in True: # [not-an-iterable]
+ pass
+
+for i in None: # [not-an-iterable]
+ pass
+
+for i in 8.5: # [not-an-iterable]
+ pass
+
+for i in 10: # [not-an-iterable]
+ pass
+
+
+# skip uninferable instances
+from some_missing_module import Iterable
+
+class MyClass(Iterable):
+ pass
+
+m = MyClass()
+for i in m:
+ print(i)
+
+# skip checks if statement is inside mixin class
+class ManagedAccessViewMixin(object):
+ access_requirements = None
+
+ def get_access_requirements(self):
+ return self.access_requirements
+
+ def dispatch(self, *_args, **_kwargs):
+ klasses = self.get_access_requirements()
+
+ for requirement in klasses:
+ print(requirement)
diff --git a/pylint/test/functional/iterable_context.txt b/pylint/test/functional/iterable_context.txt
new file mode 100644
index 0000000..fbe1433
--- /dev/null
+++ b/pylint/test/functional/iterable_context.txt
@@ -0,0 +1,10 @@
+not-an-iterable:58::Non-iterable value powers_of_two is used in an iterating context
+not-an-iterable:93::Non-iterable value A() is used in an iterating context
+not-an-iterable:95::Non-iterable value B is used in an iterating context
+not-an-iterable:96::Non-iterable value A() is used in an iterating context
+not-an-iterable:100::Non-iterable value B is used in an iterating context
+not-an-iterable:103::Non-iterable value range is used in an iterating context
+not-an-iterable:107::Non-iterable value True is used in an iterating context
+not-an-iterable:110::Non-iterable value None is used in an iterating context
+not-an-iterable:113::Non-iterable value 8.5 is used in an iterating context
+not-an-iterable:116::Non-iterable value 10 is used in an iterating context
diff --git a/pylint/test/functional/iterable_context_py2.py b/pylint/test/functional/iterable_context_py2.py
new file mode 100644
index 0000000..8687f84
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py2.py
@@ -0,0 +1,18 @@
+"""
+Checks that iterable metaclasses are recognized by pylint.
+"""
+# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,bad-mcs-method-argument
+
+# metaclasses as iterables
+class Meta(type):
+ def __iter__(self):
+ return iter((1, 2, 3))
+
+class SomeClass(object):
+ __metaclass__ = Meta
+
+
+for i in SomeClass:
+ print i
+for i in SomeClass(): # [not-an-iterable]
+ print i
diff --git a/pylint/test/functional/iterable_context_py2.rc b/pylint/test/functional/iterable_context_py2.rc
new file mode 100644
index 0000000..61e01ea
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py2.rc
@@ -0,0 +1,3 @@
+[testoptions]
+max_pyver=2.7
+
diff --git a/pylint/test/functional/iterable_context_py2.txt b/pylint/test/functional/iterable_context_py2.txt
new file mode 100644
index 0000000..8de579a
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py2.txt
@@ -0,0 +1 @@
+not-an-iterable:17::Non-iterable value SomeClass() is used in an iterating context
diff --git a/pylint/test/functional/iterable_context_py3.py b/pylint/test/functional/iterable_context_py3.py
new file mode 100644
index 0000000..cb2a505
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py3.py
@@ -0,0 +1,18 @@
+"""
+Checks that iterable metaclasses are recognized by pylint.
+"""
+# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,bad-mcs-method-argument
+
+# metaclasses as iterables
+class Meta(type):
+ def __iter__(self):
+ return iter((1, 2, 3))
+
+class SomeClass(metaclass=Meta):
+ pass
+
+
+for i in SomeClass:
+ print(i)
+for i in SomeClass(): # [not-an-iterable]
+ print(i)
diff --git a/pylint/test/functional/iterable_context_py3.rc b/pylint/test/functional/iterable_context_py3.rc
new file mode 100644
index 0000000..9bf6df0
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py3.rc
@@ -0,0 +1,3 @@
+[testoptions]
+min_pyver=3.0
+
diff --git a/pylint/test/functional/iterable_context_py3.txt b/pylint/test/functional/iterable_context_py3.txt
new file mode 100644
index 0000000..8de579a
--- /dev/null
+++ b/pylint/test/functional/iterable_context_py3.txt
@@ -0,0 +1 @@
+not-an-iterable:17::Non-iterable value SomeClass() is used in an iterating context
diff --git a/pylint/test/functional/mapping_context.py b/pylint/test/functional/mapping_context.py
new file mode 100644
index 0000000..cfab8dc
--- /dev/null
+++ b/pylint/test/functional/mapping_context.py
@@ -0,0 +1,59 @@
+"""
+Checks that only valid values are used in a mapping context.
+"""
+# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-self-use,import-error
+from __future__ import print_function
+
+
+def test(**kwargs):
+ print(kwargs)
+
+
+# dictionary value/comprehension
+dict_value = dict(a=1, b=2, c=3)
+dict_comp = {chr(x): x for x in range(256)}
+test(**dict_value)
+test(**dict_comp)
+
+
+# in order to be used in kwargs custom mapping class should define
+# __iter__(), __getitem__(key) and keys().
+class CustomMapping(object):
+ def __init__(self):
+ self.data = dict(a=1, b=2, c=3, d=4, e=5)
+
+ def __getitem__(self, key):
+ return self.data[key]
+
+ def keys(self):
+ return self.data.keys()
+
+test(**CustomMapping())
+test(**CustomMapping) # [not-a-mapping]
+
+class NotMapping(object):
+ pass
+
+test(**NotMapping()) # [not-a-mapping]
+
+# skip checks if statement is inside mixin class
+class SomeMixin(object):
+ kwargs = None
+
+ def get_kwargs(self):
+ return self.kwargs
+
+ def run(self, **kwargs):
+ print(kwargs)
+
+ def dispatch(self):
+ kws = self.get_kwargs()
+ self.run(**kws)
+
+# skip uninferable instances
+from some_missing_module import Mapping
+
+class MyClass(Mapping):
+ pass
+
+test(**MyClass())
diff --git a/pylint/test/functional/mapping_context.txt b/pylint/test/functional/mapping_context.txt
new file mode 100644
index 0000000..201da1a
--- /dev/null
+++ b/pylint/test/functional/mapping_context.txt
@@ -0,0 +1,2 @@
+not-a-mapping:32::Non-mapping value CustomMapping is used in a mapping context
+not-a-mapping:37::Non-mapping value NotMapping() is used in a mapping context
diff --git a/pylint/test/functional/mapping_context_py2.py b/pylint/test/functional/mapping_context_py2.py
new file mode 100644
index 0000000..afe4400
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py2.py
@@ -0,0 +1,19 @@
+# pylint: disable=missing-docstring,invalid-name,too-few-public-methods
+from __future__ import print_function
+
+
+def test(**kwargs):
+ print(kwargs)
+
+# metaclasses as mappings
+class Meta(type):
+ def __getitem__(self, key):
+ return ord(key)
+ def keys(self):
+ return ['a', 'b', 'c']
+
+class SomeClass(object):
+ __metaclass__ = Meta
+
+test(**SomeClass)
+test(**SomeClass()) # [not-a-mapping]
diff --git a/pylint/test/functional/mapping_context_py2.rc b/pylint/test/functional/mapping_context_py2.rc
new file mode 100644
index 0000000..61e01ea
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py2.rc
@@ -0,0 +1,3 @@
+[testoptions]
+max_pyver=2.7
+
diff --git a/pylint/test/functional/mapping_context_py2.txt b/pylint/test/functional/mapping_context_py2.txt
new file mode 100644
index 0000000..59cca6c
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py2.txt
@@ -0,0 +1 @@
+not-a-mapping:19::Non-mapping value SomeClass() is used in a mapping context
diff --git a/pylint/test/functional/mapping_context_py3.py b/pylint/test/functional/mapping_context_py3.py
new file mode 100644
index 0000000..042d4d0
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py3.py
@@ -0,0 +1,19 @@
+# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-self-use
+from __future__ import print_function
+
+def test(**kwargs):
+ print(kwargs)
+
+# metaclasses as mappings
+class Meta(type):
+ def __getitem__(cls, key):
+ return ord(key)
+
+ def keys(cls):
+ return ['a', 'b', 'c']
+
+class SomeClass(metaclass=Meta):
+ pass
+
+test(**SomeClass)
+test(**SomeClass()) # [not-a-mapping]
diff --git a/pylint/test/functional/mapping_context_py3.rc b/pylint/test/functional/mapping_context_py3.rc
new file mode 100644
index 0000000..9bf6df0
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py3.rc
@@ -0,0 +1,3 @@
+[testoptions]
+min_pyver=3.0
+
diff --git a/pylint/test/functional/mapping_context_py3.txt b/pylint/test/functional/mapping_context_py3.txt
new file mode 100644
index 0000000..59cca6c
--- /dev/null
+++ b/pylint/test/functional/mapping_context_py3.txt
@@ -0,0 +1 @@
+not-a-mapping:19::Non-mapping value SomeClass() is used in a mapping context
diff --git a/pylint/test/functional/yield_from_iterable_py33.py b/pylint/test/functional/yield_from_iterable_py33.py
new file mode 100644
index 0000000..7803936
--- /dev/null
+++ b/pylint/test/functional/yield_from_iterable_py33.py
@@ -0,0 +1,7 @@
+"""
+Check that `yield from`-statement takes an iterable.
+"""
+# pylint: disable=missing-docstring
+
+def to_ten():
+ yield from 10 # [not-an-iterable]
diff --git a/pylint/test/functional/yield_from_iterable_py33.rc b/pylint/test/functional/yield_from_iterable_py33.rc
new file mode 100644
index 0000000..3330edd
--- /dev/null
+++ b/pylint/test/functional/yield_from_iterable_py33.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.3 \ No newline at end of file
diff --git a/pylint/test/functional/yield_from_iterable_py33.txt b/pylint/test/functional/yield_from_iterable_py33.txt
new file mode 100644
index 0000000..906ee93
--- /dev/null
+++ b/pylint/test/functional/yield_from_iterable_py33.txt
@@ -0,0 +1 @@
+not-an-iterable:7:to_ten:Non-iterable value 10 is used in an iterating context
diff --git a/pylint/test/unittest_checker_base.py b/pylint/test/unittest_checker_base.py
index c68f379..2094314 100644
--- a/pylint/test/unittest_checker_base.py
+++ b/pylint/test/unittest_checker_base.py
@@ -1,7 +1,6 @@
"""Unittest for the base checker."""
import re
-import sys
import unittest
import astroid
diff --git a/pylint/test/unittest_checker_typecheck.py b/pylint/test/unittest_checker_typecheck.py
index b7135ea..0aaa8a5 100644
--- a/pylint/test/unittest_checker_typecheck.py
+++ b/pylint/test/unittest_checker_typecheck.py
@@ -5,6 +5,7 @@ from astroid import test_utils
from pylint.checkers import typecheck
from pylint.testutils import CheckerTestCase, Message, set_config
+
class TypeCheckerTest(CheckerTestCase):
"Tests for pylint.checkers.typecheck"
CHECKER_CLASS = typecheck.TypeChecker