prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  `os.path.relpath` may throw an exception on Windows.
  `os.path.relpath` may throw an exception on Windows.
  
  ```
  Traceback (most recent call last):
  File "C:\tools\sublime\Data\Installed Packages\LSP.sublime-package\plugin/references.py", line 55, in 
  File "C:\tools\sublime\Data\Installed Packages\LSP.sublime-package\plugin/references.py", line 62, in _handle_response
  File "C:\tools\sublime\Data\Installed Packages\LSP.sublime-package\plugin/references.py", line 85, in _show_references_in_output_panel
  File "C:\tools\sublime\Data\Installed Packages\LSP.sublime-package\plugin/references.py", line 107, in _get_relative_path
  File "./python3.3/ntpath.py", line 564, in relpath
  ValueError: path is on mount 'C:', start on mount '\myserver\myshare'
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `plugin/references.py`
  Content:
  ```
  1 from .core.panels import ensure_panel
  2 from .core.protocol import Location
  3 from .core.protocol import Point
  4 from .core.protocol import Request
  5 from .core.registry import get_position
  6 from .core.registry import LspTextCommand
  7 from .core.sessions import Session
  8 from .core.settings import PLUGIN_NAME
  9 from .core.settings import userprefs
  10 from .core.types import ClientConfig
  11 from .core.types import PANEL_FILE_REGEX
  12 from .core.types import PANEL_LINE_REGEX
  13 from .core.typing import Dict, List, Optional, Tuple
  14 from .core.views import get_line
  15 from .core.views import get_uri_and_position_from_location
  16 from .core.views import text_document_position_params
  17 from .locationpicker import LocationPicker
  18 import functools
  19 import linecache
  20 import os
  21 import sublime
  22 
  23 
  24 def ensure_references_panel(window: sublime.Window) -> Optional[sublime.View]:
  25     return ensure_panel(window, "references", PANEL_FILE_REGEX, PANEL_LINE_REGEX,
  26                         "Packages/" + PLUGIN_NAME + "/Syntaxes/References.sublime-syntax")
  27 
  28 
  29 class LspSymbolReferencesCommand(LspTextCommand):
  30 
  31     capability = 'referencesProvider'
  32 
  33     def __init__(self, view: sublime.View) -> None:
  34         super().__init__(view)
  35         self._picker = None  # type: Optional[LocationPicker]
  36 
  37     def run(self, _: sublime.Edit, event: Optional[dict] = None, point: Optional[int] = None) -> None:
  38         session = self.best_session(self.capability)
  39         file_path = self.view.file_name()
  40         pos = get_position(self.view, event, point)
  41         if session and file_path and pos is not None:
  42             params = text_document_position_params(self.view, pos)
  43             params['context'] = {"includeDeclaration": False}
  44             request = Request("textDocument/references", params, self.view, progress=True)
  45             session.send_request(
  46                 request,
  47                 functools.partial(
  48                     self._handle_response_async,
  49                     self.view.substr(self.view.word(pos)),
  50                     session
  51                 )
  52             )
  53 
  54     def _handle_response_async(self, word: str, session: Session, response: Optional[List[Location]]) -> None:
  55         sublime.set_timeout(lambda: self._handle_response(word, session, response))
  56 
  57     def _handle_response(self, word: str, session: Session, response: Optional[List[Location]]) -> None:
  58         if response:
  59             if userprefs().show_references_in_quick_panel:
  60                 self._show_references_in_quick_panel(session, response)
  61             else:
  62                 self._show_references_in_output_panel(word, session, response)
  63         else:
  64             window = self.view.window()
  65             if window:
  66                 window.status_message("No references found")
  67 
  68     def _show_references_in_quick_panel(self, session: Session, locations: List[Location]) -> None:
  69         self.view.run_command("add_jump_record", {"selection": [(r.a, r.b) for r in self.view.sel()]})
  70         LocationPicker(self.view, session, locations, side_by_side=False)
  71 
  72     def _show_references_in_output_panel(self, word: str, session: Session, locations: List[Location]) -> None:
  73         window = session.window
  74         panel = ensure_references_panel(window)
  75         if not panel:
  76             return
  77         manager = session.manager()
  78         if not manager:
  79             return
  80         base_dir = manager.get_project_path(self.view.file_name() or "")
  81         to_render = []  # type: List[str]
  82         references_count = 0
  83         references_by_file = _group_locations_by_uri(window, session.config, locations)
  84         for file, references in references_by_file.items():
  85             to_render.append('{}:'.format(_get_relative_path(base_dir, file)))
  86             for reference in references:
  87                 references_count += 1
  88                 point, line = reference
  89                 to_render.append('{:>5}:{:<4} {}'.format(point.row + 1, point.col + 1, line))
  90             to_render.append("")  # add spacing between filenames
  91         characters = "\n".join(to_render)
  92         panel.settings().set("result_base_dir", base_dir)
  93         panel.run_command("lsp_clear_panel")
  94         window.run_command("show_panel", {"panel": "output.references"})
  95         panel.run_command('append', {
  96             'characters': "{} references for '{}'\n\n{}".format(references_count, word, characters),
  97             'force': True,
  98             'scroll_to_end': False
  99         })
  100         # highlight all word occurrences
  101         regions = panel.find_all(r"\b{}\b".format(word))
  102         panel.add_regions('ReferenceHighlight', regions, 'comment', flags=sublime.DRAW_OUTLINED)
  103 
  104 
  105 def _get_relative_path(base_dir: Optional[str], file_path: str) -> str:
  106     if base_dir:
  107         return os.path.relpath(file_path, base_dir)
  108     else:
  109         return file_path
  110 
  111 
  112 def _group_locations_by_uri(
  113     window: sublime.Window,
  114     config: ClientConfig,
  115     locations: List[Location]
  116 ) -> Dict[str, List[Tuple[Point, str]]]:
  117     """Return a dictionary that groups locations by the URI it belongs."""
  118     grouped_locations = {}  # type: Dict[str, List[Tuple[Point, str]]]
  119     for location in locations:
  120         uri, position = get_uri_and_position_from_location(location)
  121         file_path = config.map_server_uri_to_client_path(uri)
  122         point = Point.from_lsp(position)
  123         # get line of the reference, to showcase its use
  124         reference_line = get_line(window, file_path, point.row)
  125         if grouped_locations.get(file_path) is None:
  126             grouped_locations[file_path] = []
  127         grouped_locations[file_path].append((point, reference_line))
  128     # we don't want to cache the line, we always want to get fresh data
  129     linecache.clearcache()
  130     return grouped_locations
  131
  ```
  --- 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/plugin/references.py b/plugin/references.py
  --- a/plugin/references.py
  +++ b/plugin/references.py
  @@ -104,9 +104,12 @@
   
   def _get_relative_path(base_dir: Optional[str], file_path: str) -> str:
       if base_dir:
  -        return os.path.relpath(file_path, base_dir)
  -    else:
  -        return file_path
  +        try:
  +            return os.path.relpath(file_path, base_dir)
  +        except ValueError:
  +            # On Windows, ValueError is raised when path and start are on different drives.
  +            pass
  +    return file_path
   
   
   def _group_locations_by_uri(
  
verification_info: {"golden_diff": "diff --git a/plugin/references.py b/plugin/references.py\n--- a/plugin/references.py\n+++ b/plugin/references.py\n@@ -104,9 +104,12 @@\n \n def _get_relative_path(base_dir: Optional[str], file_path: str) -> str:\n     if base_dir:\n-        return os.path.relpath(file_path, base_dir)\n-    else:\n-        return file_path\n+        try:\n+            return os.path.relpath(file_path, base_dir)\n+        except ValueError:\n+            # On Windows, ValueError is raised when path and start are on different drives.\n+            pass\n+    return file_path\n \n \n def _group_locations_by_uri(\n", "issue": "`os.path.relpath` may throw an exception on Windows.\n`os.path.relpath` may throw an exception on Windows.\r\n\r\n```\r\nTraceback (most recent call last):\r\nFile \"C:\\tools\\sublime\\Data\\Installed Packages\\LSP.sublime-package\\plugin/references.py\", line 55, in \r\nFile \"C:\\tools\\sublime\\Data\\Installed Packages\\LSP.sublime-package\\plugin/references.py\", line 62, in _handle_response\r\nFile \"C:\\tools\\sublime\\Data\\Installed Packages\\LSP.sublime-package\\plugin/references.py\", line 85, in _show_references_in_output_panel\r\nFile \"C:\\tools\\sublime\\Data\\Installed Packages\\LSP.sublime-package\\plugin/references.py\", line 107, in _get_relative_path\r\nFile \"./python3.3/ntpath.py\", line 564, in relpath\r\nValueError: path is on mount 'C:', start on mount '\\myserver\\myshare'\r\n```\n", "before_files": [{"content": "from .core.panels import ensure_panel\nfrom .core.protocol import Location\nfrom .core.protocol import Point\nfrom .core.protocol import Request\nfrom .core.registry import get_position\nfrom .core.registry import LspTextCommand\nfrom .core.sessions import Session\nfrom .core.settings import PLUGIN_NAME\nfrom .core.settings import userprefs\nfrom .core.types import ClientConfig\nfrom .core.types import PANEL_FILE_REGEX\nfrom .core.types import PANEL_LINE_REGEX\nfrom .core.typing import Dict, List, Optional, Tuple\nfrom .core.views import get_line\nfrom .core.views import get_uri_and_position_from_location\nfrom .core.views import text_document_position_params\nfrom .locationpicker import LocationPicker\nimport functools\nimport linecache\nimport os\nimport sublime\n\n\ndef ensure_references_panel(window: sublime.Window) -> Optional[sublime.View]:\n    return ensure_panel(window, \"references\", PANEL_FILE_REGEX, PANEL_LINE_REGEX,\n                        \"Packages/\" + PLUGIN_NAME + \"/Syntaxes/References.sublime-syntax\")\n\n\nclass LspSymbolReferencesCommand(LspTextCommand):\n\n    capability = 'referencesProvider'\n\n    def __init__(self, view: sublime.View) -> None:\n        super().__init__(view)\n        self._picker = None  # type: Optional[LocationPicker]\n\n    def run(self, _: sublime.Edit, event: Optional[dict] = None, point: Optional[int] = None) -> None:\n        session = self.best_session(self.capability)\n        file_path = self.view.file_name()\n        pos = get_position(self.view, event, point)\n        if session and file_path and pos is not None:\n            params = text_document_position_params(self.view, pos)\n            params['context'] = {\"includeDeclaration\": False}\n            request = Request(\"textDocument/references\", params, self.view, progress=True)\n            session.send_request(\n                request,\n                functools.partial(\n                    self._handle_response_async,\n                    self.view.substr(self.view.word(pos)),\n                    session\n                )\n            )\n\n    def _handle_response_async(self, word: str, session: Session, response: Optional[List[Location]]) -> None:\n        sublime.set_timeout(lambda: self._handle_response(word, session, response))\n\n    def _handle_response(self, word: str, session: Session, response: Optional[List[Location]]) -> None:\n        if response:\n            if userprefs().show_references_in_quick_panel:\n                self._show_references_in_quick_panel(session, response)\n            else:\n                self._show_references_in_output_panel(word, session, response)\n        else:\n            window = self.view.window()\n            if window:\n                window.status_message(\"No references found\")\n\n    def _show_references_in_quick_panel(self, session: Session, locations: List[Location]) -> None:\n        self.view.run_command(\"add_jump_record\", {\"selection\": [(r.a, r.b) for r in self.view.sel()]})\n        LocationPicker(self.view, session, locations, side_by_side=False)\n\n    def _show_references_in_output_panel(self, word: str, session: Session, locations: List[Location]) -> None:\n        window = session.window\n        panel = ensure_references_panel(window)\n        if not panel:\n            return\n        manager = session.manager()\n        if not manager:\n            return\n        base_dir = manager.get_project_path(self.view.file_name() or \"\")\n        to_render = []  # type: List[str]\n        references_count = 0\n        references_by_file = _group_locations_by_uri(window, session.config, locations)\n        for file, references in references_by_file.items():\n            to_render.append('{}:'.format(_get_relative_path(base_dir, file)))\n            for reference in references:\n                references_count += 1\n                point, line = reference\n                to_render.append('{:>5}:{:<4} {}'.format(point.row + 1, point.col + 1, line))\n            to_render.append(\"\")  # add spacing between filenames\n        characters = \"\\n\".join(to_render)\n        panel.settings().set(\"result_base_dir\", base_dir)\n        panel.run_command(\"lsp_clear_panel\")\n        window.run_command(\"show_panel\", {\"panel\": \"output.references\"})\n        panel.run_command('append', {\n            'characters': \"{} references for '{}'\\n\\n{}\".format(references_count, word, characters),\n            'force': True,\n            'scroll_to_end': False\n        })\n        # highlight all word occurrences\n        regions = panel.find_all(r\"\\b{}\\b\".format(word))\n        panel.add_regions('ReferenceHighlight', regions, 'comment', flags=sublime.DRAW_OUTLINED)\n\n\ndef _get_relative_path(base_dir: Optional[str], file_path: str) -> str:\n    if base_dir:\n        return os.path.relpath(file_path, base_dir)\n    else:\n        return file_path\n\n\ndef _group_locations_by_uri(\n    window: sublime.Window,\n    config: ClientConfig,\n    locations: List[Location]\n) -> Dict[str, List[Tuple[Point, str]]]:\n    \"\"\"Return a dictionary that groups locations by the URI it belongs.\"\"\"\n    grouped_locations = {}  # type: Dict[str, List[Tuple[Point, str]]]\n    for location in locations:\n        uri, position = get_uri_and_position_from_location(location)\n        file_path = config.map_server_uri_to_client_path(uri)\n        point = Point.from_lsp(position)\n        # get line of the reference, to showcase its use\n        reference_line = get_line(window, file_path, point.row)\n        if grouped_locations.get(file_path) is None:\n            grouped_locations[file_path] = []\n        grouped_locations[file_path].append((point, reference_line))\n    # we don't want to cache the line, we always want to get fresh data\n    linecache.clearcache()\n    return grouped_locations\n", "path": "plugin/references.py"}], "after_files": [{"content": "from .core.panels import ensure_panel\nfrom .core.protocol import Location\nfrom .core.protocol import Point\nfrom .core.protocol import Request\nfrom .core.registry import get_position\nfrom .core.registry import LspTextCommand\nfrom .core.sessions import Session\nfrom .core.settings import PLUGIN_NAME\nfrom .core.settings import userprefs\nfrom .core.types import ClientConfig\nfrom .core.types import PANEL_FILE_REGEX\nfrom .core.types import PANEL_LINE_REGEX\nfrom .core.typing import Dict, List, Optional, Tuple\nfrom .core.views import get_line\nfrom .core.views import get_uri_and_position_from_location\nfrom .core.views import text_document_position_params\nfrom .locationpicker import LocationPicker\nimport functools\nimport linecache\nimport os\nimport sublime\n\n\ndef ensure_references_panel(window: sublime.Window) -> Optional[sublime.View]:\n    return ensure_panel(window, \"references\", PANEL_FILE_REGEX, PANEL_LINE_REGEX,\n                        \"Packages/\" + PLUGIN_NAME + \"/Syntaxes/References.sublime-syntax\")\n\n\nclass LspSymbolReferencesCommand(LspTextCommand):\n\n    capability = 'referencesProvider'\n\n    def __init__(self, view: sublime.View) -> None:\n        super().__init__(view)\n        self._picker = None  # type: Optional[LocationPicker]\n\n    def run(self, _: sublime.Edit, event: Optional[dict] = None, point: Optional[int] = None) -> None:\n        session = self.best_session(self.capability)\n        file_path = self.view.file_name()\n        pos = get_position(self.view, event, point)\n        if session and file_path and pos is not None:\n            params = text_document_position_params(self.view, pos)\n            params['context'] = {\"includeDeclaration\": False}\n            request = Request(\"textDocument/references\", params, self.view, progress=True)\n            session.send_request(\n                request,\n                functools.partial(\n                    self._handle_response_async,\n                    self.view.substr(self.view.word(pos)),\n                    session\n                )\n            )\n\n    def _handle_response_async(self, word: str, session: Session, response: Optional[List[Location]]) -> None:\n        sublime.set_timeout(lambda: self._handle_response(word, session, response))\n\n    def _handle_response(self, word: str, session: Session, response: Optional[List[Location]]) -> None:\n        if response:\n            if userprefs().show_references_in_quick_panel:\n                self._show_references_in_quick_panel(session, response)\n            else:\n                self._show_references_in_output_panel(word, session, response)\n        else:\n            window = self.view.window()\n            if window:\n                window.status_message(\"No references found\")\n\n    def _show_references_in_quick_panel(self, session: Session, locations: List[Location]) -> None:\n        self.view.run_command(\"add_jump_record\", {\"selection\": [(r.a, r.b) for r in self.view.sel()]})\n        LocationPicker(self.view, session, locations, side_by_side=False)\n\n    def _show_references_in_output_panel(self, word: str, session: Session, locations: List[Location]) -> None:\n        window = session.window\n        panel = ensure_references_panel(window)\n        if not panel:\n            return\n        manager = session.manager()\n        if not manager:\n            return\n        base_dir = manager.get_project_path(self.view.file_name() or \"\")\n        to_render = []  # type: List[str]\n        references_count = 0\n        references_by_file = _group_locations_by_uri(window, session.config, locations)\n        for file, references in references_by_file.items():\n            to_render.append('{}:'.format(_get_relative_path(base_dir, file)))\n            for reference in references:\n                references_count += 1\n                point, line = reference\n                to_render.append('{:>5}:{:<4} {}'.format(point.row + 1, point.col + 1, line))\n            to_render.append(\"\")  # add spacing between filenames\n        characters = \"\\n\".join(to_render)\n        panel.settings().set(\"result_base_dir\", base_dir)\n        panel.run_command(\"lsp_clear_panel\")\n        window.run_command(\"show_panel\", {\"panel\": \"output.references\"})\n        panel.run_command('append', {\n            'characters': \"{} references for '{}'\\n\\n{}\".format(references_count, word, characters),\n            'force': True,\n            'scroll_to_end': False\n        })\n        # highlight all word occurrences\n        regions = panel.find_all(r\"\\b{}\\b\".format(word))\n        panel.add_regions('ReferenceHighlight', regions, 'comment', flags=sublime.DRAW_OUTLINED)\n\n\ndef _get_relative_path(base_dir: Optional[str], file_path: str) -> str:\n    if base_dir:\n        try:\n            return os.path.relpath(file_path, base_dir)\n        except ValueError:\n            # On Windows, ValueError is raised when path and start are on different drives.\n            pass\n    return file_path\n\n\ndef _group_locations_by_uri(\n    window: sublime.Window,\n    config: ClientConfig,\n    locations: List[Location]\n) -> Dict[str, List[Tuple[Point, str]]]:\n    \"\"\"Return a dictionary that groups locations by the URI it belongs.\"\"\"\n    grouped_locations = {}  # type: Dict[str, List[Tuple[Point, str]]]\n    for location in locations:\n        uri, position = get_uri_and_position_from_location(location)\n        file_path = config.map_server_uri_to_client_path(uri)\n        point = Point.from_lsp(position)\n        # get line of the reference, to showcase its use\n        reference_line = get_line(window, file_path, point.row)\n        if grouped_locations.get(file_path) is None:\n            grouped_locations[file_path] = []\n        grouped_locations[file_path].append((point, reference_line))\n    # we don't want to cache the line, we always want to get fresh data\n    linecache.clearcache()\n    return grouped_locations\n", "path": "plugin/references.py"}]}