Conditionally bypass cache when adding styles.

Working on https://github.com/Textualize/textual/issues/1587 surfaced a caching issue that is best shown by running the code below:

```py
from rich.style import Style

meta = {"click": "something"}
s1 = Style.from_meta(meta)
s2 = Style.from_meta(meta)
print(s1.link_id, s2.link_id)  # Different link_id.

base = Style(color="red")
print((base + s1).link_id)  # This is the link_id of s1.
print((base + s2).link_id)  # This is the link_id of s1!
```

The change presented here will bypass cache when adding styles that have a link id but don't have a link attribute (if they did, so would the combined style and the call to .copy would refresh the link id either way).
Simply refreshing the link id will break Textual link highlighting.
This commit is contained in:
Rodrigo Girão Serrão 2023-09-26 13:26:57 +01:00
parent ec91917deb
commit 7fbcc6d7c7
No known key found for this signature in database
GPG key ID: 84116786F3295A35

View file

@ -729,8 +729,7 @@ class Style:
text = text or str(self)
sys.stdout.write(f"{self.render(text)}\n")
@lru_cache(maxsize=1024)
def _add(self, style: Optional["Style"]) -> "Style":
def _add_no_cache(self, style: Optional["Style"]) -> "Style":
if style is None or style._null:
return self
if self._null:
@ -754,8 +753,20 @@ class Style:
new_style._hash = None
return new_style
@lru_cache(maxsize=1024)
def _add(self, style: Optional["Style"]) -> "Style":
return self._add_no_cache(style)
def __add__(self, style: Optional["Style"]) -> "Style":
combined_style = self._add(style)
if (
style is not None
and not style._link
and not self._link
and (self._link_id or style._link_id)
):
combined_style = self._add_no_cache(style)
else:
combined_style = self._add(style)
return combined_style.copy() if combined_style.link else combined_style