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

little change to try to init the registry on module loading #3

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3"]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3", "3.11-dev"]
steps:
- uses: "actions/checkout@v2"
- uses: "actions/setup-python@v2"
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ default_language_version:
python: python3
repos:
- repo: https://github.com/psf/black
rev: 21.12b0
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/myint/autoflake
Expand Down
14 changes: 9 additions & 5 deletions src/extendable/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class ExtendableMeta(ABCMeta):

@no_type_check
def __new__(metacls, name, bases, namespace, extends=None, **kwargs):
"""create the expected class anc collect the class definition that will be used
"""create the expected class and collect the class definition that will be used
at the end of registry load process to build the final class."""
class_def = None
if not _registry_build_mode:
Expand All @@ -94,12 +94,16 @@ def __new__(metacls, name, bases, namespace, extends=None, **kwargs):
# for the original class, we wrap the class methods to forward
# the call to the aggregated one at runtime
namespace = metacls._wrap_class_methods(namespace)
# We build the Origial class
# We build the original class
new_cls = metacls._build_original_class(
name=name, bases=bases, namespace=namespace, **kwargs
)
if not _registry_build_mode and class_def:
class_def.original_cls = new_cls
if False:
registry = extendable_registry.get()
with registry.build_mode():
extendable_registry.get().build_extendable_class(class_def)
return new_cls

@no_type_check
Expand Down Expand Up @@ -134,6 +138,8 @@ def _collect_class_def(metacls, name, bases, namespace, extends=None, **kwargs):
# For each defined Extendable class, we keep a copy of the class
# definition. This copy will be used to create the aggregated class
other_bases = [b for b in bases if not metacls._is_extendable(b)]
# namespace = dict(namespace)
# namespace.pop("__classcell__", None)
cls_def = ExtendableClassDef(
original_name=name,
bases=tuple(other_bases),
Expand All @@ -156,9 +162,7 @@ def _build_original_class(metacls, name, bases, namespace, **kwargs):
another type. In such a case, the new type should only override
this method to call the __new__ method on the other type.
"""
return super().__new__(
metacls, name=name, bases=bases, namespace=namespace, **kwargs
)
return super().__new__(metacls, name, bases, namespace, **kwargs)

@classmethod
def _wrap_class_methods(metacls, namespace: Dict[str, Any]) -> Dict[str, Any]:
Expand Down
1 change: 1 addition & 0 deletions src/extendable/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def init_registry(self, module_matchings: Optional[List[str]] = None) -> None:

The module list accept wildcard expression as last character
"""
self._extendable_classes.clear()
module_matchings = module_matchings if module_matchings else ["*"]
with self.build_mode(), ModuleIndex() as idx:
for match in module_matchings:
Expand Down
47 changes: 47 additions & 0 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,53 @@ def cls_sum(cls) -> int:
assert isinstance(result.__class__, ExtendableMeta)


def test_simple_extends_same_class(test_registry):
class A(metaclass=ExtendableMeta):
prop_a: int = 1

def sum(self) -> int:
return self.prop_a

@classmethod
def cls_sum(cls) -> int:
return 2

class B(A, extends=A):
prop_b: int = 2

def sum(self) -> int:
s = super()
return s.sum() + self.prop_b

@classmethod
def cls_sum(cls) -> int:
return super().cls_sum() + 3

class C(A, extends=A):
prop_c: int = 3

def sum(self) -> int:
s = super()
return s.sum() + self.prop_c

@classmethod
def cls_sum(cls) -> int:
return super().cls_sum() + 4

test_registry.init_registry()

result: Union[A, B, C] = A()
assert isinstance(result, A)
assert isinstance(result, B)
assert isinstance(result, C)
assert result.prop_c == 3
assert result.prop_b == 2
assert result.prop_a == 1
assert result.sum() == 6
assert A.cls_sum() == 9
assert isinstance(result.__class__, ExtendableMeta)


def test_extends_new_model(test_registry):
class A(metaclass=ExtendableMeta):
value: int = 2
Expand Down
2 changes: 2 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ python =
3.8: py38, typing
3.9: py39, typing, pypi-description
3.10: py310, typing
3.11: py311, typing
pypy3: pypy3

[tox]
Expand All @@ -15,6 +16,7 @@ envlist =
py38
py39
py310
py311
pypy3
lint
typing
Expand Down