prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  RoutablePage throws a TypeError if index route is not set
  RoutablePage should not raise TypeError if index route is not set. 
  
  [route method](https://github.com/torchbox/wagtail/blob/master/wagtail/contrib/wagtailroutablepage/models.py#L97) properly calls parent class method if route is not found, but `serve` method has different signature, so it fails.
  
  There is also a discussion of similar issue on Google groups:
  https://groups.google.com/forum/#!msg/wagtail/Q9FymA-MOxM/1UkQ0hRGAAAJ
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `wagtail/contrib/wagtailroutablepage/models.py`
  Content:
  ```
  1 from __future__ import absolute_import, unicode_literals
  2 
  3 from django.conf.urls import url
  4 from django.core.urlresolvers import RegexURLResolver
  5 from django.http import Http404
  6 
  7 from wagtail.wagtailcore.models import Page
  8 from wagtail.wagtailcore.url_routing import RouteResult
  9 
  10 _creation_counter = 0
  11 
  12 
  13 def route(pattern, name=None):
  14     def decorator(view_func):
  15         global _creation_counter
  16         _creation_counter += 1
  17 
  18         # Make sure page has _routablepage_routes attribute
  19         if not hasattr(view_func, '_routablepage_routes'):
  20             view_func._routablepage_routes = []
  21 
  22         # Add new route to view
  23         view_func._routablepage_routes.append((
  24             url(pattern, view_func, name=(name or view_func.__name__)),
  25             _creation_counter,
  26         ))
  27 
  28         return view_func
  29 
  30     return decorator
  31 
  32 
  33 class RoutablePageMixin(object):
  34     """
  35     This class can be mixed in to a Page model, allowing extra routes to be
  36     added to it.
  37     """
  38     #: Set this to a tuple of ``django.conf.urls.url`` objects.
  39     subpage_urls = None
  40 
  41     @classmethod
  42     def get_subpage_urls(cls):
  43         routes = []
  44         for attr in dir(cls):
  45             val = getattr(cls, attr)
  46             if hasattr(val, '_routablepage_routes'):
  47                 routes.extend(val._routablepage_routes)
  48 
  49         return tuple([
  50             route[0]
  51             for route in sorted(routes, key=lambda route: route[1])
  52         ])
  53 
  54     @classmethod
  55     def get_resolver(cls):
  56         if '_routablepage_urlresolver' not in cls.__dict__:
  57             subpage_urls = cls.get_subpage_urls()
  58             cls._routablepage_urlresolver = RegexURLResolver(r'^/', subpage_urls)
  59 
  60         return cls._routablepage_urlresolver
  61 
  62     def reverse_subpage(self, name, args=None, kwargs=None):
  63         """
  64         This method takes a route name/arguments and returns a URL path.
  65         """
  66         args = args or []
  67         kwargs = kwargs or {}
  68 
  69         return self.get_resolver().reverse(name, *args, **kwargs)
  70 
  71     def resolve_subpage(self, path):
  72         """
  73         This method takes a URL path and finds the view to call.
  74         """
  75         view, args, kwargs = self.get_resolver().resolve(path)
  76 
  77         # Bind the method
  78         view = view.__get__(self, type(self))
  79 
  80         return view, args, kwargs
  81 
  82     def route(self, request, path_components):
  83         """
  84         This hooks the subpage URLs into Wagtail's routing.
  85         """
  86         if self.live:
  87             try:
  88                 path = '/'
  89                 if path_components:
  90                     path += '/'.join(path_components) + '/'
  91 
  92                 view, args, kwargs = self.resolve_subpage(path)
  93                 return RouteResult(self, args=(view, args, kwargs))
  94             except Http404:
  95                 pass
  96 
  97         return super(RoutablePageMixin, self).route(request, path_components)
  98 
  99     def serve(self, request, view, args, kwargs):
  100         return view(request, *args, **kwargs)
  101 
  102     def serve_preview(self, request, mode_name):
  103         view, args, kwargs = self.resolve_subpage('/')
  104         return view(request, *args, **kwargs)
  105 
  106 
  107 class RoutablePage(RoutablePageMixin, Page):
  108     """
  109     This class extends Page by adding methods which allows extra routes to be
  110     added to it.
  111     """
  112 
  113     class Meta:
  114         abstract = True
  115
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/wagtail/contrib/wagtailroutablepage/models.py b/wagtail/contrib/wagtailroutablepage/models.py
  --- a/wagtail/contrib/wagtailroutablepage/models.py
  +++ b/wagtail/contrib/wagtailroutablepage/models.py
  @@ -96,7 +96,13 @@
   
           return super(RoutablePageMixin, self).route(request, path_components)
   
  -    def serve(self, request, view, args, kwargs):
  +    def serve(self, request, view=None, args=None, kwargs=None):
  +        if args is None:
  +            args = []
  +        if kwargs is None:
  +            kwargs = {}
  +        if view is None:
  +            return super(RoutablePageMixin, self).serve(request, *args, **kwargs)
           return view(request, *args, **kwargs)
   
       def serve_preview(self, request, mode_name):
  
verification_info: {"golden_diff": "diff --git a/wagtail/contrib/wagtailroutablepage/models.py b/wagtail/contrib/wagtailroutablepage/models.py\n--- a/wagtail/contrib/wagtailroutablepage/models.py\n+++ b/wagtail/contrib/wagtailroutablepage/models.py\n@@ -96,7 +96,13 @@\n \n         return super(RoutablePageMixin, self).route(request, path_components)\n \n-    def serve(self, request, view, args, kwargs):\n+    def serve(self, request, view=None, args=None, kwargs=None):\n+        if args is None:\n+            args = []\n+        if kwargs is None:\n+            kwargs = {}\n+        if view is None:\n+            return super(RoutablePageMixin, self).serve(request, *args, **kwargs)\n         return view(request, *args, **kwargs)\n \n     def serve_preview(self, request, mode_name):\n", "issue": "RoutablePage throws a TypeError if index route is not set\nRoutablePage should not raise TypeError if index route is not set. \n\n[route method](https://github.com/torchbox/wagtail/blob/master/wagtail/contrib/wagtailroutablepage/models.py#L97) properly calls parent class method if route is not found, but `serve` method has different signature, so it fails.\n\nThere is also a discussion of similar issue on Google groups:\nhttps://groups.google.com/forum/#!msg/wagtail/Q9FymA-MOxM/1UkQ0hRGAAAJ\n\n", "before_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom django.conf.urls import url\nfrom django.core.urlresolvers import RegexURLResolver\nfrom django.http import Http404\n\nfrom wagtail.wagtailcore.models import Page\nfrom wagtail.wagtailcore.url_routing import RouteResult\n\n_creation_counter = 0\n\n\ndef route(pattern, name=None):\n    def decorator(view_func):\n        global _creation_counter\n        _creation_counter += 1\n\n        # Make sure page has _routablepage_routes attribute\n        if not hasattr(view_func, '_routablepage_routes'):\n            view_func._routablepage_routes = []\n\n        # Add new route to view\n        view_func._routablepage_routes.append((\n            url(pattern, view_func, name=(name or view_func.__name__)),\n            _creation_counter,\n        ))\n\n        return view_func\n\n    return decorator\n\n\nclass RoutablePageMixin(object):\n    \"\"\"\n    This class can be mixed in to a Page model, allowing extra routes to be\n    added to it.\n    \"\"\"\n    #: Set this to a tuple of ``django.conf.urls.url`` objects.\n    subpage_urls = None\n\n    @classmethod\n    def get_subpage_urls(cls):\n        routes = []\n        for attr in dir(cls):\n            val = getattr(cls, attr)\n            if hasattr(val, '_routablepage_routes'):\n                routes.extend(val._routablepage_routes)\n\n        return tuple([\n            route[0]\n            for route in sorted(routes, key=lambda route: route[1])\n        ])\n\n    @classmethod\n    def get_resolver(cls):\n        if '_routablepage_urlresolver' not in cls.__dict__:\n            subpage_urls = cls.get_subpage_urls()\n            cls._routablepage_urlresolver = RegexURLResolver(r'^/', subpage_urls)\n\n        return cls._routablepage_urlresolver\n\n    def reverse_subpage(self, name, args=None, kwargs=None):\n        \"\"\"\n        This method takes a route name/arguments and returns a URL path.\n        \"\"\"\n        args = args or []\n        kwargs = kwargs or {}\n\n        return self.get_resolver().reverse(name, *args, **kwargs)\n\n    def resolve_subpage(self, path):\n        \"\"\"\n        This method takes a URL path and finds the view to call.\n        \"\"\"\n        view, args, kwargs = self.get_resolver().resolve(path)\n\n        # Bind the method\n        view = view.__get__(self, type(self))\n\n        return view, args, kwargs\n\n    def route(self, request, path_components):\n        \"\"\"\n        This hooks the subpage URLs into Wagtail's routing.\n        \"\"\"\n        if self.live:\n            try:\n                path = '/'\n                if path_components:\n                    path += '/'.join(path_components) + '/'\n\n                view, args, kwargs = self.resolve_subpage(path)\n                return RouteResult(self, args=(view, args, kwargs))\n            except Http404:\n                pass\n\n        return super(RoutablePageMixin, self).route(request, path_components)\n\n    def serve(self, request, view, args, kwargs):\n        return view(request, *args, **kwargs)\n\n    def serve_preview(self, request, mode_name):\n        view, args, kwargs = self.resolve_subpage('/')\n        return view(request, *args, **kwargs)\n\n\nclass RoutablePage(RoutablePageMixin, Page):\n    \"\"\"\n    This class extends Page by adding methods which allows extra routes to be\n    added to it.\n    \"\"\"\n\n    class Meta:\n        abstract = True\n", "path": "wagtail/contrib/wagtailroutablepage/models.py"}], "after_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom django.conf.urls import url\nfrom django.core.urlresolvers import RegexURLResolver\nfrom django.http import Http404\n\nfrom wagtail.wagtailcore.models import Page\nfrom wagtail.wagtailcore.url_routing import RouteResult\n\n_creation_counter = 0\n\n\ndef route(pattern, name=None):\n    def decorator(view_func):\n        global _creation_counter\n        _creation_counter += 1\n\n        # Make sure page has _routablepage_routes attribute\n        if not hasattr(view_func, '_routablepage_routes'):\n            view_func._routablepage_routes = []\n\n        # Add new route to view\n        view_func._routablepage_routes.append((\n            url(pattern, view_func, name=(name or view_func.__name__)),\n            _creation_counter,\n        ))\n\n        return view_func\n\n    return decorator\n\n\nclass RoutablePageMixin(object):\n    \"\"\"\n    This class can be mixed in to a Page model, allowing extra routes to be\n    added to it.\n    \"\"\"\n    #: Set this to a tuple of ``django.conf.urls.url`` objects.\n    subpage_urls = None\n\n    @classmethod\n    def get_subpage_urls(cls):\n        routes = []\n        for attr in dir(cls):\n            val = getattr(cls, attr)\n            if hasattr(val, '_routablepage_routes'):\n                routes.extend(val._routablepage_routes)\n\n        return tuple([\n            route[0]\n            for route in sorted(routes, key=lambda route: route[1])\n        ])\n\n    @classmethod\n    def get_resolver(cls):\n        if '_routablepage_urlresolver' not in cls.__dict__:\n            subpage_urls = cls.get_subpage_urls()\n            cls._routablepage_urlresolver = RegexURLResolver(r'^/', subpage_urls)\n\n        return cls._routablepage_urlresolver\n\n    def reverse_subpage(self, name, args=None, kwargs=None):\n        \"\"\"\n        This method takes a route name/arguments and returns a URL path.\n        \"\"\"\n        args = args or []\n        kwargs = kwargs or {}\n\n        return self.get_resolver().reverse(name, *args, **kwargs)\n\n    def resolve_subpage(self, path):\n        \"\"\"\n        This method takes a URL path and finds the view to call.\n        \"\"\"\n        view, args, kwargs = self.get_resolver().resolve(path)\n\n        # Bind the method\n        view = view.__get__(self, type(self))\n\n        return view, args, kwargs\n\n    def route(self, request, path_components):\n        \"\"\"\n        This hooks the subpage URLs into Wagtail's routing.\n        \"\"\"\n        if self.live:\n            try:\n                path = '/'\n                if path_components:\n                    path += '/'.join(path_components) + '/'\n\n                view, args, kwargs = self.resolve_subpage(path)\n                return RouteResult(self, args=(view, args, kwargs))\n            except Http404:\n                pass\n\n        return super(RoutablePageMixin, self).route(request, path_components)\n\n    def serve(self, request, view=None, args=None, kwargs=None):\n        if args is None:\n            args = []\n        if kwargs is None:\n            kwargs = {}\n        if view is None:\n            return super(RoutablePageMixin, self).serve(request, *args, **kwargs)\n        return view(request, *args, **kwargs)\n\n    def serve_preview(self, request, mode_name):\n        view, args, kwargs = self.resolve_subpage('/')\n        return view(request, *args, **kwargs)\n\n\nclass RoutablePage(RoutablePageMixin, Page):\n    \"\"\"\n    This class extends Page by adding methods which allows extra routes to be\n    added to it.\n    \"\"\"\n\n    class Meta:\n        abstract = True\n", "path": "wagtail/contrib/wagtailroutablepage/models.py"}]}