Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of methods that modify the network location #1316

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
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
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 @@ -1187,19 +1187,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 @@ -1216,12 +1218,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 @@ -1235,15 +1240,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 @@ -1257,12 +1264,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