aboutsummaryrefslogtreecommitdiff
path: root/tests/functional/a/abstract/abstract_class_instantiated.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/a/abstract/abstract_class_instantiated.py')
-rw-r--r--tests/functional/a/abstract/abstract_class_instantiated.py143
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/functional/a/abstract/abstract_class_instantiated.py b/tests/functional/a/abstract/abstract_class_instantiated.py
new file mode 100644
index 000000000..85facb540
--- /dev/null
+++ b/tests/functional/a/abstract/abstract_class_instantiated.py
@@ -0,0 +1,143 @@
+"""Check that instantiating a class with
+`abc.ABCMeta` as metaclass fails if it defines
+abstract methods.
+"""
+
+# pylint: disable=too-few-public-methods, missing-docstring
+# pylint: disable=abstract-method, import-error, useless-object-inheritance
+
+import abc
+import weakref
+from lala import Bala
+
+
+class GoodClass(object, metaclass=abc.ABCMeta):
+ pass
+
+class SecondGoodClass(object, metaclass=abc.ABCMeta):
+ def test(self):
+ """ do nothing. """
+
+class ThirdGoodClass(object, metaclass=abc.ABCMeta):
+ """ This should not raise the warning. """
+ def test(self):
+ raise NotImplementedError()
+
+class BadClass(object, metaclass=abc.ABCMeta):
+ @abc.abstractmethod
+ def test(self):
+ """ do nothing. """
+
+class SecondBadClass(object, metaclass=abc.ABCMeta):
+ @property
+ @abc.abstractmethod
+ def test(self):
+ """ do nothing. """
+
+class ThirdBadClass(SecondBadClass):
+ pass
+
+
+class Structure(object, metaclass=abc.ABCMeta):
+ @abc.abstractmethod
+ def __iter__(self):
+ pass
+ @abc.abstractmethod
+ def __len__(self):
+ pass
+ @abc.abstractmethod
+ def __contains__(self, _):
+ pass
+ @abc.abstractmethod
+ def __hash__(self):
+ pass
+
+class Container(Structure):
+ def __contains__(self, _):
+ pass
+
+class Sizable(Structure):
+ def __len__(self):
+ return 42
+
+class Hashable(Structure):
+ __hash__ = 42
+
+
+class Iterator(Structure):
+ def keys(self): # pylint: disable=no-self-use
+ return iter([1, 2, 3])
+
+ __iter__ = keys
+
+class AbstractSizable(Structure):
+ @abc.abstractmethod
+ def length(self):
+ pass
+ __len__ = length
+
+class NoMroAbstractMethods(Container, Iterator, Sizable, Hashable):
+ pass
+
+class BadMroAbstractMethods(Container, Iterator, AbstractSizable):
+ pass
+
+class SomeMetaclass(metaclass=abc.ABCMeta):
+
+ @abc.abstractmethod
+ def prop(self):
+ pass
+
+class FourthGoodClass(SomeMetaclass):
+ """Don't consider this abstract if some attributes are
+ there, but can't be inferred.
+ """
+ prop = Bala # missing
+
+
+def main():
+ """ do nothing """
+ GoodClass()
+ SecondGoodClass()
+ ThirdGoodClass()
+ FourthGoodClass()
+ weakref.WeakKeyDictionary()
+ weakref.WeakValueDictionary()
+ NoMroAbstractMethods()
+
+ BadMroAbstractMethods() # [abstract-class-instantiated]
+ BadClass() # [abstract-class-instantiated]
+ SecondBadClass() # [abstract-class-instantiated]
+ ThirdBadClass() # [abstract-class-instantiated]
+
+
+if 1: # pylint: disable=using-constant-test
+ class FourthBadClass(object, metaclass=abc.ABCMeta):
+
+ def test(self):
+ pass
+else:
+ class FourthBadClass(object, metaclass=abc.ABCMeta):
+
+ @abc.abstractmethod
+ def test(self):
+ pass
+
+
+def main2():
+ FourthBadClass() # [abstract-class-instantiated]
+
+
+class BadClassTwo(abc.ABC):
+ """
+ Check that instantiating a class with `abc.ABCMeta` as ancestor fails if it
+ defines abstract methods.
+ """
+ @abc.abstractmethod
+ def test(self):
+ pass
+
+
+def main_two():
+ """ do nothing """
+ BadClassTwo() # [abstract-class-instantiated]