From 07b2e84dff919060fe74c154a7ae4206fe01e814 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 27 Sep 2024 13:34:13 -0500 Subject: [PATCH] Improve performance of building URLs with authority (#1163) --- CHANGES/1163.misc.rst | 1 + tests/test_url_build.py | 25 +++++++++++++++++++++++++ yarl/_url.py | 11 ++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 CHANGES/1163.misc.rst diff --git a/CHANGES/1163.misc.rst b/CHANGES/1163.misc.rst new file mode 100644 index 000000000..a4976b747 --- /dev/null +++ b/CHANGES/1163.misc.rst @@ -0,0 +1 @@ +Improved performance of calling :py:meth:`~yarl.URL.build` with ``authority`` -- by :user:`bdraco`. diff --git a/tests/test_url_build.py b/tests/test_url_build.py index 0b7b9cd73..cc9b15f7e 100644 --- a/tests/test_url_build.py +++ b/tests/test_url_build.py @@ -153,6 +153,31 @@ def test_build_with_authority_without_encoding(): assert str(url) == "http://foo:bar@host.com:8000/path" +def test_build_with_authority_empty_host_no_scheme(): + url = URL.build(authority="", path="path") + assert str(url) == "path" + + +def test_build_with_authority_and_only_user(): + url = URL.build(scheme="https", authority="user:@foo.com", path="/path") + assert str(url) == "https://user:@foo.com/path" + + +def test_build_with_authority_with_port(): + url = URL.build(scheme="https", authority="foo.com:8080", path="/path") + assert str(url) == "https://foo.com:8080/path" + + +def test_build_with_authority_with_ipv6(): + url = URL.build(scheme="https", authority="[::1]", path="/path") + assert str(url) == "https://[::1]/path" + + +def test_build_with_authority_with_ipv6_and_port(): + url = URL.build(scheme="https", authority="[::1]:81", path="/path") + assert str(url) == "https://[::1]:81/path" + + def test_query_str(): u = URL.build(scheme="http", host="127.0.0.1", path="/", query_string="arg=value1") assert str(u) == "http://127.0.0.1/?arg=value1" diff --git a/yarl/_url.py b/yarl/_url.py index 25988f81d..65a91bb71 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -368,10 +368,15 @@ def build( if encoded: netloc = authority else: - tmp = SplitResult("", authority, "", "", "") - port = None if tmp.port == DEFAULT_PORTS.get(scheme) else tmp.port + _user, _password, _host, _port = cls._split_netloc(authority) + port = None if _port == DEFAULT_PORTS.get(scheme) else _port + _host = ( + "" + if _host is None + else cls._encode_host(_host, validate_host=False) + ) netloc = cls._make_netloc( - tmp.username, tmp.password, tmp.hostname, port, encode=True + _user, _password, _host, port, encode=True, encode_host=False ) elif not user and not password and not host and not port: netloc = ""