From 9262defaafb6f477332ae73cdd78a17b3f500a64 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Mon, 15 Aug 2022 16:59:02 -0700 Subject: [PATCH 1/4] Use strict optional checking in misc.py Two things to change here: First, I think the StreamWrapper code was buggy and it meant to patch an instance, not the class. It probably doesn't show up in practice because the encodings are the same. Second, urlparse's hostname can be None. While this isn't likely, I chose to put it in the signature rather than assert. I then need one assert when something from it gets added to `self.pip_trusted_origins` in another file. `self.pip_trusted_origins` genuinely assumes that hostname is not None, so the assert seemed fine. --- src/pip/_internal/network/session.py | 3 ++- src/pip/_internal/utils/misc.py | 18 ++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index e512ac78464..355bf201b01 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -422,7 +422,8 @@ def add_trusted_host( host_port = parse_netloc(host) if host_port not in self.pip_trusted_origins: - self.pip_trusted_origins.append(host_port) + assert host_port[0] is not None + self.pip_trusted_origins.append((host_port[0], host_port[1])) self.mount( build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index a8f4cb5cf56..9f2dd989cbf 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -1,6 +1,3 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - import contextlib import errno import getpass @@ -337,17 +334,18 @@ def write_output(msg: Any, *args: Any) -> None: class StreamWrapper(StringIO): - orig_stream: TextIO = None + orig_stream: TextIO @classmethod def from_stream(cls, orig_stream: TextIO) -> "StreamWrapper": - cls.orig_stream = orig_stream - return cls() + ret = cls() + ret.orig_stream = orig_stream + return ret # compileall.compile_dir() needs stdout.encoding to print to stdout - # https://github.com/python/mypy/issues/4125 + # type ignore is because TextIOBase.encoding is writeable @property - def encoding(self): # type: ignore + def encoding(self) -> str: # type: ignore return self.orig_stream.encoding @@ -415,7 +413,7 @@ def build_url_from_netloc(netloc: str, scheme: str = "https") -> str: return f"{scheme}://{netloc}" -def parse_netloc(netloc: str) -> Tuple[str, Optional[int]]: +def parse_netloc(netloc: str) -> Tuple[Optional[str], Optional[int]]: """ Return the host-port pair from a netloc. """ @@ -503,7 +501,7 @@ def _redact_netloc(netloc: str) -> Tuple[str]: return (redact_netloc(netloc),) -def split_auth_netloc_from_url(url: str) -> Tuple[str, str, Tuple[str, str]]: +def split_auth_netloc_from_url(url: str) -> Tuple[str, str, Tuple[Optional[str], Optional[str]]]: """ Parse a url into separate netloc, auth, and url with no auth. From d21832e62731334a057de101f4eb0c33ebddbcbf Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Mon, 15 Aug 2022 17:24:45 -0700 Subject: [PATCH 2/4] fix ci --- news/14514698-7F32-4890-97C1-7403A685733D.trivial.rst | 0 src/pip/_internal/utils/misc.py | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 news/14514698-7F32-4890-97C1-7403A685733D.trivial.rst diff --git a/news/14514698-7F32-4890-97C1-7403A685733D.trivial.rst b/news/14514698-7F32-4890-97C1-7403A685733D.trivial.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index 9f2dd989cbf..a3ca2d9abd5 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -501,7 +501,9 @@ def _redact_netloc(netloc: str) -> Tuple[str]: return (redact_netloc(netloc),) -def split_auth_netloc_from_url(url: str) -> Tuple[str, str, Tuple[Optional[str], Optional[str]]]: +def split_auth_netloc_from_url( + url: str, +) -> Tuple[str, str, Tuple[Optional[str], Optional[str]]]: """ Parse a url into separate netloc, auth, and url with no auth. From 4b1bd7fd329497bf0048ff84c2adda733ad50189 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Tue, 16 Aug 2022 14:24:04 -0700 Subject: [PATCH 3/4] validate host --- src/pip/_internal/network/session.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index 355bf201b01..7a7d10ac389 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -420,10 +420,11 @@ def add_trusted_host( msg += f" (from {source})" logger.info(msg) - host_port = parse_netloc(host) - if host_port not in self.pip_trusted_origins: - assert host_port[0] is not None - self.pip_trusted_origins.append((host_port[0], host_port[1])) + parsed_host, parsed_port = parse_netloc(host) + if parsed_host is None: + raise ValueError(f"Trusted host URL must include a host part: {host!r}") + if (parsed_host, parsed_port) not in self.pip_trusted_origins: + self.pip_trusted_origins.append((parsed_host, parsed_port)) self.mount( build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter From 69cf232b722f3724649c080f9fc1108edaa94706 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Tue, 16 Aug 2022 14:28:06 -0700 Subject: [PATCH 4/4] fixup --- src/pip/_internal/network/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index 7a7d10ac389..a445b05e5bb 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -430,7 +430,7 @@ def add_trusted_host( build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter ) self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter) - if not host_port[1]: + if not parsed_port: self.mount( build_url_from_netloc(host, scheme="http") + ":", self._trusted_host_adapter,