Skip to content

Commit

Permalink
Improve performance of methods that modify the network location (#1316)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 17, 2024
1 parent ee0e509 commit fcb8d7c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGES/1316.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved performance of :class:`~yarl.URL` methods that modify the network location -- by :user:`bdraco`.
31 changes: 20 additions & 11 deletions yarl/_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -1189,19 +1189,21 @@ def with_user(self, user: Union[str, None]) -> "URL":
"""
# N.B. doesn't cleanup query/fragment
val = self._val
scheme, netloc, path, query, fragment = self._val
if user is None:
password = None
elif isinstance(user, str):
user = self._QUOTER(user)
password = self.raw_password
else:
raise TypeError("Invalid user type")
if not val.netloc:
if not netloc:
raise ValueError("user replacement is not allowed for relative URLs")
encoded_host = self.host_subcomponent or ""
netloc = self._make_netloc(user, password, encoded_host, self.explicit_port)
return self._from_val(val._replace(netloc=netloc))
return self._from_val(
tuple.__new__(SplitResult, (scheme, netloc, path, query, fragment))
)

def with_password(self, password: Union[str, None]) -> "URL":
"""Return a new URL with password replaced.
Expand All @@ -1218,12 +1220,15 @@ def with_password(self, password: Union[str, None]) -> "URL":
password = self._QUOTER(password)
else:
raise TypeError("Invalid password type")
if not self._val.netloc:
scheme, netloc, path, query, fragment = self._val
if not netloc:
raise ValueError("password replacement is not allowed for relative URLs")
encoded_host = self.host_subcomponent or ""
port = self.explicit_port
netloc = self._make_netloc(self.raw_user, password, encoded_host, port)
return self._from_val(self._val._replace(netloc=netloc))
return self._from_val(
tuple.__new__(SplitResult, (scheme, netloc, path, query, fragment))
)

def with_host(self, host: str) -> "URL":
"""Return a new URL with host replaced.
Expand All @@ -1237,15 +1242,17 @@ def with_host(self, host: str) -> "URL":
# N.B. doesn't cleanup query/fragment
if not isinstance(host, str):
raise TypeError("Invalid host type")
val = self._val
if not val.netloc:
scheme, netloc, path, query, fragment = self._val
if not netloc:
raise ValueError("host replacement is not allowed for relative URLs")
if not host:
raise ValueError("host removing is not allowed")
encoded_host = self._encode_host(host, validate_host=True) if host else ""
port = self.explicit_port
netloc = self._make_netloc(self.raw_user, self.raw_password, encoded_host, port)
return self._from_val(val._replace(netloc=netloc))
return self._from_val(
tuple.__new__(SplitResult, (scheme, netloc, path, query, fragment))
)

def with_port(self, port: Union[int, None]) -> "URL":
"""Return a new URL with port replaced.
Expand All @@ -1259,12 +1266,14 @@ def with_port(self, port: Union[int, None]) -> "URL":
raise TypeError(f"port should be int or None, got {type(port)}")
if not (0 <= port <= 65535):
raise ValueError(f"port must be between 0 and 65535, got {port}")
val = self._val
if not val.netloc:
scheme, netloc, path, query, fragment = self._val
if not netloc:
raise ValueError("port replacement is not allowed for relative URLs")
encoded_host = self.host_subcomponent or ""
netloc = self._make_netloc(self.raw_user, self.raw_password, encoded_host, port)
return self._from_val(val._replace(netloc=netloc))
return self._from_val(
tuple.__new__(SplitResult, (scheme, netloc, path, query, fragment))
)

def with_path(self, path: str, *, encoded: bool = False) -> "URL":
"""Return a new URL with path replaced."""
Expand Down

0 comments on commit fcb8d7c

Please sign in to comment.