fix?: recursion error on Sanic subclass initialisation (#2072)
* fix?: recursion error on Sanic subclass init * tests: add test case for sanic subclass initialisation * Remove BaseSanic metaclass Co-authored-by: Adam Hopkins <admhpkns@gmail.com>
This commit is contained in:
parent
15a8b5c894
commit
6763e2bb0a
@ -8,38 +8,19 @@ from sanic.mixins.routes import RouteMixin
|
|||||||
from sanic.mixins.signals import SignalMixin
|
from sanic.mixins.signals import SignalMixin
|
||||||
|
|
||||||
|
|
||||||
class Base(type):
|
|
||||||
def __new__(cls, name, bases, attrs):
|
|
||||||
init = attrs.get("__init__")
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
nonlocal init
|
|
||||||
nonlocal name
|
|
||||||
|
|
||||||
bases = [
|
|
||||||
b for base in type(self).__bases__ for b in base.__bases__
|
|
||||||
]
|
|
||||||
|
|
||||||
for base in bases:
|
|
||||||
base.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
if init:
|
|
||||||
init(self, *args, **kwargs)
|
|
||||||
|
|
||||||
attrs["__init__"] = __init__
|
|
||||||
return type.__new__(cls, name, bases, attrs)
|
|
||||||
|
|
||||||
|
|
||||||
class BaseSanic(
|
class BaseSanic(
|
||||||
RouteMixin,
|
RouteMixin,
|
||||||
MiddlewareMixin,
|
MiddlewareMixin,
|
||||||
ListenerMixin,
|
ListenerMixin,
|
||||||
ExceptionMixin,
|
ExceptionMixin,
|
||||||
SignalMixin,
|
SignalMixin,
|
||||||
metaclass=Base,
|
|
||||||
):
|
):
|
||||||
__fake_slots__: Tuple[str, ...]
|
__fake_slots__: Tuple[str, ...]
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
for base in BaseSanic.__bases__:
|
||||||
|
base.__init__(self, *args, **kwargs) # type: ignore
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<{self.__class__.__name__} {self.name}>"
|
return f"<{self.__class__.__name__} {self.name}>"
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ class Blueprint(BaseSanic):
|
|||||||
version: Optional[int] = None,
|
version: Optional[int] = None,
|
||||||
strict_slashes: Optional[bool] = None,
|
strict_slashes: Optional[bool] = None,
|
||||||
):
|
):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
self._apps: Set[Sanic] = set()
|
self._apps: Set[Sanic] = set()
|
||||||
self.ctx = SimpleNamespace()
|
self.ctx = SimpleNamespace()
|
||||||
|
@ -405,3 +405,10 @@ def test_app_set_context(app):
|
|||||||
|
|
||||||
retrieved = Sanic.get_app(app.name)
|
retrieved = Sanic.get_app(app.name)
|
||||||
assert retrieved.ctx.foo == 1
|
assert retrieved.ctx.foo == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_subclass_initialisation():
|
||||||
|
class CustomSanic(Sanic):
|
||||||
|
pass
|
||||||
|
|
||||||
|
CustomSanic("test_subclass_initialisation")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user