From e077b8d1a5a1ae8d2dc31b87ccee72cd28d83b17 Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Wed, 24 Jun 2026 12:16:42 +0200 Subject: [PATCH] fix: port setter caches scheme default in _port, leaking stale port on scheme change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The port setter stored DEFAULT_PORTS.get(self.scheme) in self._port when port=None was passed. This cached the scheme-dependent default port, which then became stale when the scheme later changed — the port property returned the cached value instead of the new scheme's default. Concrete bug (issue #143): set(scheme=None, netloc=None) on an https URL produced '//:443/hello' instead of '/hello', because netloc=None set _port=443 (the https default) before scheme=None cleared the scheme. Fix: store None in _port when port=None, letting the port getter's existing logic supply the scheme-appropriate default dynamically. Also removes the now-unnecessary _port cache assignment in load(). --- furl/furl.py | 4 +--- tests/test_furl.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/furl/furl.py b/furl/furl.py index cd6d710..64f1a2c 100644 --- a/furl/furl.py +++ b/furl/furl.py @@ -1407,8 +1407,6 @@ def load(self, url): self.netloc = tokens.netloc # Raises ValueError in Python 2.7+. self.scheme = tokens.scheme - if not self.port: - self._port = DEFAULT_PORTS.get(self.scheme) self.path.load(tokens.path) self.query.load(tokens.query) self.fragment.load(tokens.fragment) @@ -1469,7 +1467,7 @@ def port(self, port): Raises: ValueError on invalid port. """ if port is None: - self._port = DEFAULT_PORTS.get(self.scheme) + self._port = None elif is_valid_port(port): self._port = int(str(port)) else: diff --git a/tests/test_furl.py b/tests/test_furl.py index bc268c8..a411219 100644 --- a/tests/test_furl.py +++ b/tests/test_furl.py @@ -1511,7 +1511,7 @@ def test_basic_manipulation(self): assert str(f) == 'http://www.yahoo.com/?foo=eep' f.scheme = 'sup' - assert str(f) == 'sup://www.yahoo.com:80/?foo=eep' + assert str(f) == 'sup://www.yahoo.com/?foo=eep' f.port = None assert str(f) == 'sup://www.yahoo.com/?foo=eep'