Skip to content

fix: port property leaks stale scheme default when scheme changes#191

Open
gaoflow wants to merge 1 commit into
gruns:masterfrom
gaoflow:fix-port-scheme-interaction
Open

fix: port property leaks stale scheme default when scheme changes#191
gaoflow wants to merge 1 commit into
gruns:masterfrom
gaoflow:fix-port-scheme-interaction

Conversation

@gaoflow

@gaoflow gaoflow commented Jun 24, 2026

Copy link
Copy Markdown

The port setter stores DEFAULT_PORTS.get(self.scheme) in self._port when port=None. This caches the scheme-dependent default port, which becomes stale when the scheme later changes -- the port property returns the cached value instead of the new scheme's default.

Concrete reproduction:

from furl import furl

f = furl('https://www.google.com/hello')
f.copy().set(scheme=None, netloc=None).url
# Expected: '/hello'
# Actual:   '//:443/hello'  (port 443 leaks from the old https scheme)

Root cause: netloc=None processes before scheme=None in set(), so port=None caches DEFAULT_PORTS['https']=443 before the scheme is cleared.

Fix: store None in _port when port=None, letting the port getter's existing self._port or DEFAULT_PORTS.get(self.scheme) logic supply the scheme-appropriate default dynamically at access time. This also fixes the case where port=None followed by scheme='https' previously returned port 80 instead of 443.

Also removes the now-unnecessary _port cache assignment in load().

Fixes #143.

…n scheme change

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 gruns#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().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

default port not properly removed with set(netloc=None) and weird interaction with set(scheme=None)

1 participant