raise attribute error (#2443)

* raise attribute error

* fix compute defaults
This commit is contained in:
Will McGugan
2023-05-01 16:57:40 +01:00
committed by GitHub
parent ba90657559
commit 83b1fcc102
4 changed files with 17 additions and 6 deletions

View File

@@ -7,14 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased ## Unreleased
### Changed
- Setting attributes with a `compute_` method will now raise an `AttributeError` https://github.com/Textualize/textual/issues/2383
- Unknown psuedo-selectors will now raise a tokenizer error (previously they were silently ignored) https://github.com/Textualize/textual/pull/2445
### Added ### Added
- Watch methods can now optionally be private https://github.com/Textualize/textual/issues/2382 - Watch methods can now optionally be private https://github.com/Textualize/textual/issues/2382
### Changed
- Unknown psuedo-selectors will now raise a tokenizer error (previously they were silently ignored) https://github.com/Textualize/textual/pull/2445
## [0.22.3] - 2023-04-29 ## [0.22.3] - 2023-04-29
### Fixed ### Fixed

View File

@@ -174,6 +174,12 @@ class Reactive(Generic[ReactiveType]):
_rich_traceback_omit = True _rich_traceback_omit = True
self._initialize_reactive(obj, self.name) self._initialize_reactive(obj, self.name)
if hasattr(obj, self.compute_name):
raise AttributeError(
f"Can't set {obj}.{self.name!r}; reactive attributes with a compute method are read-only"
)
name = self.name name = self.name
current_value = getattr(obj, name) current_value = getattr(obj, name)
# Check for validate function # Check for validate function
@@ -276,7 +282,9 @@ class Reactive(Generic[ReactiveType]):
compute_method = getattr(obj, f"compute_{compute}") compute_method = getattr(obj, f"compute_{compute}")
except AttributeError: except AttributeError:
continue continue
current_value = getattr(obj, f"_reactive_{compute}") current_value = getattr(
obj, f"_reactive_{compute}", getattr(obj, f"_default_{compute}", None)
)
value = compute_method() value = compute_method()
setattr(obj, f"_reactive_{compute}", value) setattr(obj, f"_reactive_{compute}", value)
if value != current_value: if value != current_value:

View File

@@ -336,7 +336,6 @@ class ProgressBar(Widget, can_focus=False):
self.show_percentage = show_percentage self.show_percentage = show_percentage
self.show_eta = show_eta self.show_eta = show_eta
self.percentage = None
self.total = total self.total = total
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:

View File

@@ -356,6 +356,9 @@ async def test_compute():
app.start = 10 app.start = 10
assert app.count_double == 14 assert app.count_double == 14
with pytest.raises(AttributeError):
app.count_double = 100
async def test_watch_compute(): async def test_watch_compute():
"""Check that watching a computed attribute works.""" """Check that watching a computed attribute works."""