mirror of
https://github.com/avatao-content/baseimage-tutorial-framework
synced 2024-11-22 13:51:33 +00:00
Add metaclass capable of building instances from class name string
This commit is contained in:
parent
80eca7e322
commit
d9bcfb3705
@ -0,0 +1 @@
|
|||||||
|
from .type_id_registry import TypeIdREgistryMixin
|
@ -0,0 +1,43 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from .type_id_registry import TypeIdREgistryMixin
|
||||||
|
|
||||||
|
|
||||||
|
def test_registry():
|
||||||
|
class A(TypeIdREgistryMixin):
|
||||||
|
_type_id_registry = {}
|
||||||
|
class B(A):
|
||||||
|
pass
|
||||||
|
class C(A):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
assert A._type_id_registry['B'] == B
|
||||||
|
assert A._type_id_registry['C'] == C
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_by_type_id():
|
||||||
|
class D(TypeIdREgistryMixin):
|
||||||
|
_type_id_registry = {}
|
||||||
|
built = []
|
||||||
|
class E(D):
|
||||||
|
def __init__(self):
|
||||||
|
built.append(self)
|
||||||
|
class F(D):
|
||||||
|
def __init__(self):
|
||||||
|
built.append(self)
|
||||||
|
raise RuntimeError('cica')
|
||||||
|
class H(E):
|
||||||
|
pass
|
||||||
|
|
||||||
|
D.build_type('E')
|
||||||
|
assert isinstance(built[0], E)
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError) as err:
|
||||||
|
D.build_type('F')
|
||||||
|
assert err.value.args[0] == 'cica'
|
||||||
|
assert isinstance(built[1], F)
|
||||||
|
|
||||||
|
D.build_type('H')
|
||||||
|
assert isinstance(built[2], H)
|
||||||
|
assert isinstance(built[2], E)
|
@ -0,0 +1,21 @@
|
|||||||
|
from abc import ABCMeta
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
|
|
||||||
|
class TypeIdREgistryMeta(ABCMeta):
|
||||||
|
def __init__(cls, name, bases, attrs):
|
||||||
|
with suppress(AttributeError):
|
||||||
|
if cls.__name__ in cls._type_id_registry:
|
||||||
|
raise RuntimeError('Type id must be unique!')
|
||||||
|
cls._type_id_registry[cls.__name__] = cls
|
||||||
|
super().__init__(name, bases, attrs)
|
||||||
|
|
||||||
|
|
||||||
|
class TypeIdREgistryMixin(metaclass=TypeIdREgistryMeta):
|
||||||
|
@classmethod
|
||||||
|
def build_type(cls, type_id, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
instance_type = cls._type_id_registry[type_id]
|
||||||
|
return instance_type(*args, **kwargs)
|
||||||
|
except KeyError:
|
||||||
|
raise RuntimeError(f'No type with id {type_id}!')
|
Loading…
Reference in New Issue
Block a user