prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  DataTable crashes layout if 'field' is key in ColumnDataSource data
  Bokeh 0.13.0
  Mac OS 10.13.3
  python 2.7.10
  Safari 11.0.3
  
  If 'field' is a key in the data of ColumnDataSource, bokeh serve cannot generate a layout including a DataTable using this ColumnDataSource.  This only fails if the DataTable is in the layout, the DataTable may exist if not in the layout.
  
  The following code will fail.  If you replace 'field' in variables with almost anything else, the code works.
  
  ```
  from bokeh.models import ColumnDataSource
  from bokeh.models.widgets import TableColumn, DataTable
  from bokeh.io import curdoc
  from bokeh.layouts import column
  
  
  variables = ['x', 'y', 'field']
  source = ColumnDataSource(data={v: [i] for i, v in enumerate(variables)})
  table = DataTable(source=source, columns=[TableColumn(field=v, title=v) for v in variables])
  curdoc().add_root(column(table))
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `examples/models/file/donut.py`
  Content:
  ```
  1 from __future__ import print_function
  2 
  3 import base64
  4 from math import pi, sin, cos
  5 
  6 from bokeh.util.browser import view
  7 from bokeh.colors.named import skyblue, seagreen, tomato, orchid, firebrick, lightgray
  8 from bokeh.document import Document
  9 from bokeh.embed import file_html
  10 from bokeh.models.glyphs import Wedge, AnnularWedge, ImageURL, Text
  11 from bokeh.models import ColumnDataSource, Plot, Range1d
  12 from bokeh.resources import INLINE
  13 from bokeh.sampledata.browsers import browsers_nov_2013, icons
  14 
  15 df = browsers_nov_2013
  16 
  17 xdr = Range1d(start=-2, end=2)
  18 ydr = Range1d(start=-2, end=2)
  19 
  20 plot = Plot(x_range=xdr, y_range=ydr, plot_width=800, plot_height=800)
  21 plot.title.text = "Web browser market share (November 2013)"
  22 plot.toolbar_location = None
  23 
  24 colors = {"Chrome": seagreen, "Firefox": tomato, "Safari": orchid, "Opera": firebrick, "IE": skyblue, "Other": lightgray}
  25 
  26 aggregated = df.groupby("Browser").agg(sum)
  27 selected = aggregated[aggregated.Share >= 1].copy()
  28 selected.loc["Other"] = aggregated[aggregated.Share < 1].sum()
  29 browsers = selected.index.tolist()
  30 
  31 radians = lambda x: 2*pi*(x/100)
  32 angles = selected.Share.map(radians).cumsum()
  33 
  34 end_angles = angles.tolist()
  35 start_angles = [0] + end_angles[:-1]
  36 
  37 browsers_source = ColumnDataSource(dict(
  38     start  = start_angles,
  39     end    = end_angles,
  40     colors = [colors[browser] for browser in browsers ],
  41 ))
  42 
  43 glyph = Wedge(x=0, y=0, radius=1, line_color="white",
  44     line_width=2, start_angle="start", end_angle="end", fill_color="colors")
  45 plot.add_glyph(browsers_source, glyph)
  46 
  47 def polar_to_cartesian(r, start_angles, end_angles):
  48     cartesian = lambda r, alpha: (r*cos(alpha), r*sin(alpha))
  49     points = []
  50 
  51     for start, end in zip(start_angles, end_angles):
  52         points.append(cartesian(r, (end + start)/2))
  53 
  54     return zip(*points)
  55 
  56 first = True
  57 
  58 for browser, start_angle, end_angle in zip(browsers, start_angles, end_angles):
  59     versions = df[(df.Browser == browser) & (df.Share >= 0.5)]
  60     angles = versions.Share.map(radians).cumsum() + start_angle
  61     end = angles.tolist() + [end_angle]
  62     start = [start_angle] + end[:-1]
  63     base_color = colors[browser]
  64     fill = [ base_color.lighten(i*0.05) for i in range(len(versions) + 1) ]
  65     # extra empty string accounts for all versions with share < 0.5 together
  66     text = [ number if share >= 1 else "" for number, share in zip(versions.VersionNumber, versions.Share) ] + [""]
  67     x, y = polar_to_cartesian(1.25, start, end)
  68 
  69     source = ColumnDataSource(dict(start=start, end=end, fill=fill))
  70     glyph = AnnularWedge(x=0, y=0,
  71         inner_radius=1, outer_radius=1.5, start_angle="start", end_angle="end",
  72         line_color="white", line_width=2, fill_color="fill")
  73     plot.add_glyph(source, glyph)
  74 
  75 
  76     text_angle = [(start[i]+end[i])/2 for i in range(len(start))]
  77     text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]
  78 
  79     if first and text:
  80         text.insert(0, '(version)')
  81         offset = pi / 48
  82         text_angle.insert(0, text_angle[0] - offset)
  83         start.insert(0, start[0] - offset)
  84         end.insert(0, end[0] - offset)
  85         x, y = polar_to_cartesian(1.25, start, end)
  86         first = False
  87 
  88 
  89     text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))
  90     glyph = Text(x="x", y="y", text="text", angle="angle",
  91         text_align="center", text_baseline="middle", text_font_size="8pt")
  92     plot.add_glyph(text_source, glyph)
  93 
  94 
  95 def to_base64(png):
  96     return "data:image/png;base64," + base64.b64encode(png).decode("utf-8")
  97 
  98 urls = [ to_base64(icons.get(browser, b"")) for browser in browsers ]
  99 x, y = polar_to_cartesian(1.7, start_angles, end_angles)
  100 
  101 icons_source = ColumnDataSource(dict(urls=urls, x=x, y=y))
  102 glyph = ImageURL(url="urls", x="x", y="y", anchor="center")
  103 plot.add_glyph(icons_source, glyph)
  104 
  105 text = [ "%.02f%%" % value for value in selected.Share ]
  106 x, y = polar_to_cartesian(0.7, start_angles, end_angles)
  107 
  108 text_source = ColumnDataSource(dict(text=text, x=x, y=y))
  109 glyph = Text(x="x", y="y", text="text", text_align="center", text_baseline="middle")
  110 plot.add_glyph(text_source, glyph)
  111 
  112 doc = Document()
  113 doc.add_root(plot)
  114 doc.validate()
  115 
  116 filename = "donut.html"
  117 with open(filename, "w") as f:
  118     f.write(file_html(doc, INLINE, "Donut Chart"))
  119 print("Wrote %s" % filename)
  120 view(filename)
  121
  ```
  --- 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/examples/models/file/donut.py b/examples/models/file/donut.py
  --- a/examples/models/file/donut.py
  +++ b/examples/models/file/donut.py
  @@ -61,7 +61,7 @@
       end = angles.tolist() + [end_angle]
       start = [start_angle] + end[:-1]
       base_color = colors[browser]
  -    fill = [ base_color.lighten(i*0.05) for i in range(len(versions) + 1) ]
  +    fill = [ base_color.lighten(i*0.05).to_hex() for i in range(len(versions) + 1) ]
       # extra empty string accounts for all versions with share < 0.5 together
       text = [ number if share >= 1 else "" for number, share in zip(versions.VersionNumber, versions.Share) ] + [""]
       x, y = polar_to_cartesian(1.25, start, end)
  @@ -72,20 +72,9 @@
           line_color="white", line_width=2, fill_color="fill")
       plot.add_glyph(source, glyph)
   
  -
       text_angle = [(start[i]+end[i])/2 for i in range(len(start))]
       text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]
   
  -    if first and text:
  -        text.insert(0, '(version)')
  -        offset = pi / 48
  -        text_angle.insert(0, text_angle[0] - offset)
  -        start.insert(0, start[0] - offset)
  -        end.insert(0, end[0] - offset)
  -        x, y = polar_to_cartesian(1.25, start, end)
  -        first = False
  -
  -
       text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))
       glyph = Text(x="x", y="y", text="text", angle="angle",
           text_align="center", text_baseline="middle", text_font_size="8pt")
  
verification_info: {"golden_diff": "diff --git a/examples/models/file/donut.py b/examples/models/file/donut.py\n--- a/examples/models/file/donut.py\n+++ b/examples/models/file/donut.py\n@@ -61,7 +61,7 @@\n     end = angles.tolist() + [end_angle]\n     start = [start_angle] + end[:-1]\n     base_color = colors[browser]\n-    fill = [ base_color.lighten(i*0.05) for i in range(len(versions) + 1) ]\n+    fill = [ base_color.lighten(i*0.05).to_hex() for i in range(len(versions) + 1) ]\n     # extra empty string accounts for all versions with share < 0.5 together\n     text = [ number if share >= 1 else \"\" for number, share in zip(versions.VersionNumber, versions.Share) ] + [\"\"]\n     x, y = polar_to_cartesian(1.25, start, end)\n@@ -72,20 +72,9 @@\n         line_color=\"white\", line_width=2, fill_color=\"fill\")\n     plot.add_glyph(source, glyph)\n \n-\n     text_angle = [(start[i]+end[i])/2 for i in range(len(start))]\n     text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]\n \n-    if first and text:\n-        text.insert(0, '(version)')\n-        offset = pi / 48\n-        text_angle.insert(0, text_angle[0] - offset)\n-        start.insert(0, start[0] - offset)\n-        end.insert(0, end[0] - offset)\n-        x, y = polar_to_cartesian(1.25, start, end)\n-        first = False\n-\n-\n     text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))\n     glyph = Text(x=\"x\", y=\"y\", text=\"text\", angle=\"angle\",\n         text_align=\"center\", text_baseline=\"middle\", text_font_size=\"8pt\")\n", "issue": "DataTable crashes layout if 'field' is key in ColumnDataSource data\nBokeh 0.13.0\r\nMac OS 10.13.3\r\npython 2.7.10\r\nSafari 11.0.3\r\n\r\nIf 'field' is a key in the data of ColumnDataSource, bokeh serve cannot generate a layout including a DataTable using this ColumnDataSource.  This only fails if the DataTable is in the layout, the DataTable may exist if not in the layout.\r\n\r\nThe following code will fail.  If you replace 'field' in variables with almost anything else, the code works.\r\n\r\n```\r\nfrom bokeh.models import ColumnDataSource\r\nfrom bokeh.models.widgets import TableColumn, DataTable\r\nfrom bokeh.io import curdoc\r\nfrom bokeh.layouts import column\r\n\r\n\r\nvariables = ['x', 'y', 'field']\r\nsource = ColumnDataSource(data={v: [i] for i, v in enumerate(variables)})\r\ntable = DataTable(source=source, columns=[TableColumn(field=v, title=v) for v in variables])\r\ncurdoc().add_root(column(table))\r\n```\r\n\n", "before_files": [{"content": "from __future__ import print_function\n\nimport base64\nfrom math import pi, sin, cos\n\nfrom bokeh.util.browser import view\nfrom bokeh.colors.named import skyblue, seagreen, tomato, orchid, firebrick, lightgray\nfrom bokeh.document import Document\nfrom bokeh.embed import file_html\nfrom bokeh.models.glyphs import Wedge, AnnularWedge, ImageURL, Text\nfrom bokeh.models import ColumnDataSource, Plot, Range1d\nfrom bokeh.resources import INLINE\nfrom bokeh.sampledata.browsers import browsers_nov_2013, icons\n\ndf = browsers_nov_2013\n\nxdr = Range1d(start=-2, end=2)\nydr = Range1d(start=-2, end=2)\n\nplot = Plot(x_range=xdr, y_range=ydr, plot_width=800, plot_height=800)\nplot.title.text = \"Web browser market share (November 2013)\"\nplot.toolbar_location = None\n\ncolors = {\"Chrome\": seagreen, \"Firefox\": tomato, \"Safari\": orchid, \"Opera\": firebrick, \"IE\": skyblue, \"Other\": lightgray}\n\naggregated = df.groupby(\"Browser\").agg(sum)\nselected = aggregated[aggregated.Share >= 1].copy()\nselected.loc[\"Other\"] = aggregated[aggregated.Share < 1].sum()\nbrowsers = selected.index.tolist()\n\nradians = lambda x: 2*pi*(x/100)\nangles = selected.Share.map(radians).cumsum()\n\nend_angles = angles.tolist()\nstart_angles = [0] + end_angles[:-1]\n\nbrowsers_source = ColumnDataSource(dict(\n    start  = start_angles,\n    end    = end_angles,\n    colors = [colors[browser] for browser in browsers ],\n))\n\nglyph = Wedge(x=0, y=0, radius=1, line_color=\"white\",\n    line_width=2, start_angle=\"start\", end_angle=\"end\", fill_color=\"colors\")\nplot.add_glyph(browsers_source, glyph)\n\ndef polar_to_cartesian(r, start_angles, end_angles):\n    cartesian = lambda r, alpha: (r*cos(alpha), r*sin(alpha))\n    points = []\n\n    for start, end in zip(start_angles, end_angles):\n        points.append(cartesian(r, (end + start)/2))\n\n    return zip(*points)\n\nfirst = True\n\nfor browser, start_angle, end_angle in zip(browsers, start_angles, end_angles):\n    versions = df[(df.Browser == browser) & (df.Share >= 0.5)]\n    angles = versions.Share.map(radians).cumsum() + start_angle\n    end = angles.tolist() + [end_angle]\n    start = [start_angle] + end[:-1]\n    base_color = colors[browser]\n    fill = [ base_color.lighten(i*0.05) for i in range(len(versions) + 1) ]\n    # extra empty string accounts for all versions with share < 0.5 together\n    text = [ number if share >= 1 else \"\" for number, share in zip(versions.VersionNumber, versions.Share) ] + [\"\"]\n    x, y = polar_to_cartesian(1.25, start, end)\n\n    source = ColumnDataSource(dict(start=start, end=end, fill=fill))\n    glyph = AnnularWedge(x=0, y=0,\n        inner_radius=1, outer_radius=1.5, start_angle=\"start\", end_angle=\"end\",\n        line_color=\"white\", line_width=2, fill_color=\"fill\")\n    plot.add_glyph(source, glyph)\n\n\n    text_angle = [(start[i]+end[i])/2 for i in range(len(start))]\n    text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]\n\n    if first and text:\n        text.insert(0, '(version)')\n        offset = pi / 48\n        text_angle.insert(0, text_angle[0] - offset)\n        start.insert(0, start[0] - offset)\n        end.insert(0, end[0] - offset)\n        x, y = polar_to_cartesian(1.25, start, end)\n        first = False\n\n\n    text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))\n    glyph = Text(x=\"x\", y=\"y\", text=\"text\", angle=\"angle\",\n        text_align=\"center\", text_baseline=\"middle\", text_font_size=\"8pt\")\n    plot.add_glyph(text_source, glyph)\n\n\ndef to_base64(png):\n    return \"data:image/png;base64,\" + base64.b64encode(png).decode(\"utf-8\")\n\nurls = [ to_base64(icons.get(browser, b\"\")) for browser in browsers ]\nx, y = polar_to_cartesian(1.7, start_angles, end_angles)\n\nicons_source = ColumnDataSource(dict(urls=urls, x=x, y=y))\nglyph = ImageURL(url=\"urls\", x=\"x\", y=\"y\", anchor=\"center\")\nplot.add_glyph(icons_source, glyph)\n\ntext = [ \"%.02f%%\" % value for value in selected.Share ]\nx, y = polar_to_cartesian(0.7, start_angles, end_angles)\n\ntext_source = ColumnDataSource(dict(text=text, x=x, y=y))\nglyph = Text(x=\"x\", y=\"y\", text=\"text\", text_align=\"center\", text_baseline=\"middle\")\nplot.add_glyph(text_source, glyph)\n\ndoc = Document()\ndoc.add_root(plot)\ndoc.validate()\n\nfilename = \"donut.html\"\nwith open(filename, \"w\") as f:\n    f.write(file_html(doc, INLINE, \"Donut Chart\"))\nprint(\"Wrote %s\" % filename)\nview(filename)\n", "path": "examples/models/file/donut.py"}], "after_files": [{"content": "from __future__ import print_function\n\nimport base64\nfrom math import pi, sin, cos\n\nfrom bokeh.util.browser import view\nfrom bokeh.colors.named import skyblue, seagreen, tomato, orchid, firebrick, lightgray\nfrom bokeh.document import Document\nfrom bokeh.embed import file_html\nfrom bokeh.models.glyphs import Wedge, AnnularWedge, ImageURL, Text\nfrom bokeh.models import ColumnDataSource, Plot, Range1d\nfrom bokeh.resources import INLINE\nfrom bokeh.sampledata.browsers import browsers_nov_2013, icons\n\ndf = browsers_nov_2013\n\nxdr = Range1d(start=-2, end=2)\nydr = Range1d(start=-2, end=2)\n\nplot = Plot(x_range=xdr, y_range=ydr, plot_width=800, plot_height=800)\nplot.title.text = \"Web browser market share (November 2013)\"\nplot.toolbar_location = None\n\ncolors = {\"Chrome\": seagreen, \"Firefox\": tomato, \"Safari\": orchid, \"Opera\": firebrick, \"IE\": skyblue, \"Other\": lightgray}\n\naggregated = df.groupby(\"Browser\").agg(sum)\nselected = aggregated[aggregated.Share >= 1].copy()\nselected.loc[\"Other\"] = aggregated[aggregated.Share < 1].sum()\nbrowsers = selected.index.tolist()\n\nradians = lambda x: 2*pi*(x/100)\nangles = selected.Share.map(radians).cumsum()\n\nend_angles = angles.tolist()\nstart_angles = [0] + end_angles[:-1]\n\nbrowsers_source = ColumnDataSource(dict(\n    start  = start_angles,\n    end    = end_angles,\n    colors = [colors[browser] for browser in browsers ],\n))\n\nglyph = Wedge(x=0, y=0, radius=1, line_color=\"white\",\n    line_width=2, start_angle=\"start\", end_angle=\"end\", fill_color=\"colors\")\nplot.add_glyph(browsers_source, glyph)\n\ndef polar_to_cartesian(r, start_angles, end_angles):\n    cartesian = lambda r, alpha: (r*cos(alpha), r*sin(alpha))\n    points = []\n\n    for start, end in zip(start_angles, end_angles):\n        points.append(cartesian(r, (end + start)/2))\n\n    return zip(*points)\n\nfirst = True\n\nfor browser, start_angle, end_angle in zip(browsers, start_angles, end_angles):\n    versions = df[(df.Browser == browser) & (df.Share >= 0.5)]\n    angles = versions.Share.map(radians).cumsum() + start_angle\n    end = angles.tolist() + [end_angle]\n    start = [start_angle] + end[:-1]\n    base_color = colors[browser]\n    fill = [ base_color.lighten(i*0.05).to_hex() for i in range(len(versions) + 1) ]\n    # extra empty string accounts for all versions with share < 0.5 together\n    text = [ number if share >= 1 else \"\" for number, share in zip(versions.VersionNumber, versions.Share) ] + [\"\"]\n    x, y = polar_to_cartesian(1.25, start, end)\n\n    source = ColumnDataSource(dict(start=start, end=end, fill=fill))\n    glyph = AnnularWedge(x=0, y=0,\n        inner_radius=1, outer_radius=1.5, start_angle=\"start\", end_angle=\"end\",\n        line_color=\"white\", line_width=2, fill_color=\"fill\")\n    plot.add_glyph(source, glyph)\n\n    text_angle = [(start[i]+end[i])/2 for i in range(len(start))]\n    text_angle = [angle + pi if pi/2 < angle < 3*pi/2 else angle for angle in text_angle]\n\n    text_source = ColumnDataSource(dict(text=text, x=x, y=y, angle=text_angle))\n    glyph = Text(x=\"x\", y=\"y\", text=\"text\", angle=\"angle\",\n        text_align=\"center\", text_baseline=\"middle\", text_font_size=\"8pt\")\n    plot.add_glyph(text_source, glyph)\n\n\ndef to_base64(png):\n    return \"data:image/png;base64,\" + base64.b64encode(png).decode(\"utf-8\")\n\nurls = [ to_base64(icons.get(browser, b\"\")) for browser in browsers ]\nx, y = polar_to_cartesian(1.7, start_angles, end_angles)\n\nicons_source = ColumnDataSource(dict(urls=urls, x=x, y=y))\nglyph = ImageURL(url=\"urls\", x=\"x\", y=\"y\", anchor=\"center\")\nplot.add_glyph(icons_source, glyph)\n\ntext = [ \"%.02f%%\" % value for value in selected.Share ]\nx, y = polar_to_cartesian(0.7, start_angles, end_angles)\n\ntext_source = ColumnDataSource(dict(text=text, x=x, y=y))\nglyph = Text(x=\"x\", y=\"y\", text=\"text\", text_align=\"center\", text_baseline=\"middle\")\nplot.add_glyph(text_source, glyph)\n\ndoc = Document()\ndoc.add_root(plot)\ndoc.validate()\n\nfilename = \"donut.html\"\nwith open(filename, \"w\") as f:\n    f.write(file_html(doc, INLINE, \"Donut Chart\"))\nprint(\"Wrote %s\" % filename)\nview(filename)\n", "path": "examples/models/file/donut.py"}]}