Repository: bokeh/bokeh

Issue:
Bokeh cannot serve notebooks on Python 2
Using a notebook containing a single code cell (simply  `1+1`) in a Python 2 environment: 

`bokeh serve --show Test.ipynb`

Results in the following error:

```
SyntaxError: encoding declaration in Unicode string
```

Note that this is why the unit tests added in #8546 skip for Python 2.





Discussion:
This issue is primarily to serve as documentation. I am not averse to considering a PR from anyone interested in contributing a fix for Python 2. However, given the BEP-5 plans for dropping Python 2 support later this year, it is not a priority for @bokeh/core, so I'm closing as `wontfix`. (Can re-open if/when a PR appears)

Resolving patch:
diff --git a/bokeh/application/handlers/notebook.py b/bokeh/application/handlers/notebook.py
--- a/bokeh/application/handlers/notebook.py
+++ b/bokeh/application/handlers/notebook.py
@@ -22,6 +22,7 @@
 from __future__ import absolute_import, division, print_function, unicode_literals
 
 import re
+import sys
 import logging
 log = logging.getLogger(__name__)
 
@@ -122,6 +123,9 @@ def __call__(self, nb, resources):
 
             source, _ = exporter.from_notebook_node(nb)
             source = source.replace('get_ipython().run_line_magic', '')
+            source = source.replace('get_ipython().magic', '')
+            if sys.version_info.major == 2:
+                source = source.replace('# coding: utf-8','')
             kwargs['source'] = source
 
         super(NotebookHandler, self).__init__(*args, **kwargs)


Test patch:
diff --git a/bokeh/application/handlers/tests/test_notebook.py b/bokeh/application/handlers/tests/test_notebook.py
--- a/bokeh/application/handlers/tests/test_notebook.py
+++ b/bokeh/application/handlers/tests/test_notebook.py
@@ -12,6 +12,7 @@
 
 import pytest ; pytest
 
+import sys
 #-----------------------------------------------------------------------------
 # Imports
 #-----------------------------------------------------------------------------
@@ -19,7 +20,6 @@
 # Standard library imports
 
 # External imports
-import six
 from packaging import version
 import nbformat
 import nbconvert
@@ -56,7 +56,6 @@ class Test_NotebookHandler(object):
 
     # Public methods ----------------------------------------------------------
 
-    @pytest.mark.skipif(six.PY2, reason="this test doesn't work on Python 2 due to unicode literals")
     def test_runner_strips_line_magics(self):
         doc = Document()
         source = nbformat.v4.new_notebook()
@@ -68,7 +67,6 @@ def load(filename):
 
         with_script_contents(source, load)
 
-    @pytest.mark.skipif(six.PY2, reason="this test doesn't work on Python 2 due to unicode literals")
     def test_runner_strips_cell_magics(self):
         doc = Document()
         source = nbformat.v4.new_notebook()
@@ -94,9 +92,14 @@ def load(filename):
 
         assert result['handler']._runner.path == result['filename']
         if version.parse(nbconvert.__version__) < version.parse("5.4"):
-            assert result['handler']._runner.source == "\n# coding: utf-8\n"
+            expected_source = "\n# coding: utf-8\n"
         else:
-            assert result['handler']._runner.source == "#!/usr/bin/env python\n# coding: utf-8\n"
+            expected_source = "#!/usr/bin/env python\n# coding: utf-8\n"
+
+        if sys.version_info.major == 2:
+            expected_source = expected_source.replace('# coding: utf-8','')
+
+        assert result['handler']._runner.source == expected_source
         assert not doc.roots
 
     def test_missing_filename_raises(self):