diff --git a/src/hyperlink/_url.py b/src/hyperlink/_url.py index 8797b5c..0c4b82b 100644 --- a/src/hyperlink/_url.py +++ b/src/hyperlink/_url.py @@ -479,7 +479,7 @@ def register_scheme( text, uses_netloc=True, default_port=None, query_plus_is_space=True ): # type: (Text, bool, Optional[int], bool) -> None - """Registers new scheme information, resulting in correct port and + """Registers or updates scheme information, resulting in correct port and slash behavior from the URL object. There are dozens of standard schemes preregistered, so this function is mostly meant for proprietary internal customizations or stopgaps on missing @@ -510,6 +510,7 @@ def register_scheme( ) if uses_netloc is True: + NO_NETLOC_SCHEMES.discard(text) SCHEME_PORT_MAP[text] = default_port elif uses_netloc is False: if default_port is not None: @@ -517,11 +518,14 @@ def register_scheme( "unexpected default port while specifying" " non-netloc scheme: %r" % default_port ) + SCHEME_PORT_MAP.pop(text, None) NO_NETLOC_SCHEMES.add(text) else: raise ValueError("uses_netloc expected bool, not: %r" % uses_netloc) - if not query_plus_is_space: + if query_plus_is_space: + NO_QUERY_PLUS_SCHEMES.discard(text) + else: NO_QUERY_PLUS_SCHEMES.add(text) return diff --git a/src/hyperlink/test/test_scheme_registration.py b/src/hyperlink/test/test_scheme_registration.py index b43c91e..bb508d6 100644 --- a/src/hyperlink/test/test_scheme_registration.py +++ b/src/hyperlink/test/test_scheme_registration.py @@ -13,11 +13,13 @@ def setUp(self): # type: () -> None self._orig_scheme_port_map = dict(_url.SCHEME_PORT_MAP) self._orig_no_netloc_schemes = set(_url.NO_NETLOC_SCHEMES) + self._orig_no_query_plus_schemes = set(_url.NO_QUERY_PLUS_SCHEMES) def tearDown(self): # type: () -> None _url.SCHEME_PORT_MAP = self._orig_scheme_port_map _url.NO_NETLOC_SCHEMES = self._orig_no_netloc_schemes + _url.NO_QUERY_PLUS_SCHEMES = self._orig_no_query_plus_schemes def test_register_scheme_basic(self): # type: () -> None @@ -49,6 +51,32 @@ def test_register_no_netloc_scheme(self): u4 = u4.replace(path=("example", "path")) assert u4.to_text() == "noloctron:example/path" + def test_reregister_scheme_replaces_previous_settings(self): + # type: () -> None + register_scheme( + "switchable", + uses_netloc=True, + default_port=8080, + query_plus_is_space=False, + ) + register_scheme( + "switchable", uses_netloc=False, query_plus_is_space=True + ) + + assert _url.scheme_uses_netloc("switchable") is False + assert "switchable" not in _url.SCHEME_PORT_MAP + assert "switchable" not in _url.NO_QUERY_PLUS_SCHEMES + decoded = DecodedURL.from_text("switchable:path?q=a+b") + assert decoded.get("q") == ["a b"] + + register_scheme("switchable", uses_netloc=True, default_port=8080) + assert _url.scheme_uses_netloc("switchable") is True + assert "switchable" not in _url.NO_NETLOC_SCHEMES + assert "switchable" not in _url.NO_QUERY_PLUS_SCHEMES + assert URL.from_text("switchable://example.com").port == 8080 + decoded = DecodedURL.from_text("switchable://example.com/?q=a+b") + assert decoded.get("q") == ["a b"] + def test_register_no_netloc_with_port(self): # type: () -> None with self.assertRaises(ValueError):