Skip to content

Commit 37b04d2

Browse files
authored
Improve performances of URL.joinpath (#1418)
1 parent 14c3759 commit 37b04d2

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

CHANGES/1418.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved performance of the :py:meth:`~yarl.URL.joinpath` method -- by :user:`bdraco`.

yarl/_url.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -987,28 +987,29 @@ def _make_child(self, paths: "Sequence[str]", encoded: bool = False) -> "URL":
987987
segments = path.split("/")
988988
segments.reverse()
989989
# remove trailing empty segment for all but the last path
990-
segment_slice_start = int(not last and segments[0] == "")
991-
parsed += segments[segment_slice_start:]
992-
parsed.reverse()
990+
parsed += segments[1:] if not last and segments[0] == "" else segments
993991

994-
path = self._path
995-
if path and (old_path_segments := path.split("/")):
992+
if (path := self._path) and (old_segments := path.split("/")):
996993
# If the old path ends with a slash, the last segment is an empty string
997994
# and should be removed before adding the new path segments.
998-
old_path_cutoff = -1 if old_path_segments[-1] == "" else None
999-
parsed = [*old_path_segments[:old_path_cutoff], *parsed]
995+
old = old_segments[:-1] if old_segments[-1] == "" else old_segments
996+
old.reverse()
997+
parsed += old
1000998

1001-
if netloc := self._netloc:
1002-
# If the netloc is present, we need to ensure that the path is normalized
1003-
parsed = normalize_path_segments(parsed) if needs_normalize else parsed
1004-
if parsed and parsed[0] != "":
1005-
# inject a leading slash when adding a path to an absolute URL
1006-
# where there was none before
1007-
parsed = ["", *parsed]
999+
# If the netloc is present, inject a leading slash when adding a
1000+
# path to an absolute URL where there was none before.
1001+
if (netloc := self._netloc) and parsed and parsed[-1] != "":
1002+
parsed.append("")
10081003

1009-
new_path = "/".join(parsed)
1004+
parsed.reverse()
1005+
if not netloc or not needs_normalize:
1006+
return self._from_parts(self._scheme, netloc, "/".join(parsed), "", "")
10101007

1011-
return self._from_parts(self._scheme, netloc, new_path, "", "")
1008+
path = "/".join(normalize_path_segments(parsed))
1009+
# If normalizing the path segments removed the leading slash, add it back.
1010+
if path and path[0] != "/":
1011+
path = f"/{path}"
1012+
return self._from_parts(self._scheme, netloc, path, "", "")
10121013

10131014
def with_scheme(self, scheme: str) -> "URL":
10141015
"""Return a new URL with scheme replaced."""

0 commit comments

Comments
 (0)