Closed mzebrak closed 1 year ago
I can't reproduce any issue with that code. The error you mention in a comment suggests you are running an older version of Textual. Can you please double check you are running 0.11.0
. Running textual diagnose
will help with that.
I can't reproduce any issue with that code. The error you mention in a comment suggests you are running an older version of Textual. Can you please double check you are running
0.11.0
. Runningtextual diagnose
will help with that.
That's interesting because:
(screens-py3.10) PS D:\PycharmProjects\screens> textual diagnose
# Textual Diagnostics
## Versions
| Name | Value |
|---------|--------|
| Textual | 0.11.0 |
| Rich | 13.3.1 |
## Python
| Name | Value |
|----------------|---------------------------------------------------------------------------------------------------|
| Version | 3.10.7 |
| Implementation | CPython |
| Compiler | MSC v.1933 64 bit (AMD64) |
| Executable | C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\Scripts\python.exe |
## Operating System
| Name | Value |
|---------|------------|
| System | Windows |
| Release | 10 |
| Version | 10.0.19044 |
## Terminal
| Name | Value |
|----------------------|------------------|
| Terminal Application | Windows Terminal |
| TERM | *Not set* |
| COLORTERM | *Not set* |
| FORCE_COLOR | *Not set* |
| NO_COLOR | *Not set* |
## Rich Console options
| Name | Value |
|----------------|----------------------|
| size | width=120, height=26 |
| legacy_windows | False |
| min_width | 1 |
| max_width | 120 |
| is_terminal | True |
| encoding | utf-8 |
| max_height | 26 |
| justify | None |
| overflow | None |
| no_wrap | False |
| highlight | None |
| markup | None |
| height | None |
When I run textual console
and then textual run --dev <script_path>
:
And of course amount of SomeWidget should be always equal to 1. So there is a problem clearly visible when switching screens via switch_screen("first")
and switch_screen("second")
When I run textual console
and then textual run --dev <script_path>
:
No problem when switching screens via self.app.switch_screen(FirstScreen())
and self.app.switch_screen(SecondScreen())
I don't think it is a windows platform-specific bug since as I correctly remember - saw it for the first time under the Ubuntu:22.04 environment.
yield Header()
in BaseScreen's compose method.Traceback:
╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\widgets\_he │
│ ader.py:136 in on_mount │
│ │
│ 133 │ │ def set_sub_title(sub_title: str) -> None: │
│ 134 │ │ │ self.query_one(HeaderTitle).sub_text = sub_title │
│ 135 │ │ │
│ ❱ 136 │ │ self.watch(self.app, "title", set_title) │
│ 137 │ │ self.watch(self.app, "sub_title", set_sub_title) │
│ 138 │
│ │
│ ╭──────────────────────────────────────── locals ─────────────────────────────────────────╮ │
│ │ self = Header() │ │
│ │ set_sub_title = <function Header.on_mount.<locals>.set_sub_title at 0x0000023B81A181F0> │ │
│ │ set_title = <function Header.on_mount.<locals>.set_title at 0x0000023B818FFC70> │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\dom.py:669 │
│ in watch │
│ │
│ 666 │ │ │ callback: A callback to run when attribute changes. │
│ 667 │ │ │ init: Check watchers on first call. │
│ 668 │ │ """ │
│ ❱ 669 │ │ _watch(self, obj, attribute_name, callback, init=init) │
│ 670 │ │
│ 671 │ def get_pseudo_classes(self) -> Iterable[str]: │
│ 672 │ │ """Get any pseudo classes applicable to this Node, e.g. hover, focus. │
│ │
│ ╭─────────────────────────────────────── locals ───────────────────────────────────────╮ │
│ │ attribute_name = 'title' │ │
│ │ callback = <function Header.on_mount.<locals>.set_title at 0x0000023B818FFC70> │ │
│ │ init = True │ │
│ │ obj = MyApp(title='MyApp', classes={'-dark-mode'}) │ │
│ │ self = Header() │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\reactive.py │
│ :354 in _watch │
│ │
│ 351 │ watcher_list.append((node, callback)) │
│ 352 │ if init: │
│ 353 │ │ current_value = getattr(obj, attribute_name, None) │
│ ❱ 354 │ │ Reactive._check_watchers(obj, attribute_name, current_value) │
│ 355 │
│ │
│ ╭───────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────╮ │
│ │ attribute_name = 'title' │ │
│ │ callback = <function Header.on_mount.<locals>.set_title at 0x0000023B818FFC70> │ │
│ │ current_value = 'MyApp' │ │
│ │ init = True │ │
│ │ node = Header() │ │
│ │ obj = MyApp(title='MyApp', classes={'-dark-mode'}) │ │
│ │ watcher_list = [ │ │
│ │ │ (Header(), <function Header.on_mount.<locals>.set_title at 0x0000023B818FEC20>), │ │
│ │ │ (Header(), <function Header.on_mount.<locals>.set_title at 0x0000023B818FFC70>) │ │
│ │ ] │ │
│ │ watchers = { │ │
│ │ │ 'title': [ │ │
│ │ │ │ (Header(), <function Header.on_mount.<locals>.set_title at 0x0000023B818FEC20>), │ │
│ │ │ │ (Header(), <function Header.on_mount.<locals>.set_title at 0x0000023B818FFC70>) │ │
│ │ │ ], │ │
│ │ │ 'sub_title': [ │ │
│ │ │ │ ( │ │
│ │ │ │ │ Header(), │ │
│ │ │ │ │ <function Header.on_mount.<locals>.set_sub_title at 0x0000023B818FE4D0> │ │
│ │ │ │ ) │ │
│ │ │ ] │ │
│ │ } │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\widgets\_he │
│ ader.py:131 in set_title │
│ │
│ 128 │ ╭───── locals ─────╮ │
│ 129 │ def on_mount(self) -> None: │ self = Header() │ │
│ 130 │ │ def set_title(title: str) -> None: │ title = 'MyApp' │ │
│ ❱ 131 │ │ │ self.query_one(HeaderTitle).text = title ╰──────────────────╯ │
│ 132 │ │ │
│ 133 │ │ def set_sub_title(sub_title: str) -> None: │
│ 134 │ │ │ self.query_one(HeaderTitle).sub_text = sub_title │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\dom.py:839 │
│ in query_one │
│ │
│ 836 │ │ │ query_selector = selector.__name__ │
│ 837 │ │ query: DOMQuery[Widget] = DOMQuery(self, filter=query_selector) │
│ 838 │ │ │
│ ❱ 839 │ │ return query.only_one() if expect_type is None else query.only_one(expect_type) │
│ 840 │ │
│ 841 │ def set_styles(self, css: str | None = None, **update_styles) -> None: │
│ 842 │ │ """Set custom styles on this object.""" │
│ │
│ ╭──────────────────────────── locals ────────────────────────────╮ │
│ │ DOMQuery = <class 'textual.css.query.DOMQuery'> │ │
│ │ expect_type = None │ │
│ │ query = <DOMQuery Header() filter='HeaderTitle'> │ │
│ │ query_selector = 'HeaderTitle' │ │
│ │ selector = <class 'textual.widgets._header.HeaderTitle'> │ │
│ │ self = Header() │ │
│ ╰────────────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\css\query.p │
│ y:243 in only_one │
│ │
│ 240 │ │ """ │
│ 241 │ │ # Call on first to get the first item. Here we'll use all of the │
│ 242 │ │ # testing and checking it provides. │
│ ❱ 243 │ │ the_one = self.first(expect_type) if expect_type is not None else self.first() │
│ 244 │ │ try: │
│ 245 │ │ │ # Now see if we can access a subsequent item in the nodes. There │
│ 246 │ │ │ # should *not* be anything there, so we *should* get an │
│ │
│ ╭──────────────────────── locals ────────────────────────╮ │
│ │ expect_type = None │ │
│ │ self = <DOMQuery Header() filter='HeaderTitle'> │ │
│ ╰────────────────────────────────────────────────────────╯ │
│ │
│ C:\Users\...\AppData\Local\pypoetry\Cache\virtualenvs\screens-XJncIhWR-py3.10\lib\site-packages\textual\css\query.p │
│ y:214 in first │
│ │
│ 211 │ │ │ │ │ ) │
│ 212 │ │ │ return first │
│ 213 │ │ else: │
│ ❱ 214 │ │ │ raise NoMatches(f"No nodes match {self!r}") │
│ 215 │ │
│ 216 │ @overload │
│ 217 │ def only_one(self) -> Widget: │
│ │
│ ╭──────────────────────── locals ────────────────────────╮ │
│ │ expect_type = None │ │
│ │ self = <DOMQuery Header() filter='HeaderTitle'> │ │
│ ╰────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
NoMatches: No nodes match <DOMQuery Header() filter='HeaderTitle'>
Don't forget to star the repository!
Follow @textualizeio for Textual updates.
Version: 0.11.0
Consider a following code:
The example provided above shows some problems. Try launching it and switching views via "n" and "m" keys. I think it's a descriptive example so there's not much to add, but it seems that there are 2 bugs in this piece of code - one is a problem with displaying the header, because after uncommenting it throws an error, and second problem occurs when switching screens.