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:
Arthur Goldberg 2021-03-21 09:09:31 +01:00 committed by GitHub
parent 15a8b5c894
commit 6763e2bb0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 23 deletions

View File

@ -8,38 +8,19 @@ from sanic.mixins.routes import RouteMixin
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(
RouteMixin,
MiddlewareMixin,
ListenerMixin,
ExceptionMixin,
SignalMixin,
metaclass=Base,
):
__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:
return f"<{self.__class__.__name__} {self.name}>"

View File

@ -73,6 +73,7 @@ class Blueprint(BaseSanic):
version: Optional[int] = None,
strict_slashes: Optional[bool] = None,
):
super().__init__()
self._apps: Set[Sanic] = set()
self.ctx = SimpleNamespace()

View File

@ -405,3 +405,10 @@ def test_app_set_context(app):
retrieved = Sanic.get_app(app.name)
assert retrieved.ctx.foo == 1
def test_subclass_initialisation():
class CustomSanic(Sanic):
pass
CustomSanic("test_subclass_initialisation")