diff --git a/ycmd/completers/language_server/language_server_protocol.py b/ycmd/completers/language_server/language_server_protocol.py index ef4bb4005a..e26ecfc336 100644 --- a/ycmd/completers/language_server/language_server_protocol.py +++ b/ycmd/completers/language_server/language_server_protocol.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with ycmd. If not, see . +import sys import collections import os import json @@ -761,14 +762,18 @@ def UriToFilePath( uri ): if parsed_uri.scheme != 'file': raise InvalidUriException( uri ) - # url2pathname doesn't work as expected when uri.path is percent-encoded and - # is a windows path for ex: - # url2pathname('/C%3a/') == 'C:\\C:' - # whereas - # url2pathname('/C:/') == 'C:\\' - # Therefore first unquote pathname. - pathname = unquote( parsed_uri.path ) - return os.path.abspath( url2pathname( pathname ) ) + if sys.version_info < ( 3, 14 ): + # Before Python 3.14: + # url2pathname doesn't work as expected when uri.path is percent-encoded and + # is a windows path for ex: + # url2pathname('/C%3a/') == 'C:\\C:' + # whereas + # url2pathname('/C:/') == 'C:\\' + # Therefore first unquote pathname. + return os.path.abspath( url2pathname( unquote( parsed_uri.path ) ) ) + else: + # After Python 3.14, url2pathname seems to work properly + return os.path.abspath( url2pathname( uri, require_scheme=True ) ) def _BuildMessageData( message ): diff --git a/ycmd/tests/language_server/language_server_protocol_test.py b/ycmd/tests/language_server/language_server_protocol_test.py index 15c91a0001..4133bea0c3 100644 --- a/ycmd/tests/language_server/language_server_protocol_test.py +++ b/ycmd/tests/language_server/language_server_protocol_test.py @@ -153,6 +153,8 @@ def test_UriToFilePath_Unix( self ): equal_to( '/usr/local/test/test.test' ) ) assert_that( lsp.UriToFilePath( 'file:///usr/local/test/test.test' ), equal_to( '/usr/local/test/test.test' ) ) + assert_that( lsp.UriToFilePath( 'file:///usr/local/test%23foo/test.test' ), + equal_to( '/usr/local/test#foo/test.test' ) ) @WindowsOnly