Skip to content
Snippets Groups Projects
Commit 808af992 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

exceptions fixed

parent 85d13eee
No related branches found
Tags v2.5.9
No related merge requests found
......@@ -36,6 +36,33 @@ Example:
assert isinstance(BaseCodedError('message', 2', Code2Error)
The exceptions have to be in a common hierarchy to check them via
codes.
For example, the following is true:
::
class DifferentHierarchy(CodedCustomException):
pass
assert not isinstance(DifferentHierarchy('message', 2), Code2Error)
In general, please do not construct direct exceptions from CodedCustomException,
please do it via a hierarchy such as:
::
class GenericError(CodedCustomException):
pass
class SpecificError(GenericError):
code = 3
raise SpecificError('message')
Note that this won't allow you to handle exceptions like that
::
......
......@@ -39,6 +39,13 @@ class CustomException(Exception):
return a
def get_base_of_bases(classes):
class_bases = ()
for class_ in classes:
class_bases += class_.__bases__
return class_bases
class CodedCustomExceptionMetaclass(type):
code = None # type: tp.Optional[tp.Any]
......@@ -46,6 +53,21 @@ class CodedCustomExceptionMetaclass(type):
if super().__instancecheck__(instance):
return True
if cls is CodedCustomException:
return super().__instancecheck__(cls, instance)
class_base = (cls, )
while CodedCustomException not in get_base_of_bases(class_base) and class_base:
class_base = get_base_of_bases(class_base)
inst_base = (instance.__class__, )
while CodedCustomException not in get_base_of_bases(inst_base) and inst_base:
inst_base = get_base_of_bases(inst_base)
if len(set(class_base).intersection(set(inst_base))) == 0:
# These classes belong in different exception hierarchies
return False
try:
return cls.code == instance.code
except AttributeError:
......
......@@ -22,13 +22,19 @@ class TestExceptions(unittest.TestCase):
self.fail()
def test_coded_exception(self):
class Base2Error(CodedCustomException):
code = 2
class BaseError(CodedCustomException):
pass
exc = CodedCustomException('message', 2)
self.assertIsInstance(exc, Base2Error)
class Base2Error(BaseError):
code = 2
exc = Base2Error('message')
self.assertIsInstance(BaseError('message', 2), CodedCustomException)
self.assertIsInstance(Base2Error('message'), CodedCustomException)
self.assertNotIsInstance(CodedCustomException('message', 2), Base2Error)
self.assertIsInstance(BaseError('message', 2), Base2Error)
self.assertIsInstance(Base2Error('message'), Base2Error)
self.assertIsInstance(exc, Base2Error)
class DifferentHierarchy(CodedCustomException):
pass
self.assertNotIsInstance(DifferentHierarchy('message', 2), Base2Error)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment