Mercurial > public > mercurial-scm > hg-stable
changeset 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 | bde94bd8e8a2 |
children | 180591a9a6a1 |
files | mercurial/interfaces/misc.py mercurial/utils/urlutil.py |
diffstat | 2 files changed, 72 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/interfaces/misc.py Sat Feb 08 18:15:18 2025 +0100 +++ b/mercurial/interfaces/misc.py Mon Feb 10 00:15:22 2025 +0100 @@ -9,7 +9,9 @@ Callable, Iterator, List, + Optional, Protocol, + Tuple, ) @@ -45,3 +47,64 @@ @abc.abstractmethod def __contains__(self, d: bytes) -> bool: ... + + +AuthInfoT = Tuple[ + bytes, + Optional[ + Tuple[ + None, + Tuple[bytes, bytes], + bytes, + bytes, + ] + ], +] + + +class IUrl(Protocol): + r"""Reliable URL parser. + + This parses URLs and provides attributes for the following + components: + + <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment> + + Missing components are set to None. The only exception is + fragment, which is set to '' if present but empty. + + If parsefragment is False, fragment is included in query. If + parsequery is False, query is included in path. If both are + False, both fragment and query are included in path. + + See http://www.ietf.org/rfc/rfc2396.txt for more information. + """ + + path: Optional[bytes] + scheme: Optional[bytes] + user: Optional[bytes] + passwd: Optional[bytes] + host: Optional[bytes] + port: Optional[bytes] + query: Optional[bytes] + fragment: Optional[bytes] + + @abc.abstractmethod + def copy(self) -> IUrl: + ... + + @abc.abstractmethod + def authinfo(self) -> AuthInfoT: + ... + + @abc.abstractmethod + def isabs(self) -> bool: + ... + + @abc.abstractmethod + def localpath(self) -> bytes: + ... + + @abc.abstractmethod + def islocal(self) -> bool: + ...
--- a/mercurial/utils/urlutil.py Sat Feb 08 18:15:18 2025 +0100 +++ b/mercurial/utils/urlutil.py Mon Feb 10 00:15:22 2025 +0100 @@ -30,6 +30,10 @@ stringutil, ) +from ..interfaces import ( + misc as int_misc, +) + from ..revlogutils import ( constants as revlog_constants, ) @@ -60,7 +64,7 @@ ) -class url: +class url(int_misc.IUrl): r"""Reliable URL parser. This parses URLs and provides attributes for the following @@ -244,7 +248,7 @@ if v is not None: setattr(self, a, urlreq.unquote(v)) - def copy(self): + def copy(self) -> url: u = url(b'temporary useless value') u.path = self.path u.scheme = self.scheme @@ -361,7 +365,7 @@ __str__ = encoding.strmethod(__bytes__) - def authinfo(self): + def authinfo(self) -> int_misc.AuthInfoT: user, passwd = self.user, self.passwd try: self.user, self.passwd = None, None @@ -376,7 +380,7 @@ # a password. return (s, (None, (s, self.host), self.user, self.passwd or b'')) - def isabs(self): + def isabs(self) -> bool: if self.scheme and self.scheme != b'file': return True # remote URL if hasdriveletter(self.path): @@ -401,7 +405,7 @@ return path return self._origpath - def islocal(self): + def islocal(self) -> bool: '''whether localpath will return something that posixfile can open''' return ( not self.scheme