comparison mercurial/utils/urlutil.py @ 52907:ba343f763595

typing: add an interface for url This is fairly simple. This is a dependency for the "path" class in the same module, that is itself imported by `mercurial.interfaces.repository`. So we get it out of the way first.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 10 Feb 2025 00:15:22 +0100
parents 4cb75772818d
children 180591a9a6a1
comparison
equal deleted inserted replaced
52906:bde94bd8e8a2 52907:ba343f763595
26 urllibcompat, 26 urllibcompat,
27 ) 27 )
28 28
29 from . import ( 29 from . import (
30 stringutil, 30 stringutil,
31 )
32
33 from ..interfaces import (
34 misc as int_misc,
31 ) 35 )
32 36
33 from ..revlogutils import ( 37 from ..revlogutils import (
34 constants as revlog_constants, 38 constants as revlog_constants,
35 ) 39 )
58 raise error.Abort( 62 raise error.Abort(
59 _(b"no port number associated with service '%s'") % port 63 _(b"no port number associated with service '%s'") % port
60 ) 64 )
61 65
62 66
63 class url: 67 class url(int_misc.IUrl):
64 r"""Reliable URL parser. 68 r"""Reliable URL parser.
65 69
66 This parses URLs and provides attributes for the following 70 This parses URLs and provides attributes for the following
67 components: 71 components:
68 72
242 for a in ('user', 'passwd', 'host', 'port', 'path', 'fragment'): 246 for a in ('user', 'passwd', 'host', 'port', 'path', 'fragment'):
243 v = getattr(self, a) 247 v = getattr(self, a)
244 if v is not None: 248 if v is not None:
245 setattr(self, a, urlreq.unquote(v)) 249 setattr(self, a, urlreq.unquote(v))
246 250
247 def copy(self): 251 def copy(self) -> url:
248 u = url(b'temporary useless value') 252 u = url(b'temporary useless value')
249 u.path = self.path 253 u.path = self.path
250 u.scheme = self.scheme 254 u.scheme = self.scheme
251 u.user = self.user 255 u.user = self.user
252 u.passwd = self.passwd 256 u.passwd = self.passwd
359 s += b'#' + urlreq.quote(self.fragment, safe=self._safepchars) 363 s += b'#' + urlreq.quote(self.fragment, safe=self._safepchars)
360 return s 364 return s
361 365
362 __str__ = encoding.strmethod(__bytes__) 366 __str__ = encoding.strmethod(__bytes__)
363 367
364 def authinfo(self): 368 def authinfo(self) -> int_misc.AuthInfoT:
365 user, passwd = self.user, self.passwd 369 user, passwd = self.user, self.passwd
366 try: 370 try:
367 self.user, self.passwd = None, None 371 self.user, self.passwd = None, None
368 s = bytes(self) 372 s = bytes(self)
369 finally: 373 finally:
374 # URIs must not contain credentials. The host is passed in the 378 # URIs must not contain credentials. The host is passed in the
375 # URIs list because Python < 2.4.3 uses only that to search for 379 # URIs list because Python < 2.4.3 uses only that to search for
376 # a password. 380 # a password.
377 return (s, (None, (s, self.host), self.user, self.passwd or b'')) 381 return (s, (None, (s, self.host), self.user, self.passwd or b''))
378 382
379 def isabs(self): 383 def isabs(self) -> bool:
380 if self.scheme and self.scheme != b'file': 384 if self.scheme and self.scheme != b'file':
381 return True # remote URL 385 return True # remote URL
382 if hasdriveletter(self.path): 386 if hasdriveletter(self.path):
383 return True # absolute for our purposes - can't be joined() 387 return True # absolute for our purposes - can't be joined()
384 if self.path.startswith(br'\\'): 388 if self.path.startswith(br'\\'):
399 ): 403 ):
400 path = b'/' + path 404 path = b'/' + path
401 return path 405 return path
402 return self._origpath 406 return self._origpath
403 407
404 def islocal(self): 408 def islocal(self) -> bool:
405 '''whether localpath will return something that posixfile can open''' 409 '''whether localpath will return something that posixfile can open'''
406 return ( 410 return (
407 not self.scheme 411 not self.scheme
408 or self.scheme == b'file' 412 or self.scheme == b'file'
409 or self.scheme == b'bundle' 413 or self.scheme == b'bundle'