From 04399eb70236912d2501a7731f25d02002e79ac5 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Tue, 5 Dec 2023 02:47:49 +0100 Subject: [PATCH] Exterminate offensive references from the project This change doesn't edit the test semantics, nor does it make any functional changes. It removes references to the ruscist culture that are as triggering to a lot of people as using "slave/master", "blacklist/whitelist" terminology. In particular, this gets rid of a link to the website that exists to justify ethnic cleansing in Crimea and genocides in Ukraine, being sponsored by the government of the terrorist state of muscovy. Ref https://github.com/aio-libs/yarl/issues/955#issuecomment-1819782920 --- README.rst | 10 +- benchmark.py | 4 +- docs/api.rst | 100 ++++++++++---------- docs/index.rst | 10 +- tests/test_url.py | 159 ++++++++++++++++---------------- tests/test_url_build.py | 46 +++++---- tests/test_url_update_netloc.py | 20 ++-- yarl/_url.py | 2 +- 8 files changed, 182 insertions(+), 169 deletions(-) diff --git a/README.rst b/README.rst index d4bd4e0c..844ffff6 100644 --- a/README.rst +++ b/README.rst @@ -74,9 +74,9 @@ automatically encoded giving canonical representation as result: .. code-block:: pycon - >>> url = URL('https://www.python.org/путь') + >>> url = URL('https://www.python.org/шлях') >>> url - URL('https://www.python.org/%D0%BF%D1%83%D1%82%D1%8C') + URL('https://www.python.org/%D1%88%D0%BB%D1%8F%D1%85') Regular properties are *percent-decoded*, use ``raw_`` versions for getting *encoded* strings: @@ -84,17 +84,17 @@ getting *encoded* strings: .. code-block:: pycon >>> url.path - '/путь' + '/шлях' >>> url.raw_path - '/%D0%BF%D1%83%D1%82%D1%8C' + '/%D1%88%D0%BB%D1%8F%D1%85' Human readable representation of URL is available as ``.human_repr()``: .. code-block:: pycon >>> url.human_repr() - 'https://www.python.org/путь' + 'https://www.python.org/шлях' For full documentation please read https://yarl.aio-libs.org. diff --git a/benchmark.py b/benchmark.py index e9741af6..a592f613 100644 --- a/benchmark.py +++ b/benchmark.py @@ -41,14 +41,14 @@ print( "Cython quote: {:.3f} sec".format( - timeit.timeit("q(s)", cython_setup + "s='/путь/файл';q=Quoter()") + timeit.timeit("q(s)", cython_setup + "s='/шлях/файл';q=Quoter()") ) ) print( "Python quote: {:.3f} sec".format( - timeit.timeit("q(s)", python_setup + "s='/путь/файл';q=Quoter()") + timeit.timeit("q(s)", python_setup + "s='/шлях/файл';q=Quoter()") ) ) diff --git a/docs/api.rst b/docs/api.rst index 03284c2e..5a4c3259 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -54,8 +54,8 @@ But for *non-ascii* case *encoding* is applied. .. doctest:: - >>> str(URL('http://εμπορικόσήμα.eu/путь/這裡')) - 'http://xn--jxagkqfkduily1i.eu/%D0%BF%D1%83%D1%82%D1%8C/%E9%80%99%E8%A3%A1' + >>> str(URL('http://εμπορικόσήμα.eu/шлях/這裡')) + 'http://xn--jxagkqfkduily1i.eu/%D1%88%D0%BB%D1%8F%D1%85/%E9%80%99%E8%A3%A1' The same is true for *user*, *password*, *query* and *fragment* parts of URL. @@ -70,11 +70,11 @@ Use :meth:`~URL.human_repr` for getting human readable representation: .. doctest:: - >>> url = URL('http://εμπορικόσήμα.eu/путь/這裡') + >>> url = URL('http://εμπορικόσήμα.eu/шлях/這裡') >>> str(url) - 'http://xn--jxagkqfkduily1i.eu/%D0%BF%D1%83%D1%82%D1%8C/%E9%80%99%E8%A3%A1' + 'http://xn--jxagkqfkduily1i.eu/%D1%88%D0%BB%D1%8F%D1%85/%E9%80%99%E8%A3%A1' >>> url.human_repr() - 'http://εμπορικόσήμα.eu/путь/這裡' + 'http://εμπορικόσήμα.eu/шлях/這裡' .. note:: @@ -120,8 +120,8 @@ There are two kinds of properties: *decoded* and *encoded* (with >>> URL('http://john@example.com').user 'john' - >>> URL('http://андрей@example.com').user - 'андрей' + >>> URL('http://бажан@example.com').user + 'бажан' >>> URL('http://example.com').user is None True @@ -133,8 +133,8 @@ There are two kinds of properties: *decoded* and *encoded* (with .. doctest:: - >>> URL('http://андрей@example.com').raw_user - '%D0%B0%D0%BD%D0%B4%D1%80%D0%B5%D0%B9' + >>> URL('http://довбуш@example.com').raw_user + '%D0%B4%D0%BE%D0%B2%D0%B1%D1%83%D1%88' >>> URL('http://example.com').raw_user is None True @@ -147,7 +147,7 @@ There are two kinds of properties: *decoded* and *encoded* (with >>> URL('http://john:pass@example.com').password 'pass' - >>> URL('http://андрей:пароль@example.com').password + >>> URL('http://степан:пароль@example.com').password 'пароль' >>> URL('http://example.com').password is None True @@ -265,8 +265,8 @@ There are two kinds of properties: *decoded* and *encoded* (with >>> URL('http://example.com/path/to').path '/path/to' - >>> URL('http://example.com/путь/сюда').path - '/путь/сюда' + >>> URL('http://example.com/шлях/сюди').path + '/шлях/сюди' >>> URL('http://example.com').path '/' @@ -287,8 +287,8 @@ There are two kinds of properties: *decoded* and *encoded* (with .. doctest:: - >>> URL('http://example.com/путь/сюда?ключ=знач').raw_path_qs - '/%D0%BF%D1%83%D1%82%D1%8C/%D1%81%D1%8E%D0%B4%D0%B0?%D0%BA%D0%BB%D1%8E%D1%87=%D0%B7%D0%BD%D0%B0%D1%87' + >>> URL('http://example.com/шлях/сюди?ключ=знач').raw_path_qs + '/%D1%88%D0%BB%D1%8F%D1%85/%D1%81%D1%8E%D0%B4%D0%B8?%D0%BA%D0%BB%D1%8E%D1%87=%D0%B7%D0%BD%D0%B0%D1%87' .. versionadded:: 0.15 @@ -298,8 +298,8 @@ There are two kinds of properties: *decoded* and *encoded* (with .. doctest:: - >>> URL('http://example.com/путь/сюда').raw_path - '/%D0%BF%D1%83%D1%82%D1%8C/%D1%81%D1%8E%D0%B4%D0%B0' + >>> URL('http://example.com/шлях/сюди').raw_path + '/%D1%88%D0%BB%D1%8F%D1%85/%D1%81%D1%8E%D0%B4%D0%B8' .. attribute:: URL.query_string @@ -333,8 +333,8 @@ There are two kinds of properties: *decoded* and *encoded* (with >>> URL('http://example.com/path#fragment').fragment 'fragment' - >>> URL('http://example.com/path#якорь').fragment - 'якорь' + >>> URL('http://example.com/path#якір').fragment + 'якір' >>> URL('http://example.com/path').fragment '' @@ -344,8 +344,8 @@ There are two kinds of properties: *decoded* and *encoded* (with .. doctest:: - >>> URL('http://example.com/path#якорь').raw_fragment - '%D1%8F%D0%BA%D0%BE%D1%80%D1%8C' + >>> URL('http://example.com/path#якір').raw_fragment + '%D1%8F%D0%BA%D1%96%D1%80' @@ -361,8 +361,8 @@ For *path* and *query* *yarl* supports additional helpers: >>> URL('http://example.com/path/to').parts ('/', 'path', 'to') - >>> URL('http://example.com/путь/сюда').parts - ('/', 'путь', 'сюда') + >>> URL('http://example.com/шлях/сюди').parts + ('/', 'шлях', 'сюди') >>> URL('http://example.com').parts ('/',) @@ -373,8 +373,8 @@ For *path* and *query* *yarl* supports additional helpers: .. doctest:: - >>> URL('http://example.com/путь/сюда').raw_parts - ('/', '%D0%BF%D1%83%D1%82%D1%8C', '%D1%81%D1%8E%D0%B4%D0%B0') + >>> URL('http://example.com/шлях/сюди').raw_parts + ('/', '%D1%88%D0%BB%D1%8F%D1%85', '%D1%81%D1%8E%D0%B4%D0%B8') .. attribute:: URL.name @@ -384,8 +384,8 @@ For *path* and *query* *yarl* supports additional helpers: >>> URL('http://example.com/path/to').name 'to' - >>> URL('http://example.com/путь/сюда').name - 'сюда' + >>> URL('http://example.com/шлях/сюди').name + 'сюди' >>> URL('http://example.com/path/').name '' @@ -395,8 +395,8 @@ For *path* and *query* *yarl* supports additional helpers: .. doctest:: - >>> URL('http://example.com/путь/сюда').raw_name - '%D1%81%D1%8E%D0%B4%D0%B0' + >>> URL('http://example.com/шлях/сюди').raw_name + '%D1%81%D1%8E%D0%B4%D0%B8' .. attribute:: URL.suffix @@ -406,8 +406,8 @@ For *path* and *query* *yarl* supports additional helpers: >>> URL('http://example.com/path/to.txt').suffix '.txt' - >>> URL('http://example.com/путь.сюда').suffix - '.сюда' + >>> URL('http://example.com/шлях.сюди').suffix + '.сюди' >>> URL('http://example.com/path').suffix '' @@ -417,8 +417,8 @@ For *path* and *query* *yarl* supports additional helpers: .. doctest:: - >>> URL('http://example.com/путь.сюда').raw_suffix - '.%D1%81%D1%8E%D0%B4%D0%B0' + >>> URL('http://example.com/шлях.сюди').raw_suffix + '.%D1%81%D1%8E%D0%B4%D0%B8' .. attribute:: URL.suffixes @@ -428,8 +428,8 @@ For *path* and *query* *yarl* supports additional helpers: >>> URL('http://example.com/path/to.tar.gz').suffixes ('.tar', '.gz') - >>> URL('http://example.com/путь.тут.да').suffixes - ('.тут', '.да') + >>> URL('http://example.com/шлях.тут.ось').suffixes + ('.тут', '.ось') >>> URL('http://example.com/path').suffixes () @@ -439,8 +439,8 @@ For *path* and *query* *yarl* supports additional helpers: .. doctest:: - >>> URL('http://example.com/путь.тут.да').raw_suffixes - ('.%D1%82%D1%83%D1%82', '.%D0%B4%D0%B0') + >>> URL('http://example.com/шлях.тут.ось').raw_suffixes + ('.%D1%82%D1%83%D1%82', '.%D0%BE%D1%81%D1%8C') .. attribute:: URL.query @@ -546,8 +546,8 @@ section generates a new :class:`URL` instance. >>> URL('http://user:pass@example.com').with_user('new_user') URL('http://new_user:pass@example.com') - >>> URL('http://user:pass@example.com').with_user('вася') - URL('http://%D0%B2%D0%B0%D1%81%D1%8F:pass@example.com') + >>> URL('http://user:pass@example.com').with_user('олекса') + URL('http://%D0%BE%D0%BB%D0%B5%D0%BA%D1%81%D0%B0:pass@example.com') >>> URL('http://user:pass@example.com').with_user(None) URL('http://example.com') @@ -739,8 +739,8 @@ section generates a new :class:`URL` instance. >>> URL('http://example.com/path#frag').with_fragment('anchor') URL('http://example.com/path#anchor') - >>> URL('http://example.com/path#frag').with_fragment('якорь') - URL('http://example.com/path#%D1%8F%D0%BA%D0%BE%D1%80%D1%8C') + >>> URL('http://example.com/path#frag').with_fragment('якір') + URL('http://example.com/path#%D1%8F%D0%BA%D1%96%D1%80') >>> URL('http://example.com/path#frag').with_fragment(None) URL('http://example.com/path') @@ -755,8 +755,8 @@ section generates a new :class:`URL` instance. >>> URL('http://example.com/path/to?arg#frag').with_name('new') URL('http://example.com/path/new') - >>> URL('http://example.com/path/to').with_name('имя') - URL('http://example.com/path/%D0%B8%D0%BC%D1%8F') + >>> URL('http://example.com/path/to').with_name("ім'я") + URL('http://example.com/path/%D1%96%D0%BC%27%D1%8F') .. method:: URL.with_suffix(suffix) @@ -769,8 +769,8 @@ section generates a new :class:`URL` instance. >>> URL('http://example.com/path/to?arg#frag').with_suffix('.doc') URL('http://example.com/path/to.doc') - >>> URL('http://example.com/path/to').with_suffix('.cуффикс') - URL('http://example.com/path/to.c%D1%83%D1%84%D1%84%D0%B8%D0%BA%D1%81') + >>> URL('http://example.com/path/to').with_suffix('.cуфікс') + URL('http://example.com/path/to.c%D1%83%D1%84%D1%96%D0%BA%D1%81') .. attribute:: URL.parent @@ -816,9 +816,9 @@ The path is encoded if needed. URL('http://example.com/path/to/subpath') >>> url.parts ('/', 'path', 'to', 'subpath') - >>> url = URL('http://example.com/path?arg#frag') / 'сюда' + >>> url = URL('http://example.com/path?arg#frag') / 'сюди' >>> url - URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B0') + URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B8') .. method:: URL.joinpath(*other, encoded=False) @@ -835,12 +835,12 @@ The path is encoded if needed. URL('http://example.com/path/to/subpath') >>> url.parts ('/', 'path', 'to', 'subpath') - >>> url = URL('http://example.com/path?arg#frag').joinpath('сюда') + >>> url = URL('http://example.com/path?arg#frag').joinpath('сюди') >>> url - URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B0') - >>> url = URL('http://example.com/path').joinpath('%D1%81%D1%8E%D0%B4%D0%B0', encoded=True) + URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B8') + >>> url = URL('http://example.com/path').joinpath('%D1%81%D1%8E%D0%B4%D0%B8', encoded=True) >>> url - URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B0') + URL('http://example.com/path/%D1%81%D1%8E%D0%B4%D0%B8') .. versionadded:: 1.9 diff --git a/docs/index.rst b/docs/index.rst index 50c930f2..1e4e64b6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -61,9 +61,9 @@ automatically encoded giving canonical representation as result: .. doctest:: - >>> url = URL('https://www.python.org/путь') + >>> url = URL('https://www.python.org/шлях') >>> url - URL('https://www.python.org/%D0%BF%D1%83%D1%82%D1%8C') + URL('https://www.python.org/%D1%88%D0%BB%D1%8F%D1%85') Regular properties are *percent-decoded*, use ``raw_`` versions for getting *encoded* strings: @@ -71,17 +71,17 @@ getting *encoded* strings: .. doctest:: >>> url.path - '/путь' + '/шлях' >>> url.raw_path - '/%D0%BF%D1%83%D1%82%D1%8C' + '/%D1%88%D0%BB%D1%8F%D1%85' Human readable representation of URL is available as :meth:`~yarl.URL.human_repr`: .. doctest:: >>> url.human_repr() - 'https://www.python.org/путь' + 'https://www.python.org/шлях' For full documentation please read :ref:`yarl-api` section. diff --git a/tests/test_url.py b/tests/test_url.py index 295c0639..725e9465 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -64,8 +64,8 @@ def test_origin(): def test_origin_nonascii(): - url = URL("http://user:password@историк.рф:8888/path/to?a=1&b=2") - assert str(url.origin()) == "http://xn--h1aagokeh.xn--p1ai:8888" + url = URL("http://user:password@оун-упа.укр:8888/path/to?a=1&b=2") + assert str(url.origin()) == "http://xn----8sb1bdhvc.xn--j1amh:8888" def test_origin_ipv6(): @@ -117,8 +117,8 @@ def test_raw_user(): def test_raw_user_non_ascii(): - url = URL("http://вася@example.com") - assert "%D0%B2%D0%B0%D1%81%D1%8F" == url.raw_user + url = URL("http://бажан@example.com") + assert "%D0%B1%D0%B0%D0%B6%D0%B0%D0%BD" == url.raw_user def test_no_user(): @@ -127,8 +127,8 @@ def test_no_user(): def test_user_non_ascii(): - url = URL("http://вася@example.com") - assert "вася" == url.user + url = URL("http://бажан@example.com") + assert "бажан" == url.user def test_raw_password(): @@ -164,13 +164,13 @@ def test_raw_host(): def test_raw_host_non_ascii(): - url = URL("http://историк.рф") - assert "xn--h1aagokeh.xn--p1ai" == url.raw_host + url = URL("http://оун-упа.укр") + assert "xn----8sb1bdhvc.xn--j1amh" == url.raw_host def test_host_non_ascii(): - url = URL("http://историк.рф") - assert "историк.рф" == url.host + url = URL("http://оун-упа.укр") + assert "оун-упа.укр" == url.host def test_localhost(): @@ -210,12 +210,13 @@ def test_authority_short() -> None: def test_authority_full_nonasci() -> None: - url = URL("http://ваня:пароль@айдеко.рф:8080/path") + url = URL("http://степан:пароль@слава.укр:8080/path") assert url.raw_authority == ( - "%D0%B2%D0%B0%D0%BD%D1%8F:%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C@" - "xn--80aidohy.xn--p1ai:8080" + "%D1%81%D1%82%D0%B5%D0%BF%D0%B0%D0%BD:" + "%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C@" + "xn--80aaf8a3a.xn--j1amh:8080" ) - assert url.authority == "ваня:пароль@айдеко.рф:8080" + assert url.authority == "степан:пароль@слава.укр:8080" def test_lowercase(): @@ -225,9 +226,9 @@ def test_lowercase(): def test_lowercase_nonascii(): - url = URL("http://Айдеко.Рф") - assert url.raw_host == "xn--80aidohy.xn--p1ai" - assert url.host == "айдеко.рф" + url = URL("http://Слава.Укр") + assert url.raw_host == "xn--80aaf8a3a.xn--j1amh" + assert url.host == "слава.укр" def test_compressed_ipv6(): @@ -294,13 +295,13 @@ def test_raw_path(): def test_raw_path_non_ascii(): - url = URL("http://example.com/путь/сюда") - assert "/%D0%BF%D1%83%D1%82%D1%8C/%D1%81%D1%8E%D0%B4%D0%B0" == url.raw_path + url = URL("http://example.com/шлях/сюди") + assert "/%D1%88%D0%BB%D1%8F%D1%85/%D1%81%D1%8E%D0%B4%D0%B8" == url.raw_path def test_path_non_ascii(): - url = URL("http://example.com/путь/сюда") - assert "/путь/сюда" == url.path + url = URL("http://example.com/шлях/сюди") + assert "/шлях/сюди" == url.path def test_path_with_spaces(): @@ -352,8 +353,8 @@ def test_raw_path_qs(): assert url.raw_path_qs == "/?%D0%B1=%D0%B2&%D1%8E=%D0%BA" url = URL("http://example.com/path?б=в&ю=к") assert url.raw_path_qs == "/path?%D0%B1=%D0%B2&%D1%8E=%D0%BA" - url = URL("http://example.com/путь?a=1&b=2") - assert url.raw_path_qs == "/%D0%BF%D1%83%D1%82%D1%8C?a=1&b=2" + url = URL("http://example.com/шлях?a=1&b=2") + assert url.raw_path_qs == "/%D1%88%D0%BB%D1%8F%D1%85?a=1&b=2" def test_query_string_spaces(): @@ -375,8 +376,8 @@ def test_raw_fragment(): def test_raw_fragment_non_ascii(): - url = URL("http://example.com/path#якорь") - assert "%D1%8F%D0%BA%D0%BE%D1%80%D1%8C" == url.raw_fragment + url = URL("http://example.com/path#якір") + assert "%D1%8F%D0%BA%D1%96%D1%80" == url.raw_fragment def test_raw_fragment_safe(): @@ -385,8 +386,8 @@ def test_raw_fragment_safe(): def test_fragment_non_ascii(): - url = URL("http://example.com/path#якорь") - assert "якорь" == url.fragment + url = URL("http://example.com/path#якір") + assert "якір" == url.fragment def test_raw_parts_empty(): @@ -435,17 +436,17 @@ def test_parts_for_empty_url(): def test_raw_parts_non_ascii(): - url = URL("http://example.com/путь/сюда") + url = URL("http://example.com/шлях/сюди") assert ( "/", - "%D0%BF%D1%83%D1%82%D1%8C", - "%D1%81%D1%8E%D0%B4%D0%B0", + "%D1%88%D0%BB%D1%8F%D1%85", + "%D1%81%D1%8E%D0%B4%D0%B8", ) == url.raw_parts def test_parts_non_ascii(): - url = URL("http://example.com/путь/сюда") - assert ("/", "путь", "сюда") == url.parts + url = URL("http://example.com/шлях/сюди") + assert ("/", "шлях", "сюди") == url.parts def test_name_for_empty_url(): @@ -489,8 +490,8 @@ def test_relative_raw_name_slash(): def test_name_non_ascii(): - url = URL("http://example.com/путь") - assert url.name == "путь" + url = URL("http://example.com/шлях") + assert url.name == "шлях" def test_suffix_for_empty_url(): @@ -534,8 +535,8 @@ def test_relative_raw_suffix_dot(): def test_suffix_non_ascii(): - url = URL("http://example.com/путь.суффикс") - assert url.suffix == ".суффикс" + url = URL("http://example.com/шлях.суфікс") + assert url.suffix == ".суфікс" def test_suffix_with_empty_name(): @@ -594,8 +595,8 @@ def test_relative_raw_suffixes_dot(): def test_suffixes_non_ascii(): - url = URL("http://example.com/путь.суффикс") - assert url.suffixes == (".суффикс",) + url = URL("http://example.com/шлях.суфікс") + assert url.suffixes == (".суфікс",) def test_suffixes_with_empty_name(): @@ -753,15 +754,15 @@ def test_div_for_relative_url_started_with_slash(): def test_div_non_ascii(): - url = URL("http://example.com/сюда") - url2 = url / "туда" - assert url2.path == "/сюда/туда" - assert url2.raw_path == "/%D1%81%D1%8E%D0%B4%D0%B0/%D1%82%D1%83%D0%B4%D0%B0" - assert url2.parts == ("/", "сюда", "туда") + url = URL("http://example.com/сюди") + url2 = url / "туди" + assert url2.path == "/сюди/туди" + assert url2.raw_path == "/%D1%81%D1%8E%D0%B4%D0%B8/%D1%82%D1%83%D0%B4%D0%B8" + assert url2.parts == ("/", "сюди", "туди") assert url2.raw_parts == ( "/", - "%D1%81%D1%8E%D0%B4%D0%B0", - "%D1%82%D1%83%D0%B4%D0%B0", + "%D1%81%D1%8E%D0%B4%D0%B8", + "%D1%82%D1%83%D0%B4%D0%B8", ) @@ -846,13 +847,13 @@ def test_joinpath_relative(url, to_join, expected): "url,to_join,encoded,e_path,e_raw_path,e_parts,e_raw_parts", [ pytest.param( - "http://example.com/сюда", - ("туда",), + "http://example.com/сюди", + ("туди",), False, - "/сюда/туда", - "/%D1%81%D1%8E%D0%B4%D0%B0/%D1%82%D1%83%D0%B4%D0%B0", - ("/", "сюда", "туда"), - ("/", "%D1%81%D1%8E%D0%B4%D0%B0", "%D1%82%D1%83%D0%B4%D0%B0"), + "/сюди/туди", + "/%D1%81%D1%8E%D0%B4%D0%B8/%D1%82%D1%83%D0%B4%D0%B8", + ("/", "сюди", "туди"), + ("/", "%D1%81%D1%8E%D0%B4%D0%B8", "%D1%82%D1%83%D0%B4%D0%B8"), id="non-ascii", ), pytest.param( @@ -1093,11 +1094,11 @@ def test_with_name_empty(): def test_with_name_non_ascii(): - url = URL("http://example.com/path").with_name("путь") - assert url.path == "/путь" - assert url.raw_path == "/%D0%BF%D1%83%D1%82%D1%8C" - assert url.parts == ("/", "путь") - assert url.raw_parts == ("/", "%D0%BF%D1%83%D1%82%D1%8C") + url = URL("http://example.com/path").with_name("шлях") + assert url.path == "/шлях" + assert url.raw_path == "/%D1%88%D0%BB%D1%8F%D1%85" + assert url.parts == ("/", "шлях") + assert url.raw_parts == ("/", "%D1%88%D0%BB%D1%8F%D1%85") def test_with_name_percent_encoded(): @@ -1185,11 +1186,11 @@ def test_with_suffix_empty(): def test_with_suffix_non_ascii(): - url = URL("http://example.com/path").with_suffix(".путь") - assert url.path == "/path.путь" - assert url.raw_path == "/path.%D0%BF%D1%83%D1%82%D1%8C" - assert url.parts == ("/", "path.путь") - assert url.raw_parts == ("/", "path.%D0%BF%D1%83%D1%82%D1%8C") + url = URL("http://example.com/path").with_suffix(".шлях") + assert url.path == "/path.шлях" + assert url.raw_path == "/path.%D1%88%D0%BB%D1%8F%D1%85" + assert url.parts == ("/", "path.шлях") + assert url.raw_parts == ("/", "path.%D1%88%D0%BB%D1%8F%D1%85") def test_with_suffix_percent_encoded(): @@ -1340,8 +1341,8 @@ def test_from_ascii_login(): def test_from_non_ascii_login(): - url = URL("http://вася@host:1234/") - assert ("http://" "%D0%B2%D0%B0%D1%81%D1%8F" "@host:1234/") == str(url) + url = URL("http://бажан@host:1234/") + assert ("http://%D0%B1%D0%B0%D0%B6%D0%B0%D0%BD@host:1234/") == str(url) def test_from_ascii_login_and_password(): @@ -1360,10 +1361,10 @@ def test_from_ascii_login_and_password(): def test_from_non_ascii_login_and_password(): - url = URL("http://вася:пароль@host:1234/") + url = URL("http://бажан:пароль@host:1234/") assert ( "http://" - "%D0%B2%D0%B0%D1%81%D1%8F" + "%D0%B1%D0%B0%D0%B6%D0%B0%D0%BD" ":%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C" "@host:1234/" ) == str(url) @@ -1384,16 +1385,16 @@ def test_from_ascii_path_lower_case(): def test_from_non_ascii_path(): - url = URL("http://example.com/путь/туда") + url = URL("http://example.com/шлях/туди") assert ( - "http://example.com/" "%D0%BF%D1%83%D1%82%D1%8C/%D1%82%D1%83%D0%B4%D0%B0" + "http://example.com/%D1%88%D0%BB%D1%8F%D1%85/%D1%82%D1%83%D0%B4%D0%B8" ) == str(url) def test_bytes(): - url = URL("http://example.com/путь/туда") + url = URL("http://example.com/шлях/туди") assert ( - b"http://example.com/%D0%BF%D1%83%D1%82%D1%8C/%D1%82%D1%83%D0%B4%D0%B0" + b"http://example.com/%D1%88%D0%BB%D1%8F%D1%85/%D1%82%D1%83%D0%B4%D0%B8" == bytes(url) ) @@ -1610,23 +1611,23 @@ def test_split_result_non_decoded(): def test_human_repr(): - url = URL("http://вася:пароль@хост.домен:8080/путь/сюда?арг=вал#фраг") + url = URL("http://бажан:пароль@хост.домен:8080/шлях/сюди?арг=вал#фраг") s = url.human_repr() assert URL(s) == url - assert s == "http://вася:пароль@хост.домен:8080/путь/сюда?арг=вал#фраг" + assert s == "http://бажан:пароль@хост.домен:8080/шлях/сюди?арг=вал#фраг" def test_human_repr_defaults(): - url = URL("путь") + url = URL("шлях") s = url.human_repr() - assert s == "путь" + assert s == "шлях" def test_human_repr_default_port(): - url = URL("http://вася:пароль@хост.домен/путь/сюда?арг=вал#фраг") + url = URL("http://бажан:пароль@хост.домен/шлях/сюди?арг=вал#фраг") s = url.human_repr() assert URL(s) == url - assert s == "http://вася:пароль@хост.домен/путь/сюда?арг=вал#фраг" + assert s == "http://бажан:пароль@хост.домен/шлях/сюди?арг=вал#фраг" def test_human_repr_ipv6(): @@ -1667,20 +1668,20 @@ def test_human_repr_delimiters(): def test_human_repr_non_printable(): url = URL.build( scheme="http", - user="вася\n\xad\u200b", + user="бажан\n\xad\u200b", password="пароль\n\xad\u200b", host="хост.домен", port=8080, - path="/путь\n\xad\u200b", + path="/шлях\n\xad\u200b", query={"арг\n\xad\u200b": "вал\n\xad\u200b"}, fragment="фраг\n\xad\u200b", ) s = url.human_repr() assert URL(s) == url assert ( - s == "http://вася%0A%C2%AD%E2%80%8B:пароль%0A%C2%AD%E2%80%8B" + s == "http://бажан%0A%C2%AD%E2%80%8B:пароль%0A%C2%AD%E2%80%8B" "@хост.домен:8080" - "/путь%0A%C2%AD%E2%80%8B" + "/шлях%0A%C2%AD%E2%80%8B" "?арг%0A%C2%AD%E2%80%8B=вал%0A%C2%AD%E2%80%8B" "#фраг%0A%C2%AD%E2%80%8B" ) diff --git a/tests/test_url_build.py b/tests/test_url_build.py index ed077368..5aecbc58 100644 --- a/tests/test_url_build.py +++ b/tests/test_url_build.py @@ -101,8 +101,10 @@ def test_build_with_authority_and_host(): def test_build_with_authority(): - url = URL.build(scheme="http", authority="ваня:bar@host.com:8000", path="path") - assert str(url) == "http://%D0%B2%D0%B0%D0%BD%D1%8F:bar@host.com:8000/path" + url = URL.build(scheme="http", authority="степан:bar@host.com:8000", path="path") + assert ( + str(url) == "http://%D1%81%D1%82%D0%B5%D0%BF%D0%B0%D0%BD:bar@host.com:8000/path" + ) def test_build_with_authority_without_encoding(): @@ -125,23 +127,33 @@ def test_query_dict(): def test_build_path_quoting(): u = URL.build( - scheme="http", host="127.0.0.1", path="/файл.jpg", query=dict(arg="Привет") + scheme="http", + host="127.0.0.1", + path="/фотографія.jpg", + query=dict(arg="Привіт"), ) - assert u == URL("http://127.0.0.1/файл.jpg?arg=Привет") + assert u == URL("http://127.0.0.1/фотографія.jpg?arg=Привіт") assert str(u) == ( - "http://127.0.0.1/%D1%84%D0%B0%D0%B9%D0%BB.jpg?" - "arg=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82" + "http://127.0.0.1/" + "%D1%84%D0%BE%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D1%96%D1%8F.jpg?" + "arg=%D0%9F%D1%80%D0%B8%D0%B2%D1%96%D1%82" ) def test_build_query_quoting(): - u = URL.build(scheme="http", host="127.0.0.1", path="/файл.jpg", query="arg=Привет") + u = URL.build( + scheme="http", + host="127.0.0.1", + path="/фотографія.jpg", + query="arg=Привіт", + ) - assert u == URL("http://127.0.0.1/файл.jpg?arg=Привет") + assert u == URL("http://127.0.0.1/фотографія.jpg?arg=Привіт") assert str(u) == ( - "http://127.0.0.1/%D1%84%D0%B0%D0%B9%D0%BB.jpg?" - "arg=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82" + "http://127.0.0.1/" + "%D1%84%D0%BE%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D1%96%D1%8F.jpg?" + "arg=%D0%9F%D1%80%D0%B8%D0%B2%D1%96%D1%82" ) @@ -159,14 +171,14 @@ def test_build_drop_dots(): def test_build_encode(): u = URL.build( scheme="http", - host="историк.рф", - path="/путь/файл", + host="оун-упа.укр", + path="/шлях/криївка", query_string="ключ=знач", fragment="фраг", ) expected = ( - "http://xn--h1aagokeh.xn--p1ai" - "/%D0%BF%D1%83%D1%82%D1%8C/%D1%84%D0%B0%D0%B9%D0%BB" + "http://xn----8sb1bdhvc.xn--j1amh" + "/%D1%88%D0%BB%D1%8F%D1%85/%D0%BA%D1%80%D0%B8%D1%97%D0%B2%D0%BA%D0%B0" "?%D0%BA%D0%BB%D1%8E%D1%87=%D0%B7%D0%BD%D0%B0%D1%87" "#%D1%84%D1%80%D0%B0%D0%B3" ) @@ -177,13 +189,13 @@ def test_build_already_encoded(): # resulting URL is invalid but not encoded u = URL.build( scheme="http", - host="историк.рф", - path="/путь/файл", + host="оун-упа.укр", + path="/шлях/криївка", query_string="ключ=знач", fragment="фраг", encoded=True, ) - assert str(u) == "http://историк.рф/путь/файл?ключ=знач#фраг" + assert str(u) == "http://оун-упа.укр/шлях/криївка?ключ=знач#фраг" def test_build_percent_encoded(): diff --git a/tests/test_url_update_netloc.py b/tests/test_url_update_netloc.py index cf0cc1c4..47d13bcd 100644 --- a/tests/test_url_update_netloc.py +++ b/tests/test_url_update_netloc.py @@ -33,11 +33,11 @@ def test_with_user(): def test_with_user_non_ascii(): url = URL("http://example.com") - url2 = url.with_user("вася") - assert url2.raw_user == "%D0%B2%D0%B0%D1%81%D1%8F" - assert url2.user == "вася" - assert url2.raw_authority == "%D0%B2%D0%B0%D1%81%D1%8F@example.com" - assert url2.authority == "вася@example.com:80" + url2 = url.with_user("бажан") + assert url2.raw_user == "%D0%B1%D0%B0%D0%B6%D0%B0%D0%BD" + assert url2.user == "бажан" + assert url2.raw_authority == "%D0%B1%D0%B0%D0%B6%D0%B0%D0%BD@example.com" + assert url2.authority == "бажан@example.com:80" def test_with_user_percent_encoded(): @@ -159,11 +159,11 @@ def test_with_host_empty(): def test_with_host_non_ascii(): url = URL("http://example.com:123") - url2 = url.with_host("историк.рф") - assert url2.raw_host == "xn--h1aagokeh.xn--p1ai" - assert url2.host == "историк.рф" - assert url2.raw_authority == "xn--h1aagokeh.xn--p1ai:123" - assert url2.authority == "историк.рф:123" + url2 = url.with_host("оун-упа.укр") + assert url2.raw_host == "xn----8sb1bdhvc.xn--j1amh" + assert url2.host == "оун-упа.укр" + assert url2.raw_authority == "xn----8sb1bdhvc.xn--j1amh:123" + assert url2.authority == "оун-упа.укр:123" def test_with_host_percent_encoded(): diff --git a/yarl/_url.py b/yarl/_url.py index d5202db1..9cca27ef 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -509,7 +509,7 @@ def host(self): return None if "%" in raw: # Hack for scoped IPv6 addresses like - # fe80::2%Проверка + # fe80::2%Перевірка # presence of '%' sign means only IPv6 address, so idna is useless. return raw return _idna_decode(raw)