From f0b6ee3e37a13b1358c78f3ccfb1f76f76934977 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:19:09 +0300 Subject: [PATCH] Fix relative file url repr --- CHANGES/648.bugfix.rst | 1 + tests/test_url.py | 17 +++++++++++++++++ yarl/_url.py | 11 +++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 CHANGES/648.bugfix.rst diff --git a/CHANGES/648.bugfix.rst b/CHANGES/648.bugfix.rst new file mode 100644 index 000000000..85cf127db --- /dev/null +++ b/CHANGES/648.bugfix.rst @@ -0,0 +1 @@ +Fix relative file url representation. diff --git a/tests/test_url.py b/tests/test_url.py index 2d4f1cba7..4b59e2723 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -52,6 +52,13 @@ def test_str(): assert str(url) == "http://example.com:8888/path/to?a=1&b=2" +def test_str_relative_file(): + url1 = URL("file:foo/bar") + assert str(url1) == "file:foo/bar" + url2 = URL("file:///foo/bar") + assert str(url2) == "file:///foo/bar" + + def test_repr(): url = URL("http://example.com") assert "URL('http://example.com')" == repr(url) @@ -1546,6 +1553,16 @@ def test_human_repr_non_printable(): ) +def test_human_repr_file(): + url = URL.build( + scheme="file", + path="foo/bar", + ) + s = url.human_repr() + assert URL(s) == url + assert s == "file:foo/bar" + + # relative diff --git a/yarl/_url.py b/yarl/_url.py index dfcff2ef3..b068c30f9 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -263,7 +263,7 @@ def __str__(self): val = self._val if not val.path and self.is_absolute() and (val.query or val.fragment): val = val._replace(path="/") - return urlunsplit(val) + return _urlunsplit(val) def __repr__(self): return f"{self.__class__.__name__}('{str(self)}')" @@ -1090,7 +1090,7 @@ def human_repr(self): for k, v in self.query.items() ) fragment = _human_quote(self.fragment, "") - return urlunsplit( + return _urlunsplit( SplitResult( self.scheme, self._make_netloc( @@ -1107,6 +1107,13 @@ def human_repr(self): ) +def _urlunsplit(s): + url = urlunsplit(s) + if s.scheme == "file" and not s.path.startswith("/"): + url = url.replace("///", "") + return url + + def _human_quote(s, unsafe): if not s: return s