From 9a953d0017a345179e4a8aed9814abccc89327d3 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sun, 16 Aug 2026 06:55:19 +0200 Subject: [PATCH] lib.Uri: Fix stale cache in __new_with_path() __new_with_path() builds the new Uri by deep-copying self and then replacing __string. A deep copy, however, also carries over any cached_property values that were already computed on self (e.g. __p, path, scheme, full), so once __string changes, they stay stale: for a Uri on which any of those properties had been accessed before, new_add_path() and new_replace_path() returned objects whose to_string() showed the new string while path(), hostname(), full() and friends still described the old one. Build a fresh instance with object.__new__() and initialize its three basic attributes instead of copying, so no computed cached state can be inherited. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M and pi.dev Signed-off-by: Jan Lindemann --- src/python/jw/pkg/lib/Uri.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/python/jw/pkg/lib/Uri.py b/src/python/jw/pkg/lib/Uri.py index 6c299b31..cada582e 100644 --- a/src/python/jw/pkg/lib/Uri.py +++ b/src/python/jw/pkg/lib/Uri.py @@ -1,7 +1,5 @@ from __future__ import annotations -import copy - from functools import cached_property from typing import TYPE_CHECKING, override @@ -149,7 +147,10 @@ class Uri: ) def __new_with_path(self, base: str, path: str) -> Self: - ret = copy.deepcopy(self) + # -- Build a fresh instance rather than copying self: a copy would + # inherit computed cached_property values (e.g. __p, path, full), + # which would go stale as soon as __string is replaced below. + ret = object.__new__(type(self)) ret.__string = base ret.__username = None ret.__password = None -- 2.55.0