-
-
Notifications
You must be signed in to change notification settings - Fork 994
Closed
Description
If I click the terminal and append 'ab'
to markdown, it will shutdown:
from textual.app import App
from textual.widgets import Markdown
TEXT = '''\
### Hello
**World**
'''
class MyApp(App):
def on_mount(self):
self.widgets = [
Markdown(TEXT),
]
self.mount_all(self.widgets)
async def on_click(self):
await self.query_one(Markdown).append('ab')
if __name__ == '__main__':
app = MyApp()
app.run()
It reports:
╭────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────────────────────────────────────────────╮
│ e:\PSF\textual_uv_app\src\textual_app\myapp.py:16 in on_click │
│ │
│ 13 │ │ ] ╭─────────────────────────────────────── locals ────────────────────────────────────────╮ │
│ 14 │ │ self.mount_all(self.widgets) │ self = MyApp(title='MyApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}) │ │
│ 15 │ async def on_click(self): ╰───────────────────────────────────────────────────────────────────────────────────────╯ │
│ ❱ 16 │ │ await self.query_one(Markdown).append('ab') │
│ 17 │
│ 18 if __name__ == '__main__': │
│ 19 │ app = MyApp() │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\widgets\_markdown.py:1403 in await_append │
│ │
│ 1400 │ │ │ │ │ │ last_block = existing_blocks[-1] │
│ 1401 │ │ │ │ │ │ last_block.source_range = new_blocks[0].source_range │
│ 1402 │ │ │ │ │ │ try: │
│ ❱ 1403 │ │ │ │ │ │ │ await last_block._update_from_block(new_blocks[0]) │
│ 1404 │ │ │ │ │ │ except IndexError: │
│ 1405 │ │ │ │ │ │ │ pass │
│ 1406 │ │ │ │ │ │ else: │
│ │
│ ╭───────────────────────────────────────────────────────────────────────────────────────────── locals ──────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ block = MarkdownParagraph(name='paragraph_open', classes='level-0') │ │
│ │ end = 3 │ │
│ │ existing_blocks = [MarkdownH3(id='hello-1', name='heading_open', classes='level-0'), MarkdownParagraph(name='paragraph_open', classes='level-0')] │ │
│ │ last_block = MarkdownParagraph(name='paragraph_open', classes='level-0') │ │
│ │ new_blocks = [MarkdownH3(id='hello-1', name='heading_open', classes='level-0'), MarkdownParagraph(name='paragraph_open', classes='level-0')] │ │
│ │ parser = markdown_it.main.MarkdownIt() │ │
│ │ self = Markdown() │ │
│ │ start = 1 │ │
│ │ start_line = 0 │ │
│ │ table_of_contents = [(3, 'Hello', 'hello-1')] │ │
│ │ token = Token(type='paragraph_open', tag='p', nesting=1, attrs={}, map=[1, 3], level=0, children=None, content='', markup='', info='', meta={}, block=True, hidden=False) │ │
│ │ tokens = [ │ │
│ │ │ Token(type='heading_open', tag='h3', nesting=1, attrs={}, map=[0, 1], level=0, children=None, content='', markup='###', info='', meta={}, block=True, hidden=False), │ │
│ │ │ Token( │ │
│ │ │ │ type='inline', │ │
│ │ │ │ tag='', │ │
│ │ │ │ nesting=0, │ │
│ │ │ │ attrs={}, │ │
│ │ │ │ map=[0, 1], │ │
│ │ │ │ level=1, │ │
│ │ │ │ children=[ │ │
│ │ │ │ │ Token(type='text', tag='', nesting=0, attrs={}, map=None, level=0, children=None, content='Hello', markup='', info='', meta={}, block=False, hidden=False) │ │
│ │ │ │ ], │ │
│ │ │ │ content='Hello', │ │
│ │ │ │ markup='', │ │
│ │ │ │ info='', │ │
│ │ │ │ meta={}, │ │
│ │ │ │ block=True, │ │
│ │ │ │ hidden=False │ │
│ │ │ ), │ │
│ │ │ Token(type='heading_close', tag='h3', nesting=-1, attrs={}, map=None, level=0, children=None, content='', markup='###', info='', meta={}, block=True, hidden=False), │ │
│ │ │ Token(type='paragraph_open', tag='p', nesting=1, attrs={}, map=[1, 3], level=0, children=None, content='', markup='', info='', meta={}, block=True, hidden=False), │ │
│ │ │ Token( │ │
│ │ │ │ type='inline', │ │
│ │ │ │ tag='', │ │
│ │ │ │ nesting=0, │ │
│ │ │ │ attrs={}, │ │
│ │ │ │ map=[1, 3], │ │
│ │ │ │ level=1, │ │
│ │ │ │ children=[ │ │
│ │ │ │ │ Token(type='text', tag='', nesting=0, attrs={}, map=None, level=0, children=None, content='', markup='', info='', meta={}, block=False, hidden=False), │ │
│ │ │ │ │ Token( │ │
│ │ │ │ │ │ type='strong_open', │ │
│ │ │ │ │ │ tag='strong', │ │
│ │ │ │ │ │ nesting=1, │ │
│ │ │ │ │ │ attrs={}, │ │
│ │ │ │ │ │ map=None, │ │
│ │ │ │ │ │ level=0, │ │
│ │ │ │ │ │ children=None, │ │
│ │ │ │ │ │ content='', │ │
│ │ │ │ │ │ markup='**', │ │
│ │ │ │ │ │ info='', │ │
│ │ │ │ │ │ meta={}, │ │
│ │ │ │ │ │ block=False, │ │
│ │ │ │ │ │ hidden=False │ │
│ │ │ │ │ ), │ │
│ │ │ │ │ Token(type='text', tag='', nesting=0, attrs={}, map=None, level=1, children=None, content='World', markup='', info='', meta={}, block=False, hidden=False), │ │
│ │ │ │ │ Token( │ │
│ │ │ │ │ │ type='strong_close', │ │
│ │ │ │ │ │ tag='strong', │ │
│ │ │ │ │ │ nesting=-1, │ │
│ │ │ │ │ │ attrs={}, │ │
│ │ │ │ │ │ map=None, │ │
│ │ │ │ │ │ level=0, │ │
│ │ │ │ │ │ children=None, │ │
│ │ │ │ │ │ content='', │ │
│ │ │ │ │ │ markup='**', │ │
│ │ │ │ │ │ info='', │ │
│ │ │ │ │ │ meta={}, │ │
│ │ │ │ │ │ block=False, │ │
│ │ │ │ │ │ hidden=False │ │
│ │ │ │ │ ), │ │
│ │ │ │ │ Token(type='text', tag='', nesting=0, attrs={}, map=None, level=0, children=None, content='', markup='', info='', meta={}, block=False, hidden=False), │ │
│ │ │ │ │ Token( │ │
│ │ │ │ │ │ type='softbreak', │ │
│ │ │ │ │ │ tag='br', │ │
│ │ │ │ │ │ nesting=0, │ │
│ │ │ │ │ │ attrs={}, │ │
│ │ │ │ │ │ map=None, │ │
│ │ │ │ │ │ level=0, │ │
│ │ │ │ │ │ children=None, │ │
│ │ │ │ │ │ content='', │ │
│ │ │ │ │ │ markup='', │ │
│ │ │ │ │ │ info='', │ │
│ │ │ │ │ │ meta={}, │ │
│ │ │ │ │ │ block=False, │ │
│ │ │ │ │ │ hidden=False │ │
│ │ │ │ │ ), │ │
│ │ │ │ │ Token(type='text', tag='', nesting=0, attrs={}, map=None, level=0, children=None, content='ab', markup='', info='', meta={}, block=False, hidden=False) │ │
│ │ │ │ ], │ │
│ │ │ │ content='**World**\nab', │ │
│ │ │ │ markup='', │ │
│ │ │ │ info='', │ │
│ │ │ │ meta={}, │ │
│ │ │ │ block=True, │ │
│ │ │ │ hidden=False │ │
│ │ │ ), │ │
│ │ │ Token(type='paragraph_close', tag='p', nesting=-1, attrs={}, map=None, level=0, children=None, content='', markup='', info='', meta={}, block=True, hidden=False) │ │
│ │ ] │ │
│ │ updated_source = '### Hello\n**World**\nab' │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\widgets\_markdown.py:472 in _update_from_block │
│ │
│ 469 │ │ │ self.set_content(block._content) ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ 470 │ │ │ self._copy_context(block) │ block = MarkdownH3(id='hello-1', name='heading_open', classes='level-0') │ │
│ 471 │ │ else: │ self = MarkdownParagraph(name='paragraph_open', classes='level-0') │ │
│ ❱ 472 │ │ │ await super()._update_from_block(block) ╰──────────────────────────────────────────────────────────────────────────╯ │
│ 473 │
│ 474 │
│ 475 class MarkdownBlockQuote(MarkdownBlock): │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\widgets\_markdown.py:253 in _update_from_block │
│ │
│ 250 │ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ 251 │ async def _update_from_block(self, block: MarkdownBlock) -> None: │ block = MarkdownH3(id='hello-1', name='heading_open', classes='level-0') │ │
│ 252 │ │ await self.remove() │ self = MarkdownParagraph(name='paragraph_open', classes='level-0') │ │
│ ❱ 253 │ │ await self._markdown.mount(block) ╰──────────────────────────────────────────────────────────────────────────╯ │
│ 254 │ │
│ 255 │ async def action_link(self, href: str) -> None: │
│ 256 │ │ """Called on link click.""" │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\widget.py:1370 in mount │
│ │
│ 1367 │ │ else: ╭────────────────────────────────────── locals ───────────────────────────────────────╮ │
│ 1368 │ │ │ parent = self │ after = None │ │
│ 1369 │ │ │ before = None │ │
│ ❱ 1370 │ │ mounted = self.app._register( │ ids_to_mount = ['hello-1'] │ │
│ 1371 │ │ │ parent, *widgets, before=insert_before, after=insert_after │ insert_after = None │ │
│ 1372 │ │ ) │ insert_before = None │ │
│ 1373 │ parent = Markdown() │ │
│ │ self = Markdown() │ │
│ │ widget_id = 'hello-1' │ │
│ │ widgets = (MarkdownH3(id='hello-1', name='heading_open', classes='level-0'),) │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\app.py:3459 in _register │
│ │
│ 3456 │ │ │ │ raise AppError(f"Can't register {widget!r}; expected a Widget instance") │
│ 3457 │ │ │ if widget not in self._registry: │
│ 3458 │ │ │ │ add_new_widget(widget) │
│ ❱ 3459 │ │ │ │ self._register_child(parent, widget, before, after) │
│ 3460 │ │ │ │ if widget._nodes: │
│ 3461 │ │ │ │ │ self._register(widget, *widget._nodes, cache=cache) │
│ 3462 │ │ for widget in new_widgets: │
│ │
│ ╭───────────────────────────────────────────────────────────────────────────────────────────── locals ──────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ add_new_widget = <built-in method append of list object at 0x000001F561A9AAC0> │ │
│ │ after = None │ │
│ │ apply_stylesheet = <bound method Stylesheet.apply of <Stylesheet [('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\app.py', 'App.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\screen.py', 'Screen.DEFAULT_CSS'), ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widget.py', │ │
│ │ 'Widget.DEFAULT_CSS'), ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_markdown.py', 'Markdown.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_toast.py', 'ToastRack.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_tooltip.py', 'Tooltip.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_markdown.py', 'MarkdownH3.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_markdown.py', 'MarkdownHeader.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_markdown.py', 'MarkdownBlock.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_static.py', 'Static.DEFAULT_CSS'), │ │
│ │ ('E:\\PSF\\textual_uv_app\\.venv\\Lib\\site-packages\\textual\\widgets\\_markdown.py', 'MarkdownParagraph.DEFAULT_CSS')]>> │ │
│ │ before = None │ │
│ │ cache = {} │ │
│ │ new_widgets = [MarkdownH3(id='hello-1', name='heading_open', classes='level-0')] │ │
│ │ parent = Markdown() │ │
│ │ self = MyApp(title='MyApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}) │ │
│ │ widget = MarkdownH3(id='hello-1', name='heading_open', classes='level-0') │ │
│ │ widget_list = (MarkdownH3(id='hello-1', name='heading_open', classes='level-0'),) │ │
│ │ widgets = (MarkdownH3(id='hello-1', name='heading_open', classes='level-0'),) │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\app.py:3404 in _register_child │
│ │
│ 3401 │ │ │ │ # At this point we appear to not be adding before or after, ╭──────────────────────────────────────── locals ─────────────────────────────────────────╮ │
│ 3402 │ │ │ │ # or we've got a before/after value that really means │ after = None │ │
│ 3403 │ │ │ │ # "please append". So... │ before = None │ │
│ ❱ 3404 │ │ │ │ parent._nodes._append(child) │ child = MarkdownH3(id='hello-1', name='heading_open', classes='level-0') │ │
│ 3405 │ │ │ │ parent = Markdown() │ │
│ 3406 │ │ │ # Now that the widget is in the NodeList of its parent, sort out │ self = MyApp(title='MyApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}) │ │
│ 3407 │ │ │ # the rest of the admin. ╰─────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\_node_list.py:125 in _append │
│ │
│ 122 │ │ │ self._nodes_set.add(widget) │
│ 123 │ │ │ widget_id = widget.id │
│ 124 │ │ │ if widget_id is not None: │
│ ❱ 125 │ │ │ │ self._ensure_unique_id(widget_id) │
│ 126 │ │ │ │ self._nodes_by_id[widget_id] = widget │
│ 127 │ │ │ self.updated() │
│ 128 │
│ │
│ ╭────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────╮ │
│ │ self = <NodeList [MarkdownH3(id='hello-1', name='heading_open', classes='level-0'), MarkdownH3(id='hello-1', name='heading_open', classes='level-0')]> │ │
│ │ widget = MarkdownH3(id='hello-1', name='heading_open', classes='level-0') │ │
│ │ widget_id = 'hello-1' │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ E:\PSF\textual_uv_app\.venv\Lib\site-packages\textual\_node_list.py:154 in _ensure_unique_id │
│ │
│ 151 │ │ │ DuplicateIds: If the given ID is not unique. │
│ 152 │ │ """ │
│ 153 │ │ if widget_id in self._nodes_by_id: │
│ ❱ 154 │ │ │ raise DuplicateIds( │
│ 155 │ │ │ │ f"Tried to insert a widget with ID {widget_id!r}, but a widget already e │
│ 156 │ │ │ │ "ensure all child widgets have a unique ID." │
│ 157 │ │ │ ) │
│ │
│ ╭────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────╮ │
│ │ self = <NodeList [MarkdownH3(id='hello-1', name='heading_open', classes='level-0'), MarkdownH3(id='hello-1', name='heading_open', classes='level-0')]> │ │
│ │ widget_id = 'hello-1' │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
DuplicateIds: Tried to insert a widget with ID 'hello-1', but a widget already exists with that ID (MarkdownH3(id='hello-1', name='heading_open', classes='level-0')); ensure all child widgets have a
unique ID.
Metadata
Metadata
Assignees
Labels
No labels