Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 29 additions & 19 deletions xmlschema/utils/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import platform
import posixpath
import string
import warnings
from pathlib import PurePath, PurePosixPath, PureWindowsPath
from urllib.parse import urlsplit, unquote, quote_from_bytes

Expand Down Expand Up @@ -160,27 +161,36 @@ def as_uri(self) -> str:
# Implementation that maps relative paths to not RFC 8089 compliant relative
# file URIs because urlopen() doesn't accept simple paths. For UNC paths uses
# the format with four slashes to let urlopen() works.

drive = self.drive
if len(drive) == 2 and drive[1] == ':' and drive[0] in DRIVE_LETTERS:
# A Windows path with a drive: 'c:\dir\file' => 'file:///c:/dir/file'
prefix = 'file:///' + drive
path = self.as_posix()[2:]
elif drive:
# UNC format case: '\\host\dir\file' => 'file:////host/dir/file'
prefix = 'file://'
path = self.as_posix()
else:
path = self.as_posix()
if path.startswith('/'):
# A Windows relative path or an absolute posix path:
# ('\dir\file' | '/dir/file') => 'file://dir/file'
#
# Note: PurePath.as_uri() is deprecated in Python 3.14+ (scheduled for removal
# in Python 3.19). This custom implementation doesn't call the parent method
# and provides the necessary functionality. We suppress the deprecation warning
# since this is an intentional override with a valid use case.

with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning,
message='.*PurePath.as_uri.*')

drive = self.drive
if len(drive) == 2 and drive[1] == ':' and drive[0] in DRIVE_LETTERS:
# A Windows path with a drive: 'c:\dir\file' => 'file:///c:/dir/file'
prefix = 'file:///' + drive
path = self.as_posix()[2:]
elif drive:
# UNC format case: '\\host\dir\file' => 'file:////host/dir/file'
prefix = 'file://'
path = self.as_posix()
else:
# A relative posix path: 'dir/file' => 'file:dir/file'
prefix = 'file:'

return prefix + quote_from_bytes(os.fsencode(path))
path = self.as_posix()
if path.startswith('/'):
# A Windows relative path or an absolute posix path:
# ('\dir\file' | '/dir/file') => 'file://dir/file'
prefix = 'file://'
else:
# A relative posix path: 'dir/file' => 'file:dir/file'
prefix = 'file:'

return prefix + quote_from_bytes(os.fsencode(path))

def normalize(self) -> 'LocationPath':
normalized_path = self._path_module.normpath(str(self))
Expand Down
Loading