prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Bokeh DateRangeSlider returns tuple of integers instead of dates
  In 0.12.7 the DateRangeSlider `.value` returns a tuple of integers. Additionally, in order to convert them back to dates you have to divide by 1000 (i.e. `datetime.fromtimestamp(the_tuple[0]/1000)`).
  
  Expected behavior: Return a tuple of Date objects.
  
  ```
  from datetime import datetime
  from bokeh.models.widgets import DateRangeSlider
  from bokeh.io import curdoc
  
  def date_range_update(attrname, old, new):
      print('-- range values:', date_slider.value)
      # Works
      d1 = datetime.fromtimestamp(date_slider.value[0] / 1000) 
      # Does not Work, gives error
      d2 = datetime.fromtimestamp(date_slider.value[0])
  
  date_slider = DateRangeSlider(value=(date_start,date_end), start=date_start, end=date_end)
  date_slider.on_change('value', date_range_update)
  
  curdoc().add_root(date_slider)
  
  ```
  
  #### Stack traceback and/or browser JavaScript console output
  
  #### Screenshots or screencasts of the bug in action
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `bokeh/models/widgets/sliders.py`
  Content:
  ```
  1 """ Various kinds of slider widgets.
  2 
  3 """
  4 from __future__ import absolute_import
  5 
  6 from ...core.has_props import abstract
  7 from ...core.properties import Bool, Int, Float, String, Date, Enum, Tuple, Instance, Color, Override
  8 from ...core.enums import SliderCallbackPolicy
  9 from ..callbacks import Callback
  10 from .widget import Widget
  11 
  12 @abstract
  13 class AbstractSlider(Widget):
  14     """ """
  15 
  16     title = String(default="", help="""
  17     Slider's label.
  18     """)
  19 
  20     show_value = Bool(default=True, help="""
  21     Whether or not show slider's value.
  22     """)
  23 
  24     format = String(help="""
  25     """)
  26 
  27     orientation = Enum("horizontal", "vertical", help="""
  28     Orient the slider either horizontally (default) or vertically.
  29     """)
  30 
  31     direction = Enum("ltr", "rtl", help="""
  32     """)
  33 
  34     tooltips = Bool(default=True, help="""
  35     """)
  36 
  37     callback = Instance(Callback, help="""
  38     A callback to run in the browser whenever the current Slider value changes.
  39     """)
  40 
  41     callback_throttle = Float(default=200, help="""
  42     Number of millseconds to pause between callback calls as the slider is moved.
  43     """)
  44 
  45     callback_policy = Enum(SliderCallbackPolicy, default="throttle", help="""
  46     When the callback is initiated. This parameter can take on only one of three options:
  47 
  48     * "continuous": the callback will be executed immediately for each movement of the slider
  49     * "throttle": the callback will be executed at most every ``callback_throttle`` milliseconds.
  50     * "mouseup": the callback will be executed only once when the slider is released.
  51 
  52     The "mouseup" policy is intended for scenarios in which the callback is expensive in time.
  53     """)
  54 
  55     bar_color = Color(default="#e6e6e6", help="""
  56     """)
  57 
  58 class Slider(AbstractSlider):
  59     """ Slider-based number selection widget. """
  60 
  61     start = Float(help="""
  62     The minimum allowable value.
  63     """)
  64 
  65     end = Float(help="""
  66     The maximum allowable value.
  67     """)
  68 
  69     value = Float(help="""
  70     Initial or selected value.
  71     """)
  72 
  73     step = Float(default=1, help="""
  74     The step between consecutive values.
  75     """)
  76 
  77     format = Override(default="0[.]00")
  78 
  79 class RangeSlider(AbstractSlider):
  80     """ Range-slider based number range selection widget. """
  81 
  82     value = Tuple(Float, Float, help="""
  83     Initial or selected range.
  84     """)
  85 
  86     start = Float(help="""
  87     The minimum allowable value.
  88     """)
  89 
  90     end = Float(help="""
  91     The maximum allowable value.
  92     """)
  93 
  94     step = Float(default=1, help="""
  95     The step between consecutive values.
  96     """)
  97 
  98     format = Override(default="0[.]00")
  99 
  100 class DateSlider(AbstractSlider):
  101     """ Slider-based date selection widget. """
  102 
  103     value = Date(help="""
  104     Initial or selected value.
  105     """)
  106 
  107     start = Date(help="""
  108     The minimum allowable value.
  109     """)
  110 
  111     end = Date(help="""
  112     The maximum allowable value.
  113     """)
  114 
  115     step = Int(default=1, help="""
  116     The step between consecutive values.
  117     """)
  118 
  119     format = Override(default="%d %b %G")
  120 
  121 class DateRangeSlider(AbstractSlider):
  122     """ Slider-based date range selection widget. """
  123 
  124     value = Tuple(Date, Date, help="""
  125     Initial or selected range.
  126     """)
  127 
  128     start = Date(help="""
  129     The minimum allowable value.
  130     """)
  131 
  132     end = Date(help="""
  133     The maximum allowable value.
  134     """)
  135 
  136     step = Int(default=1, help="""
  137     The step between consecutive values.
  138     """)
  139 
  140     format = Override(default="%d %b %G")
  141
  ```
  --- 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/bokeh/models/widgets/sliders.py b/bokeh/models/widgets/sliders.py
  --- a/bokeh/models/widgets/sliders.py
  +++ b/bokeh/models/widgets/sliders.py
  @@ -3,6 +3,9 @@
   """
   from __future__ import absolute_import
   
  +from datetime import datetime
  +import numbers
  +
   from ...core.has_props import abstract
   from ...core.properties import Bool, Int, Float, String, Date, Enum, Tuple, Instance, Color, Override
   from ...core.enums import SliderCallbackPolicy
  @@ -121,6 +124,25 @@
   class DateRangeSlider(AbstractSlider):
       """ Slider-based date range selection widget. """
   
  +    @property
  +    def value_as_datetime(self):
  +        ''' Convenience property to retrieve the value tuple as a tuple of
  +        datetime objects.
  +
  +        '''
  +        if self.value is None:
  +            return None
  +        v1, v2 = self.value
  +        if isinstance(v1, numbers.Number):
  +            d1 = datetime.utcfromtimestamp(v1 / 1000)
  +        else:
  +            d1 = v1
  +        if isinstance(v2, numbers.Number):
  +            d2 = datetime.utcfromtimestamp(v2 / 1000)
  +        else:
  +            d2 = v2
  +        return d1, d2
  +
       value = Tuple(Date, Date, help="""
       Initial or selected range.
       """)
  
verification_info: {"golden_diff": "diff --git a/bokeh/models/widgets/sliders.py b/bokeh/models/widgets/sliders.py\n--- a/bokeh/models/widgets/sliders.py\n+++ b/bokeh/models/widgets/sliders.py\n@@ -3,6 +3,9 @@\n \"\"\"\n from __future__ import absolute_import\n \n+from datetime import datetime\n+import numbers\n+\n from ...core.has_props import abstract\n from ...core.properties import Bool, Int, Float, String, Date, Enum, Tuple, Instance, Color, Override\n from ...core.enums import SliderCallbackPolicy\n@@ -121,6 +124,25 @@\n class DateRangeSlider(AbstractSlider):\n     \"\"\" Slider-based date range selection widget. \"\"\"\n \n+    @property\n+    def value_as_datetime(self):\n+        ''' Convenience property to retrieve the value tuple as a tuple of\n+        datetime objects.\n+\n+        '''\n+        if self.value is None:\n+            return None\n+        v1, v2 = self.value\n+        if isinstance(v1, numbers.Number):\n+            d1 = datetime.utcfromtimestamp(v1 / 1000)\n+        else:\n+            d1 = v1\n+        if isinstance(v2, numbers.Number):\n+            d2 = datetime.utcfromtimestamp(v2 / 1000)\n+        else:\n+            d2 = v2\n+        return d1, d2\n+\n     value = Tuple(Date, Date, help=\"\"\"\n     Initial or selected range.\n     \"\"\")\n", "issue": "Bokeh DateRangeSlider returns tuple of integers instead of dates\nIn 0.12.7 the DateRangeSlider `.value` returns a tuple of integers. Additionally, in order to convert them back to dates you have to divide by 1000 (i.e. `datetime.fromtimestamp(the_tuple[0]/1000)`).\r\n\r\nExpected behavior: Return a tuple of Date objects.\r\n\r\n```\r\nfrom datetime import datetime\r\nfrom bokeh.models.widgets import DateRangeSlider\r\nfrom bokeh.io import curdoc\r\n\r\ndef date_range_update(attrname, old, new):\r\n    print('-- range values:', date_slider.value)\r\n    # Works\r\n    d1 = datetime.fromtimestamp(date_slider.value[0] / 1000) \r\n    # Does not Work, gives error\r\n    d2 = datetime.fromtimestamp(date_slider.value[0])\r\n\r\ndate_slider = DateRangeSlider(value=(date_start,date_end), start=date_start, end=date_end)\r\ndate_slider.on_change('value', date_range_update)\r\n\r\ncurdoc().add_root(date_slider)\r\n\r\n```\r\n\r\n#### Stack traceback and/or browser JavaScript console output\r\n\r\n#### Screenshots or screencasts of the bug in action\r\n\n", "before_files": [{"content": "\"\"\" Various kinds of slider widgets.\n\n\"\"\"\nfrom __future__ import absolute_import\n\nfrom ...core.has_props import abstract\nfrom ...core.properties import Bool, Int, Float, String, Date, Enum, Tuple, Instance, Color, Override\nfrom ...core.enums import SliderCallbackPolicy\nfrom ..callbacks import Callback\nfrom .widget import Widget\n\n@abstract\nclass AbstractSlider(Widget):\n    \"\"\" \"\"\"\n\n    title = String(default=\"\", help=\"\"\"\n    Slider's label.\n    \"\"\")\n\n    show_value = Bool(default=True, help=\"\"\"\n    Whether or not show slider's value.\n    \"\"\")\n\n    format = String(help=\"\"\"\n    \"\"\")\n\n    orientation = Enum(\"horizontal\", \"vertical\", help=\"\"\"\n    Orient the slider either horizontally (default) or vertically.\n    \"\"\")\n\n    direction = Enum(\"ltr\", \"rtl\", help=\"\"\"\n    \"\"\")\n\n    tooltips = Bool(default=True, help=\"\"\"\n    \"\"\")\n\n    callback = Instance(Callback, help=\"\"\"\n    A callback to run in the browser whenever the current Slider value changes.\n    \"\"\")\n\n    callback_throttle = Float(default=200, help=\"\"\"\n    Number of millseconds to pause between callback calls as the slider is moved.\n    \"\"\")\n\n    callback_policy = Enum(SliderCallbackPolicy, default=\"throttle\", help=\"\"\"\n    When the callback is initiated. This parameter can take on only one of three options:\n\n    * \"continuous\": the callback will be executed immediately for each movement of the slider\n    * \"throttle\": the callback will be executed at most every ``callback_throttle`` milliseconds.\n    * \"mouseup\": the callback will be executed only once when the slider is released.\n\n    The \"mouseup\" policy is intended for scenarios in which the callback is expensive in time.\n    \"\"\")\n\n    bar_color = Color(default=\"#e6e6e6\", help=\"\"\"\n    \"\"\")\n\nclass Slider(AbstractSlider):\n    \"\"\" Slider-based number selection widget. \"\"\"\n\n    start = Float(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Float(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    value = Float(help=\"\"\"\n    Initial or selected value.\n    \"\"\")\n\n    step = Float(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"0[.]00\")\n\nclass RangeSlider(AbstractSlider):\n    \"\"\" Range-slider based number range selection widget. \"\"\"\n\n    value = Tuple(Float, Float, help=\"\"\"\n    Initial or selected range.\n    \"\"\")\n\n    start = Float(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Float(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Float(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"0[.]00\")\n\nclass DateSlider(AbstractSlider):\n    \"\"\" Slider-based date selection widget. \"\"\"\n\n    value = Date(help=\"\"\"\n    Initial or selected value.\n    \"\"\")\n\n    start = Date(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Date(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Int(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"%d %b %G\")\n\nclass DateRangeSlider(AbstractSlider):\n    \"\"\" Slider-based date range selection widget. \"\"\"\n\n    value = Tuple(Date, Date, help=\"\"\"\n    Initial or selected range.\n    \"\"\")\n\n    start = Date(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Date(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Int(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"%d %b %G\")\n", "path": "bokeh/models/widgets/sliders.py"}], "after_files": [{"content": "\"\"\" Various kinds of slider widgets.\n\n\"\"\"\nfrom __future__ import absolute_import\n\nfrom datetime import datetime\nimport numbers\n\nfrom ...core.has_props import abstract\nfrom ...core.properties import Bool, Int, Float, String, Date, Enum, Tuple, Instance, Color, Override\nfrom ...core.enums import SliderCallbackPolicy\nfrom ..callbacks import Callback\nfrom .widget import Widget\n\n@abstract\nclass AbstractSlider(Widget):\n    \"\"\" \"\"\"\n\n    title = String(default=\"\", help=\"\"\"\n    Slider's label.\n    \"\"\")\n\n    show_value = Bool(default=True, help=\"\"\"\n    Whether or not show slider's value.\n    \"\"\")\n\n    format = String(help=\"\"\"\n    \"\"\")\n\n    orientation = Enum(\"horizontal\", \"vertical\", help=\"\"\"\n    Orient the slider either horizontally (default) or vertically.\n    \"\"\")\n\n    direction = Enum(\"ltr\", \"rtl\", help=\"\"\"\n    \"\"\")\n\n    tooltips = Bool(default=True, help=\"\"\"\n    \"\"\")\n\n    callback = Instance(Callback, help=\"\"\"\n    A callback to run in the browser whenever the current Slider value changes.\n    \"\"\")\n\n    callback_throttle = Float(default=200, help=\"\"\"\n    Number of millseconds to pause between callback calls as the slider is moved.\n    \"\"\")\n\n    callback_policy = Enum(SliderCallbackPolicy, default=\"throttle\", help=\"\"\"\n    When the callback is initiated. This parameter can take on only one of three options:\n\n    * \"continuous\": the callback will be executed immediately for each movement of the slider\n    * \"throttle\": the callback will be executed at most every ``callback_throttle`` milliseconds.\n    * \"mouseup\": the callback will be executed only once when the slider is released.\n\n    The \"mouseup\" policy is intended for scenarios in which the callback is expensive in time.\n    \"\"\")\n\n    bar_color = Color(default=\"#e6e6e6\", help=\"\"\"\n    \"\"\")\n\nclass Slider(AbstractSlider):\n    \"\"\" Slider-based number selection widget. \"\"\"\n\n    start = Float(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Float(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    value = Float(help=\"\"\"\n    Initial or selected value.\n    \"\"\")\n\n    step = Float(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"0[.]00\")\n\nclass RangeSlider(AbstractSlider):\n    \"\"\" Range-slider based number range selection widget. \"\"\"\n\n    value = Tuple(Float, Float, help=\"\"\"\n    Initial or selected range.\n    \"\"\")\n\n    start = Float(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Float(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Float(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"0[.]00\")\n\nclass DateSlider(AbstractSlider):\n    \"\"\" Slider-based date selection widget. \"\"\"\n\n    value = Date(help=\"\"\"\n    Initial or selected value.\n    \"\"\")\n\n    start = Date(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Date(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Int(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"%d %b %G\")\n\nclass DateRangeSlider(AbstractSlider):\n    \"\"\" Slider-based date range selection widget. \"\"\"\n\n    @property\n    def value_as_datetime(self):\n        ''' Convenience property to retrieve the value tuple as a tuple of\n        datetime objects.\n\n        '''\n        if self.value is None:\n            return None\n        v1, v2 = self.value\n        if isinstance(v1, numbers.Number):\n            d1 = datetime.utcfromtimestamp(v1 / 1000)\n        else:\n            d1 = v1\n        if isinstance(v2, numbers.Number):\n            d2 = datetime.utcfromtimestamp(v2 / 1000)\n        else:\n            d2 = v2\n        return d1, d2\n\n    value = Tuple(Date, Date, help=\"\"\"\n    Initial or selected range.\n    \"\"\")\n\n    start = Date(help=\"\"\"\n    The minimum allowable value.\n    \"\"\")\n\n    end = Date(help=\"\"\"\n    The maximum allowable value.\n    \"\"\")\n\n    step = Int(default=1, help=\"\"\"\n    The step between consecutive values.\n    \"\"\")\n\n    format = Override(default=\"%d %b %G\")\n", "path": "bokeh/models/widgets/sliders.py"}]}