Skip to content

Commit

Permalink
Merge pull request #14 from lmignon/master-fix-isinstance
Browse files Browse the repository at this point in the history
Fix isinstance and issublcass method on multi levels inheritance hier…
  • Loading branch information
lmignon authored Sep 19, 2023
2 parents 0f2e42a + fc099d0 commit fcfe080
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions news/isinstance.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix isinstance and issublcass method on multi levels inheritance hierarchy.
3 changes: 3 additions & 0 deletions src/extendable/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ def __subclasscheck__(cls, subclass: Any) -> bool: # noqa: B902
"""Implement issubclass(sub, cls)."""
if hasattr(subclass, "__xreg_all_base_names__"):
return cls.__xreg_name__ in subclass.__xreg_all_base_names__
if hasattr(subclass, "__xreg_name__"):
_subclass = subclass._get_assembled_cls()
return issubclass(_subclass, cls)
return isinstance(subclass, type) and super().__subclasscheck__(subclass)

def _get_assembled_cls(
Expand Down
5 changes: 4 additions & 1 deletion src/extendable/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def build_extendable_class(
self, class_def: main.ExtendableClassDef
) -> main.ExtendableMeta:
"""Build the class hierarchy from the first one to the last one into the
hierachy definition."""
hierarchy definition."""
name = class_def.name
for idx, cls_def in enumerate(class_def.hierarchy):
# retrieve extendable_parent
Expand Down Expand Up @@ -153,6 +153,9 @@ def build_extendable_class(
base = cast(main.ExtendableMeta, extendableClass)
self[name] = base
base.__xreg_all_base_names__ = set(class_def.base_names)
for _base in bases:
if hasattr(_base, "__xreg_all_base_names__"):
base.__xreg_all_base_names__ |= _base.__xreg_all_base_names__
return base

@contextmanager
Expand Down
46 changes: 46 additions & 0 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,49 @@ class MyExt(metaclass=MyMeta):
pass

assert MyMeta._is_extendable(MyExt)


def test_issubclass_multi_level(test_registry):
class A(metaclass=ExtendableMeta):
pass

class B(A):
pass

class C(B):
pass

test_registry.init_registry()

assert issubclass(C, B)
assert issubclass(C().__class__, B)
assert issubclass(C().__class__, B().__class__)
assert issubclass(C, B().__class__)
assert issubclass(C, A)
assert issubclass(C().__class__, A)
assert issubclass(C, A().__class__)
assert issubclass(C().__class__, A().__class__)
assert issubclass(B, A)
assert issubclass(B().__class__, A)
assert issubclass(B().__class__, A().__class__)
assert issubclass(B, A().__class__)


def test_isinstance_multi_level(test_registry):
class A(metaclass=ExtendableMeta):
pass

class B(A):
pass

class C(B):
pass

test_registry.init_registry()

assert isinstance(C(), B)
assert isinstance(C(), B().__class__)
assert isinstance(C(), A)
assert isinstance(C(), A().__class__)
assert isinstance(B(), A)
assert isinstance(B(), A().__class__)

0 comments on commit fcfe080

Please sign in to comment.