We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IPython WebGL Examples not working.
The IPython notebook examples are not working with the latest IPython(Jupyter) 4.0 release.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `vispy/app/backends/ipython/_widget.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # Copyright (c) 2014, 2015, Vispy Development Team.
3 # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4 
5 try:
6     from IPython.html.widgets import DOMWidget
7     from IPython.utils.traitlets import Unicode, Int, Bool
8 except Exception as exp:
9     # Init dummy objects needed to import this module withour errors.
10     # These are all overwritten with imports from IPython (on success)
11     DOMWidget = object
12     Unicode = Int = Float = Bool = lambda *args, **kwargs: None
13     available, testable, why_not, which = False, False, str(exp), None
14 else:
15     available, testable, why_not, which = True, False, None, None
16 from vispy.app.backends._ipynb_util import create_glir_message
17 from vispy.app import Timer
18 
19 
20 # ---------------------------------------------------------- IPython Widget ---
21 def _stop_timers(canvas):
22     """Stop all timers in a canvas."""
23     for attr in dir(canvas):
24         try:
25             attr_obj = getattr(canvas, attr)
26         except NotImplementedError:
27             # This try/except is needed because canvas.position raises
28             # an error (it is not implemented in this backend).
29             attr_obj = None
30         if isinstance(attr_obj, Timer):
31             attr_obj.stop()
32 
33 
34 class VispyWidget(DOMWidget):
35     _view_name = Unicode("VispyView", sync=True)
36     _view_module = Unicode('/nbextensions/vispy/webgl-backend.js', sync=True)
37 
38     #height/width of the widget is managed by IPython.
39     #it's a string and can be anything valid in CSS.
40     #here we only manage the size of the viewport.
41     width = Int(sync=True)
42     height = Int(sync=True)
43     resizable = Bool(value=True, sync=True)
44 
45     def __init__(self, **kwargs):
46         super(VispyWidget, self).__init__(**kwargs)
47         self.on_msg(self.events_received)
48         self.canvas = None
49         self.canvas_backend = None
50         self.gen_event = None
51 
52     def set_canvas(self, canvas):
53         self.width, self.height = canvas._backend._default_size
54         self.canvas = canvas
55         self.canvas_backend = self.canvas._backend
56         self.canvas_backend.set_widget(self)
57         self.gen_event = self.canvas_backend._gen_event
58         #setup the backend widget then.
59 
60     def events_received(self, _, msg):
61         if msg['msg_type'] == 'init':
62             self.canvas_backend._reinit_widget()
63         elif msg['msg_type'] == 'events':
64             events = msg['contents']
65             for ev in events:
66                 self.gen_event(ev)
67         elif msg['msg_type'] == 'status':
68             if msg['contents'] == 'removed':
69                 # Stop all timers associated to the widget.
70                 _stop_timers(self.canvas_backend._vispy_canvas)
71 
72     def send_glir_commands(self, commands):
73         # TODO: check whether binary websocket is available (ipython >= 3)
74         # Until IPython 3.0 is released, use base64.
75         array_serialization = 'base64'
76         # array_serialization = 'binary'
77         if array_serialization == 'base64':
78             msg = create_glir_message(commands, 'base64')
79             msg['array_serialization'] = 'base64'
80             self.send(msg)
81         elif array_serialization == 'binary':
82             msg = create_glir_message(commands, 'binary')
83             msg['array_serialization'] = 'binary'
84             # Remove the buffers from the JSON message: they will be sent
85             # independently via binary WebSocket.
86             buffers = msg.pop('buffers')
87             self.comm.send({"method": "custom", "content": msg},
88                            buffers=buffers)
89
```
--- 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()

```

diff --git a/vispy/app/backends/ipython/_widget.py b/vispy/app/backends/ipython/_widget.py
--- a/vispy/app/backends/ipython/_widget.py
+++ b/vispy/app/backends/ipython/_widget.py
@@ -57,7 +57,10 @@
         self.gen_event = self.canvas_backend._gen_event
         #setup the backend widget then.
 
-    def events_received(self, _, msg):
+    # In IPython < 4, these callbacks are given two arguments; in
+    # IPython/jupyter 4, they take 3. events_received is variadic to
+    # accommodate both cases.
+    def events_received(self, _, msg, *args):
         if msg['msg_type'] == 'init':
             self.canvas_backend._reinit_widget()
         elif msg['msg_type'] == 'events':

{"golden_diff": "diff --git a/vispy/app/backends/ipython/_widget.py b/vispy/app/backends/ipython/_widget.py\n--- a/vispy/app/backends/ipython/_widget.py\n+++ b/vispy/app/backends/ipython/_widget.py\n@@ -57,7 +57,10 @@\n         self.gen_event = self.canvas_backend._gen_event\n         #setup the backend widget then.\n \n-    def events_received(self, _, msg):\n+    # In IPython < 4, these callbacks are given two arguments; in\n+    # IPython/jupyter 4, they take 3. events_received is variadic to\n+    # accommodate both cases.\n+    def events_received(self, _, msg, *args):\n         if msg['msg_type'] == 'init':\n             self.canvas_backend._reinit_widget()\n         elif msg['msg_type'] == 'events':\n", "issue": "IPython WebGL Examples not working.\nThe IPython notebook examples are not working with the latest IPython(Jupyter) 4.0 release.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014, 2015, Vispy Development Team.\n# Distributed under the (new) BSD License. See LICENSE.txt for more info.\n\ntry:\n    from IPython.html.widgets import DOMWidget\n    from IPython.utils.traitlets import Unicode, Int, Bool\nexcept Exception as exp:\n    # Init dummy objects needed to import this module withour errors.\n    # These are all overwritten with imports from IPython (on success)\n    DOMWidget = object\n    Unicode = Int = Float = Bool = lambda *args, **kwargs: None\n    available, testable, why_not, which = False, False, str(exp), None\nelse:\n    available, testable, why_not, which = True, False, None, None\nfrom vispy.app.backends._ipynb_util import create_glir_message\nfrom vispy.app import Timer\n\n\n# ---------------------------------------------------------- IPython Widget ---\ndef _stop_timers(canvas):\n    \"\"\"Stop all timers in a canvas.\"\"\"\n    for attr in dir(canvas):\n        try:\n            attr_obj = getattr(canvas, attr)\n        except NotImplementedError:\n            # This try/except is needed because canvas.position raises\n            # an error (it is not implemented in this backend).\n            attr_obj = None\n        if isinstance(attr_obj, Timer):\n            attr_obj.stop()\n\n\nclass VispyWidget(DOMWidget):\n    _view_name = Unicode(\"VispyView\", sync=True)\n    _view_module = Unicode('/nbextensions/vispy/webgl-backend.js', sync=True)\n\n    #height/width of the widget is managed by IPython.\n    #it's a string and can be anything valid in CSS.\n    #here we only manage the size of the viewport.\n    width = Int(sync=True)\n    height = Int(sync=True)\n    resizable = Bool(value=True, sync=True)\n\n    def __init__(self, **kwargs):\n        super(VispyWidget, self).__init__(**kwargs)\n        self.on_msg(self.events_received)\n        self.canvas = None\n        self.canvas_backend = None\n        self.gen_event = None\n\n    def set_canvas(self, canvas):\n        self.width, self.height = canvas._backend._default_size\n        self.canvas = canvas\n        self.canvas_backend = self.canvas._backend\n        self.canvas_backend.set_widget(self)\n        self.gen_event = self.canvas_backend._gen_event\n        #setup the backend widget then.\n\n    def events_received(self, _, msg):\n        if msg['msg_type'] == 'init':\n            self.canvas_backend._reinit_widget()\n        elif msg['msg_type'] == 'events':\n            events = msg['contents']\n            for ev in events:\n                self.gen_event(ev)\n        elif msg['msg_type'] == 'status':\n            if msg['contents'] == 'removed':\n                # Stop all timers associated to the widget.\n                _stop_timers(self.canvas_backend._vispy_canvas)\n\n    def send_glir_commands(self, commands):\n        # TODO: check whether binary websocket is available (ipython >= 3)\n        # Until IPython 3.0 is released, use base64.\n        array_serialization = 'base64'\n        # array_serialization = 'binary'\n        if array_serialization == 'base64':\n            msg = create_glir_message(commands, 'base64')\n            msg['array_serialization'] = 'base64'\n            self.send(msg)\n        elif array_serialization == 'binary':\n            msg = create_glir_message(commands, 'binary')\n            msg['array_serialization'] = 'binary'\n            # Remove the buffers from the JSON message: they will be sent\n            # independently via binary WebSocket.\n            buffers = msg.pop('buffers')\n            self.comm.send({\"method\": \"custom\", \"content\": msg},\n                           buffers=buffers)\n", "path": "vispy/app/backends/ipython/_widget.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright (c) 2014, 2015, Vispy Development Team.\n# Distributed under the (new) BSD License. See LICENSE.txt for more info.\n\ntry:\n    from IPython.html.widgets import DOMWidget\n    from IPython.utils.traitlets import Unicode, Int, Bool\nexcept Exception as exp:\n    # Init dummy objects needed to import this module withour errors.\n    # These are all overwritten with imports from IPython (on success)\n    DOMWidget = object\n    Unicode = Int = Float = Bool = lambda *args, **kwargs: None\n    available, testable, why_not, which = False, False, str(exp), None\nelse:\n    available, testable, why_not, which = True, False, None, None\nfrom vispy.app.backends._ipynb_util import create_glir_message\nfrom vispy.app import Timer\n\n\n# ---------------------------------------------------------- IPython Widget ---\ndef _stop_timers(canvas):\n    \"\"\"Stop all timers in a canvas.\"\"\"\n    for attr in dir(canvas):\n        try:\n            attr_obj = getattr(canvas, attr)\n        except NotImplementedError:\n            # This try/except is needed because canvas.position raises\n            # an error (it is not implemented in this backend).\n            attr_obj = None\n        if isinstance(attr_obj, Timer):\n            attr_obj.stop()\n\n\nclass VispyWidget(DOMWidget):\n    _view_name = Unicode(\"VispyView\", sync=True)\n    _view_module = Unicode('/nbextensions/vispy/webgl-backend.js', sync=True)\n\n    #height/width of the widget is managed by IPython.\n    #it's a string and can be anything valid in CSS.\n    #here we only manage the size of the viewport.\n    width = Int(sync=True)\n    height = Int(sync=True)\n    resizable = Bool(value=True, sync=True)\n\n    def __init__(self, **kwargs):\n        super(VispyWidget, self).__init__(**kwargs)\n        self.on_msg(self.events_received)\n        self.canvas = None\n        self.canvas_backend = None\n        self.gen_event = None\n\n    def set_canvas(self, canvas):\n        self.width, self.height = canvas._backend._default_size\n        self.canvas = canvas\n        self.canvas_backend = self.canvas._backend\n        self.canvas_backend.set_widget(self)\n        self.gen_event = self.canvas_backend._gen_event\n        #setup the backend widget then.\n\n    # In IPython < 4, these callbacks are given two arguments; in\n    # IPython/jupyter 4, they take 3. events_received is variadic to\n    # accommodate both cases.\n    def events_received(self, _, msg, *args):\n        if msg['msg_type'] == 'init':\n            self.canvas_backend._reinit_widget()\n        elif msg['msg_type'] == 'events':\n            events = msg['contents']\n            for ev in events:\n                self.gen_event(ev)\n        elif msg['msg_type'] == 'status':\n            if msg['contents'] == 'removed':\n                # Stop all timers associated to the widget.\n                _stop_timers(self.canvas_backend._vispy_canvas)\n\n    def send_glir_commands(self, commands):\n        # TODO: check whether binary websocket is available (ipython >= 3)\n        # Until IPython 3.0 is released, use base64.\n        array_serialization = 'base64'\n        # array_serialization = 'binary'\n        if array_serialization == 'base64':\n            msg = create_glir_message(commands, 'base64')\n            msg['array_serialization'] = 'base64'\n            self.send(msg)\n        elif array_serialization == 'binary':\n            msg = create_glir_message(commands, 'binary')\n            msg['array_serialization'] = 'binary'\n            # Remove the buffers from the JSON message: they will be sent\n            # independently via binary WebSocket.\n            buffers = msg.pop('buffers')\n            self.comm.send({\"method\": \"custom\", \"content\": msg},\n                           buffers=buffers)\n", "path": "vispy/app/backends/ipython/_widget.py"}]}