@@ -297,9 +297,14 @@ def nv_tuple_list_replace(l, v):
297297def path2url (p ):
298298 """ Return file:// URL from a filename.
299299 """
300- return six .moves .urllib .parse .urljoin (
301- 'file:' , six .moves .urllib .request .pathname2url (p )
302- )
300+ # Python 3 is a bit different and does a better job.
301+ if sys .version_info [0 ] >= 3 :
302+ import pathlib
303+ return pathlib .Path (p ).as_uri ()
304+ else :
305+ return six .moves .urllib .parse .urljoin (
306+ 'file:' , six .moves .urllib .request .pathname2url (p )
307+ )
303308
304309def normalize_url (url ):
305310 """ Normalize url
@@ -334,9 +339,10 @@ def url_join(url, path):
334339 """ url version of os.path.join
335340 """
336341 p = six .moves .urllib .parse .urlparse (url )
342+ t = ('/' .join ([p .path , path ]),)
337343 return six .moves .urllib .parse .urlunparse (
338344 p [:2 ]+
339- ( os .path . join ( p . path , path ),) +
345+ t + # os.sep is different on windows, don't use it here.
340346 p [3 :]
341347 )
342348
@@ -366,7 +372,8 @@ def normalize_jr(jr, url=None):
366372 if p .scheme == '' and url :
367373 p = six .moves .urllib .parse .urlparse (url )
368374 # it's the path of relative file
369- path = six .moves .urllib .parse .urlunparse (p [:2 ]+ (os .path .join (os .path .dirname (p .path ), path ),)+ p [3 :])
375+ path = six .moves .urllib .parse .urlunparse (p [:2 ]+ ('/' .join ([os .path .dirname (p .path ), path ]),)+ p [3 :])
376+ path = derelativise_url (path )
370377 else :
371378 path = url
372379
@@ -375,6 +382,26 @@ def normalize_jr(jr, url=None):
375382 else :
376383 return '#' + jp
377384
385+ def derelativise_url (url ):
386+ '''
387+ Normalizes URLs, gets rid of .. and .
388+ '''
389+ parsed = six .moves .urllib .parse .urlparse (url )
390+ newpath = []
391+ for chunk in parsed .path [1 :].split ('/' ):
392+ if chunk == '.' :
393+ continue
394+ elif chunk == '..' :
395+ # parent dir.
396+ newpath = newpath [:- 1 ]
397+ continue
398+ # TODO: Verify this behaviour.
399+ elif re .fullmatch (r'\.{3,}' , chunk ) is not None :
400+ # parent dir.
401+ newpath = newpath [:- 1 ]
402+ continue
403+ newpath += [chunk ]
404+ return six .moves .urllib .parse .urlunparse (parsed [:2 ]+ ('/' + ('/' .join (newpath )),)+ parsed [3 :])
378405def is_file_url (url ):
379406 return url .startswith ('file://' )
380407
@@ -549,4 +576,3 @@ def patch_path(base_path, path):
549576 path = path [1 :]
550577
551578 return path
552-
0 commit comments