4
4
"""Utilities for conversion between urls and file paths"""
5
5
6
6
import os
7
+ import sys
7
8
from urllib import (
8
9
parse as urlparse ,
9
10
request
@@ -52,18 +53,18 @@ def filepath_from_url(urlstr):
52
53
.. _ongoing discussions: https://discuss.python.org/t/file-uris-in-python/15600
53
54
"""
54
55
55
- # De-encode the URL
56
- decoded_url_str = urlparse .unquote (urlstr )
57
-
58
56
# Parse provided URL
59
- parsed_result = urlparse .urlparse (decoded_url_str )
57
+ parsed_result = urlparse .urlparse (urlstr )
58
+
59
+ # De-encode the parsed path
60
+ decoded_parsed_path = urlparse .unquote (parsed_result .path )
60
61
61
62
# Convert the parsed URL to a path
62
- filepath = Path (request .url2pathname (parsed_result . path ))
63
+ filepath = Path (request .url2pathname (decoded_parsed_path ))
63
64
64
65
# If the network location is a window drive, reassemble the path
65
66
if PureWindowsPath (parsed_result .netloc ).drive :
66
- filepath = Path (parsed_result .netloc + parsed_result . path )
67
+ filepath = Path (parsed_result .netloc + decoded_parsed_path )
67
68
68
69
# Check if the specified index has a specified `drive`, if so then do nothing
69
70
elif filepath .drive :
@@ -74,9 +75,18 @@ def filepath_from_url(urlstr):
74
75
# Remove leading "/" if/when `request.url2pathname` yields "/S:/path/file.ext"
75
76
filepath = filepath .relative_to (filepath .root )
76
77
77
- # Last resort, strip the "file:" prefix
78
- else :
79
- filepath = Path (decoded_url_str .strip ('file:' ))
78
+ # Should catch UNC paths,
79
+ # as parsing "file:///some/path/to/file.ext" doesn't provide a netloc
80
+ elif parsed_result .netloc and parsed_result .netloc != 'localhost' :
81
+ # Paths of type: "file://host/share/path/to/file.ext" provide "host" as netloc
82
+ filepath = Path ('//' , parsed_result .netloc + decoded_parsed_path )
80
83
81
84
# Convert "\" to "/" if needed
82
- return filepath .as_posix ()
85
+ path = filepath .as_posix ()
86
+
87
+ # Since the previous code handles Windows drive letter, we can assume that any path
88
+ # starting with a "/" is a UNC path if executed is run on Windows.
89
+ if path .startswith ('/' ) and sys .platform == 'win32' :
90
+ path = '/' + path
91
+
92
+ return path
0 commit comments