Skip to content

Commit

Permalink
fix?: recursion error on Sanic subclass initialisation (#2072)
Browse files Browse the repository at this point in the history
* fix?: recursion error on Sanic subclass init

* tests: add test case for sanic subclass initialisation

* Remove BaseSanic metaclass

Co-authored-by: Adam Hopkins <[email protected]>
  • Loading branch information
artcg and ahopkins authored Mar 21, 2021
1 parent 15a8b5c commit 6763e2b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 23 deletions.
27 changes: 4 additions & 23 deletions sanic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,19 @@
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}>"

Expand Down
1 change: 1 addition & 0 deletions sanic/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def __init__(
version: Optional[int] = None,
strict_slashes: Optional[bool] = None,
):
super().__init__()

self._apps: Set[Sanic] = set()
self.ctx = SimpleNamespace()
Expand Down
7 changes: 7 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

0 comments on commit 6763e2b

Please sign in to comment.