Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#4): collect all errors #5

Merged
merged 2 commits into from
Sep 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 12 additions & 5 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,16 @@ jobs:
pylint --disable=consider-using-f-string abcmeta/
- name: Test
run: |
TEST_1="AttributeError: Derived class 'ABCDerived' has not implemented 'method_1' method of the parent class 'ABCParent'"
TEST_2="Derived method expected to get 3 parameters but gets 2"
TEST_3="Derived method expected to get 'name:<class 'str'>' paramter's type, but gets 'name:<class 'int'>'"
TEST_4="Derived method expected to get 'name' paramter, but gets 'family'"
TEST_5="Derived method expected to return in 'typing.Dict[str, str]' type, but returns 'typing.Dict[str, int]'"
TEST_MULTI="$TEST_1\|Derived method expected to get 'name:<class 'str'>' paramter's type, but gets 'name:<class 'int'>'\|$TEST_4"
PYTHONPATH=. python tests/correct_class_test.py
PYTHONPATH=. python tests/incorrect_class_1_test.py |& grep -F "AttributeError: Derived class 'ABCDerived' has not implemented 'method_1' method of the parent class 'ABCParent'"
PYTHONPATH=. python tests/incorrect_class_2_test.py |& grep -F "Derived method expected to get 3 parameters but gets 2"
PYTHONPATH=. python tests/incorrect_class_3_test.py |& grep -F "Derived method expected to get 'name:<class 'str'>' paramter's type, but gets 'name:<class 'int'>'"
PYTHONPATH=. python tests/incorrect_class_4_test.py |& grep -F "Derived method expected to get 'name' paramter, but gets 'family'"
PYTHONPATH=. python tests/incorrect_class_5_test.py |& grep -F "Derived method expected to return in 'typing.Dict[str, str]' type, but returns 'typing.Dict[str, int]'"
PYTHONPATH=. python tests/incorrect_class_1_test.py |& grep -F $TEST_1
PYTHONPATH=. python tests/incorrect_class_2_test.py |& grep -F $TEST_2
PYTHONPATH=. python tests/incorrect_class_3_test.py |& grep -F $TEST_3
PYTHONPATH=. python tests/incorrect_class_4_test.py |& grep -F $TEST_4
PYTHONPATH=. python tests/incorrect_class_5_test.py |& grep -F $TEST_5
PYTHONPATH=. python tests/multiple_incorrect_methods_test.py |& grep -cG $TEST_MULTI | grep 3
9 changes: 7 additions & 2 deletions abcmeta/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def __init_subclass__(cls):
"""Python built-in method."""
super().__init_subclass__()

errors = []
for name, obj in vars(cls.__base__).items():

# Ignore uncallable methods.
Expand All @@ -156,12 +157,13 @@ def __init_subclass__(cls):

# Make sure the derived class has implemented the abstract method.
if name not in cls.__dict__:
raise AttributeError(
errors.append(
"Derived class '{}' has not implemented '{}' method of the"
" parent class '{}'.".format(
cls.__name__, name, cls.__base__.__name__
)
)
continue

derived_method = getattr(cls, name)

Expand All @@ -181,7 +183,10 @@ def __init_subclass__(cls):
diff_details = _compare_signatures_details(
obj_method_signature, derived_method_signature
)
raise AttributeError(
errors.append(
"Signature of the derived method is not the same as parent"
" class:\r\n{}".format(_prepare_text_to_raise(diff, diff_details))
)

if errors:
raise AttributeError("\n\n".join(errors))
KyleKing marked this conversation as resolved.
Show resolved Hide resolved
35 changes: 35 additions & 0 deletions tests/multiple_incorrect_methods_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Test for abcmeta library.

Test for multiple errors.
"""
from typing import Dict, Text, Tuple

from abcmeta import ABC, abstractmethod


class ABCParent(ABC):
@abstractmethod
def method_1(self, name, age):
pass

@abstractmethod
def method_2(self, name: Text, age: int) -> Dict[Text, Text]:
"""Abstract method."""

def method_3(self):
pass

@abstractmethod
def method_4(self, name: Text, age: int) -> Tuple[Text, Text]:
"""Abstract method."""


class ABCDerived(ABCParent):
def method_(self, name, age): # Intentional typo (Same error as Test 1)
pass

def method_2(self, name: int, age: int) -> Dict[Text, Text]: # New
return {"name": "test"}

def method_4(self, family: Text, age: int) -> Tuple[Text, Text]: # Test 4
return ("name", "test")