Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crashing with AttributeError: 'LoadingIndicator' object has no attribute '_start_time #3600

Closed
mzebrak opened this issue Oct 27, 2023 · 6 comments

Comments

@mzebrak
Copy link

mzebrak commented Oct 27, 2023

Overview

Consider the example below.
While spamming F1 and F2 keys really fast (in fact, so quickly that my fingers hurt 😄 ), app could be crashed.
I managed to trigger it in such a small example (but it's quite hard to do), but in a real, more complicated application
where we use a similar
solution, it's much easier to get the same error. I have the impression that it depends on the number of registered
watchers. Reading the callstack, it looks like the reason is that the Loading Indicator was not mounted even though it
should have been.

This is a bug report, so please don't ask me why I'm doing this way. I use public interface and documented
methods. The main goal is to use watch and give it an asynchronous method. (we use this in the implementation of our
own DynamicLabel widget, which can react to changes on its own (without lots of self.watch calls, we can just use
yield DynamicLabel and pass a callback to it), which I previously wrote about here)

if anyone is interested, the source code of DynamicLabel looks like this, but that's not in scope of this bug report:
from __future__ import annotations

import asyncio
from inspect import isawaitable
from typing import TYPE_CHECKING, Any

from textual.widgets import Label

from clive.__private.ui.widgets.clive_widget import CliveWidget

if TYPE_CHECKING:
    from collections.abc import Callable

    from textual.app import ComposeResult
    from textual.reactive import Reactable


class DynamicLabel(CliveWidget):
    """A label that can be updated dynamically when a reactive variable changes."""

    DEFAULT_CSS = """
    DynamicLabel {
        height: auto;
        width: auto;
    }

    DynamicLabel LoadingIndicator {
        min-height: 1;
        min-width: 5;
    }
    """

    def __init__(
            self,
            obj_to_watch: Reactable,
            attribute_name: str,
            callback: Callable[[Any], Any],
    ) -> None:
        super().__init__()

        self.__label = Label("loading...")
        self.__label.loading = True

        self.__obj_to_watch = obj_to_watch
        self.__attribute_name = attribute_name
        self.__callback = callback

    def on_mount(self) -> None:
        def delegate_work(attribute: Any) -> None:
            self.run_worker(self.attribute_changed(attribute))

        self.watch(self.__obj_to_watch, self.__attribute_name, delegate_work)

    def compose(self) -> ComposeResult:
        yield self.__label

    async def attribute_changed(self, attribute: Any) -> None:
        self.__label.loading = True
        value = self.__callback(attribute)
        if isawaitable(value):
            value = await value
        if value != self.__label.renderable:
            self.__label.update(f"{value}")
        self.__label.loading = False

I think this is related to and have the impression that there is some bug hidden in the reactivity, because we observed
some app freezing also. I personally think it's also related to #3065, because we observe issues while bumping the textual version from 0.35.1 to 0.36.0.

The minimal example causing crash, I talk about:

Show
from __future__ import annotations

import asyncio

from textual.app import App
from textual.binding import Binding
from textual.reactive import var
from textual.screen import Screen
from textual.widgets import Footer, Label


class SecondScreen(Screen):
    BINDINGS = [
        Binding("f2", "change_and_pop", "Change state and pop screen"),
    ]

    def compose(self):
        yield Label(self.__class__.__name__)
        yield Footer()

    def action_change_and_pop(self) -> None:
        self.app.data = not self.app.data
        self.app.pop_screen()


class FirstScreen(Screen):
    BINDINGS = [
        Binding("f1", "push_second_screen", "Push second screen"),
    ]

    DEFAULT_CSS = """
    LoadingIndicator {
        min-width: 3;   # otherwise it won't appear in Label
    }
    """

    def on_mount(self):
        def delegate_work(data: bool) -> None:
            self.run_worker(self.synchronize(data))

        self.watch(self.app, "data", delegate_work)

    async def synchronize(self, data: bool) -> None:
        label = self.query_one(Label)

        label.loading = True
        await asyncio.sleep(1)  # assume there is some async work to do

        label.update(f"{data=}")
        label.loading = False

    def compose(self):
        yield Label()
        yield Footer()

    def action_push_second_screen(self) -> None:
        self.app.push_screen(SecondScreen())


class CrashingApp(App[None]):
    data = var(True, always_update=True)

    def on_mount(self) -> None:
        self.push_screen(FirstScreen())


CrashingApp().run()

It crashes with such an error message:

Show
╭────────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/widget.py:2993 in render_lines               │
│                                                                                                                       │
│   2990 │   │   Returns:                                                                                               │
│   2991 │   │   │   A list of list of segments.                                                                        │
│   2992 │   │   """
│ ❱ 2993 │   │   strips = self._styles_cache.render_widget(self, crop)                                                  │
│   2994 │   │   return strips                                                                                          │
│   2995 │                                                                                                              │
│   2996 │   def get_style_at(self, x: int, y: int) -> Style:                                                           │
│                                                                                                                       │
│ ╭────────────────── locals ──────────────────╮                                                                        │
│ │ crop = Region(x=0, y=0, width=3, height=1) │                                                                        │
│ │ self = LoadingIndicator()                  │                                                                        │
│ ╰────────────────────────────────────────────╯                                                                        │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/_styles_cache.py:115 in render_widget        │
│                                                                                                                       │
│   112 │   │                                                                                                           │
│   113 │   │   base_background, background = widget._opacity_background_colors                                         │
│   114 │   │   styles = widget.styles                                                                                  │
│ ❱ 115 │   │   strips = self.render(                                                                                   │
│   116 │   │   │   styles,                                                                                             │
│   117 │   │   │   widget.region.size,                                                                                 │
│   118 │   │   │   base_background,                                                                                    │
│                                                                                                                       │
│ ╭──────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮           │
│ │      background = Color(38, 38, 38)                                                                     │           │
│ │ base_background = Color(30, 30, 30)                                                                     │           │
│ │ border_subtitle = None                                                                                  │           │
│ │    border_title = None                                                                                  │           │
│ │            crop = Region(x=0, y=0, width=3, height=1)                                                   │           │
│ │            self = <textual._styles_cache.StylesCache object at 0x7fb3c9c9be80>                          │           │
│ │          styles = RenderStyles(                                                                         │           │
│ │                   │   auto_color=False,                                                                 │           │
│ │                   │   color=Color(1, 120, 212),                                                         │           │
│ │                   │   background=Color(255, 255, 255, a=0.0392156862745098),                            │           │
│ │                   │   width=Scalar(value=100.0, unit=<Unit.WIDTH: 4>, percent_unit=<Unit.WIDTH: 4>),    │           │
│ │                   │   height=Scalar(value=100.0, unit=<Unit.HEIGHT: 5>, percent_unit=<Unit.WIDTH: 4>),  │           │
│ │                   │   min_width=Scalar(value=3.0, unit=<Unit.CELLS: 1>, percent_unit=<Unit.WIDTH: 4>),  │           │
│ │                   │   min_height=Scalar(                                                                │           │
│ │                   │   │   value=1.0,                                                                    │           │
│ │                   │   │   unit=<Unit.CELLS: 1>,                                                         │           │
│ │                   │   │   percent_unit=<Unit.WIDTH: 4>                                                  │           │
│ │                   │   ),                                                                                │           │
│ │                   │   scrollbar_color=Color(35, 86, 139),                                               │           │
│ │                   │   scrollbar_color_hover=Color(35, 86, 139),                                         │           │
│ │                   │   scrollbar_color_active=Color(231, 146, 13),                                       │           │
│ │                   │   scrollbar_corner_color=Color(20, 25, 31),                                         │           │
│ │                   │   scrollbar_background=Color(20, 25, 31),                                           │           │
│ │                   │   scrollbar_background_hover=Color(0, 5, 15),                                       │           │
│ │                   │   scrollbar_background_active=Color(0, 0, 0),                                       │           │
│ │                   │   scrollbar_size_vertical=2,                                                        │           │
│ │                   │   scrollbar_size_horizontal=1,                                                      │           │
│ │                   │   content_align_horizontal='center',                                                │           │
│ │                   │   content_align_vertical='middle',                                                  │           │
│ │                   │   link_color=Color(255, 255, 255, a=0.87),                                          │           │
│ │                   │   auto_link_color=True,                                                             │           │
│ │                   │   link_style=Style(underline=True),                                                 │           │
│ │                   │   link_hover_color=Color(255, 255, 255, a=0.87),                                    │           │
│ │                   │   auto_link_hover_color=True,                                                       │           │
│ │                   │   link_hover_background=Color(1, 120, 212),                                         │           │
│ │                   │   link_hover_style=Style(bold=True, underline=False),                               │           │
│ │                   │   overlay='screen'                                                                  │           │
│ │                   )                                                                                     │           │
│ │          widget = LoadingIndicator()                                                                    │           │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯           │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/_styles_cache.py:214 in render               │
│                                                                                                                       │
│   211 │   │   render_line = self.render_line                                                                          │
│   212 │   │   for y in crop.line_range:                                                                               │
│   213 │   │   │   if is_dirty(y) or y not in self._cache:                                                             │
│ ❱ 214 │   │   │   │   strip = render_line(                                                                            │
│   215 │   │   │   │   │   styles,                                                                                     │
│   216 │   │   │   │   │   y,                                                                                          │
│   217 │   │   │   │   │   size,                                                                                       │
│                                                                                                                       │
│ ╭───────────────────────────────────────────────────── locals ──────────────────────────────────────────────────────╮ │
│ │             _height = 1                                                                                           │ │
│ │           add_strip = <built-in method append of list object at 0x7fb3c9cdc480>                                   │ │
│ │          background = Color(38, 38, 38)                                                                           │ │
│ │     base_background = Color(30, 30, 30)                                                                           │ │
│ │     border_subtitle = None                                                                                        │ │
│ │        border_title = None                                                                                        │ │
│ │             console = <console width=121 ColorSystem.TRUECOLOR>                                                   │ │
│ │        content_size = Size(width=3, height=1)                                                                     │ │
│ │                crop = Region(x=0, y=0, width=3, height=1)                                                         │ │
│ │             filters = []                                                                                          │ │
│ │            is_dirty = <built-in method __contains__ of set object at 0x7fb3c9cbb840>                              │ │
│ │             opacity = 1.0                                                                                         │ │
│ │             padding = Spacing(top=0, right=0, bottom=0, left=0)                                                   │ │
│ │ render_content_line = <bound method Widget.render_line of LoadingIndicator()>                                     │ │
│ │         render_line = <bound method StylesCache.render_line of <textual._styles_cache.StylesCache object at       │ │
│ │                       0x7fb3c9c9be80>>                                                                            │ │
│ │                self = <textual._styles_cache.StylesCache object at 0x7fb3c9c9be80>                                │ │
│ │                size = Size(width=3, height=1)                                                                     │ │
│ │              strips = []                                                                                          │ │
│ │              styles = RenderStyles(                                                                               │ │
│ │                       │   auto_color=False,                                                                       │ │
│ │                       │   color=Color(1, 120, 212),                                                               │ │
│ │                       │   background=Color(255, 255, 255, a=0.0392156862745098),                                  │ │
│ │                       │   width=Scalar(value=100.0, unit=<Unit.WIDTH: 4>, percent_unit=<Unit.WIDTH: 4>),          │ │
│ │                       │   height=Scalar(value=100.0, unit=<Unit.HEIGHT: 5>, percent_unit=<Unit.WIDTH: 4>),        │ │
│ │                       │   min_width=Scalar(value=3.0, unit=<Unit.CELLS: 1>, percent_unit=<Unit.WIDTH: 4>),        │ │
│ │                       │   min_height=Scalar(value=1.0, unit=<Unit.CELLS: 1>, percent_unit=<Unit.WIDTH: 4>),       │ │
│ │                       │   scrollbar_color=Color(35, 86, 139),                                                     │ │
│ │                       │   scrollbar_color_hover=Color(35, 86, 139),                                               │ │
│ │                       │   scrollbar_color_active=Color(231, 146, 13),                                             │ │
│ │                       │   scrollbar_corner_color=Color(20, 25, 31),                                               │ │
│ │                       │   scrollbar_background=Color(20, 25, 31),                                                 │ │
│ │                       │   scrollbar_background_hover=Color(0, 5, 15),                                             │ │
│ │                       │   scrollbar_background_active=Color(0, 0, 0),                                             │ │
│ │                       │   scrollbar_size_vertical=2,                                                              │ │
│ │                       │   scrollbar_size_horizontal=1,                                                            │ │
│ │                       │   content_align_horizontal='center',                                                      │ │
│ │                       │   content_align_vertical='middle',                                                        │ │
│ │                       │   link_color=Color(255, 255, 255, a=0.87),                                                │ │
│ │                       │   auto_link_color=True,                                                                   │ │
│ │                       │   link_style=Style(underline=True),                                                       │ │
│ │                       │   link_hover_color=Color(255, 255, 255, a=0.87),                                          │ │
│ │                       │   auto_link_hover_color=True,                                                             │ │
│ │                       │   link_hover_background=Color(1, 120, 212),                                               │ │
│ │                       │   link_hover_style=Style(bold=True, underline=False),                                     │ │
│ │                       │   overlay='screen'                                                                        │ │
│ │                       )                                                                                           │ │
│ │               width = 3                                                                                           │ │
│ │                   y = 0                                                                                           │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/_styles_cache.py:409 in render_line          │
│                                                                                                                       │
│   406 │   │   │   # Content with border and padding (C)                                                               │
│   407 │   │   │   content_y = y - gutter.top                                                                          │
│   408 │   │   │   if content_y < content_height:                                                                      │
│ ❱ 409 │   │   │   │   line = render_content_line(y - gutter.top)                                                      │
│   410 │   │   │   │   line = line.adjust_cell_length(content_width)                                                   │
│   411 │   │   │   else:                                                                                               │
│   412 │   │   │   │   line = [make_blank(content_width, inner)]                                                       │
│                                                                                                                       │
│ ╭───────────────────────────────────────────────────── locals ──────────────────────────────────────────────────────╮ │
│ │           background = Color(38, 38, 38)                                                                          │ │
│ │      base_background = Color(30, 30, 30)                                                                          │ │
│ │        border_bottom = ''                                                                                         │ │
│ │  border_bottom_color = Color(0, 255, 0)                                                                           │ │
│ │          border_left = ''                                                                                         │ │
│ │    border_left_color = Color(0, 255, 0)                                                                           │ │
│ │         border_right = ''                                                                                         │ │
│ │   border_right_color = Color(0, 255, 0)                                                                           │ │
│ │      border_subtitle = None                                                                                       │ │
│ │         border_title = None                                                                                       │ │
│ │           border_top = ''                                                                                         │ │
│ │     border_top_color = Color(0, 255, 0)                                                                           │ │
│ │              console = <console width=121 ColorSystem.TRUECOLOR>                                                  │ │
│ │       content_height = 1                                                                                          │ │
│ │         content_size = Size(width=3, height=1)                                                                    │ │
│ │        content_width = 3                                                                                          │ │
│ │            content_y = 0                                                                                          │ │
│ │           from_color = <bound method Style.from_color of <class 'rich.style.Style'>>                              │ │
│ │               gutter = Spacing(top=0, right=0, bottom=0, left=0)                                                  │ │
│ │               height = 1                                                                                          │ │
│ │                inner = Style(                                                                                     │ │
│ │                        │   bgcolor=Color(                                                                         │ │
│ │                        │   │   '#262626',                                                                         │ │
│ │                        │   │   ColorType.TRUECOLOR,                                                               │ │
│ │                        │   │   triplet=ColorTriplet(red=38, green=38, blue=38)                                    │ │
│ │                        │   )                                                                                      │ │
│ │                        )                                                                                          │ │
│ │              opacity = 1.0                                                                                        │ │
│ │                outer = Style(                                                                                     │ │
│ │                        │   bgcolor=Color(                                                                         │ │
│ │                        │   │   '#1e1e1e',                                                                         │ │
│ │                        │   │   ColorType.TRUECOLOR,                                                               │ │
│ │                        │   │   triplet=ColorTriplet(red=30, green=30, blue=30)                                    │ │
│ │                        │   )                                                                                      │ │
│ │                        )                                                                                          │ │
│ │       outline_bottom = ''                                                                                         │ │
│ │ outline_bottom_color = Color(0, 255, 0)                                                                           │ │
│ │         outline_left = ''                                                                                         │ │
│ │   outline_left_color = Color(0, 255, 0)                                                                           │ │
│ │        outline_right = ''                                                                                         │ │
│ │  outline_right_color = Color(0, 255, 0)                                                                           │ │
│ │          outline_top = ''                                                                                         │ │
│ │    outline_top_color = Color(0, 255, 0)                                                                           │ │
│ │           pad_bottom = 0                                                                                          │ │
│ │             pad_left = 0                                                                                          │ │
│ │            pad_right = 0                                                                                          │ │
│ │              pad_top = 0                                                                                          │ │
│ │              padding = Spacing(top=0, right=0, bottom=0, left=0)                                                  │ │
│ │                 post = <function StylesCache.render_line.<locals>.post at 0x7fb3c9e51120>                         │ │
│ │  render_content_line = <bound method Widget.render_line of LoadingIndicator()>                                    │ │
│ │                 self = <textual._styles_cache.StylesCache object at 0x7fb3c9c9be80>                               │ │
│ │                 size = Size(width=3, height=1)                                                                    │ │
│ │               styles = RenderStyles(                                                                              │ │
│ │                        │   auto_color=False,                                                                      │ │
│ │                        │   color=Color(1, 120, 212),                                                              │ │
│ │                        │   background=Color(255, 255, 255, a=0.0392156862745098),                                 │ │
│ │                        │   width=Scalar(value=100.0, unit=<Unit.WIDTH: 4>, percent_unit=<Unit.WIDTH: 4>),         │ │
│ │                        │   height=Scalar(value=100.0, unit=<Unit.HEIGHT: 5>, percent_unit=<Unit.WIDTH: 4>),       │ │
│ │                        │   min_width=Scalar(value=3.0, unit=<Unit.CELLS: 1>, percent_unit=<Unit.WIDTH: 4>),       │ │
│ │                        │   min_height=Scalar(                                                                     │ │
│ │                        │   │   value=1.0,                                                                         │ │
│ │                        │   │   unit=<Unit.CELLS: 1>,                                                              │ │
│ │                        │   │   percent_unit=<Unit.WIDTH: 4>                                                       │ │
│ │                        │   ),                                                                                     │ │
│ │                        │   scrollbar_color=Color(35, 86, 139),                                                    │ │
│ │                        │   scrollbar_color_hover=Color(35, 86, 139),                                              │ │
│ │                        │   scrollbar_color_active=Color(231, 146, 13),                                            │ │
│ │                        │   scrollbar_corner_color=Color(20, 25, 31),                                              │ │
│ │                        │   scrollbar_background=Color(20, 25, 31),                                                │ │
│ │                        │   scrollbar_background_hover=Color(0, 5, 15),                                            │ │
│ │                        │   scrollbar_background_active=Color(0, 0, 0),                                            │ │
│ │                        │   scrollbar_size_vertical=2,                                                             │ │
│ │                        │   scrollbar_size_horizontal=1,                                                           │ │
│ │                        │   content_align_horizontal='center',                                                     │ │
│ │                        │   content_align_vertical='middle',                                                       │ │
│ │                        │   link_color=Color(255, 255, 255, a=0.87),                                               │ │
│ │                        │   auto_link_color=True,                                                                  │ │
│ │                        │   link_style=Style(underline=True),                                                      │ │
│ │                        │   link_hover_color=Color(255, 255, 255, a=0.87),                                         │ │
│ │                        │   auto_link_hover_color=True,                                                            │ │
│ │                        │   link_hover_background=Color(1, 120, 212),                                              │ │
│ │                        │   link_hover_style=Style(bold=True, underline=False),                                    │ │
│ │                        │   overlay='screen'                                                                       │ │
│ │                        )                                                                                          │ │
│ │                width = 3                                                                                          │ │
│ │                    y = 0                                                                                          │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/widget.py:2977 in render_line                │
│                                                                                                                       │
│   2974 │   │   │   A rendered line.                                                                                   │
│   2975 │   │   """                                                                                                    │
│   2976 │   │   if self._dirty_regions:                                                                                │
│ ❱ 2977 │   │   │   self._render_content()                                                                             │
│   2978 │   │   try:                                                                                                   │
│   2979 │   │   │   line = self._render_cache.lines[y]                                                                 │
│   2980 │   │   except IndexError:                                                                                     │
│                                                                                                                       │
│ ╭───────── locals ──────────╮                                                                                         │
│ │ self = LoadingIndicator() │                                                                                         │
│ │    y = 0                  │                                                                                         │
│ ╰───────────────────────────╯                                                                                         │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/widget.py:2935 in _render_content            │
│                                                                                                                       │
│   2932 │   def _render_content(self) -> None:                                                                         │
│   2933 │   │   """Render all lines."""                                                                                │
│   2934 │   │   width, height = self.size                                                                              │
│ ❱ 2935 │   │   renderable = self.render()                                                                             │
│   2936 │   │   renderable = self.post_render(renderable)                                                              │
│   2937 │   │   options = self._console.options.update_dimensions(width, height).update(                               │
│   2938 │   │   │   highlight=False                                                                                    │
│                                                                                                                       │
│ ╭────────── locals ───────────╮                                                                                       │
│ │ height = 1                  │                                                                                       │
│ │   self = LoadingIndicator() │                                                                                       │
│ │  width = 3                  │                                                                                       │
│ ╰─────────────────────────────╯                                                                                       │
│                                                                                                                       │
│ /home/mzebrak/.pyenv/versions/clive/lib/python3.10/site-packages/textual/widgets/_loading_indicator.py:75 in render   │
│                                                                                                                       │
│   72 │   │   self.auto_refresh = 1 / 16                                                                               │
│   73 │                                                                                                                │
│   74 │   def render(self) -> RenderableType:                                                                          │
│ ❱ 75 │   │   elapsed = time() - self._start_time                                                                      │
│   76 │   │   speed = 0.8                                                                                              │
│   77 │   │   dot = "\u25cf"                                                                                           │
│   78 │   │   _, _, background, color = self.colors                                                                    │
│                                                                                                                       │
│ ╭───────── locals ──────────╮                                                                                         │
│ │ self = LoadingIndicator() │                                                                                         │
│ ╰───────────────────────────╯                                                                                         │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'LoadingIndicator' object has no attribute '_start_time'

Video

I know that it's not easy to cause this crash, because you need to have nimble fingers, so I'm posting a video to prove
it:

Show
Screencast.from.10-27-2023.10.38.24.AM.webm

Textual diagnose

Show

Textual Diagnostics

Versions

Name Value
Textual 0.40.0
Rich 13.3.5

Python

Name Value
Version 3.10.6
Implementation CPython
Compiler GCC 11.3.0
Executable /home/mzebrak/.pyenv/versions/3.10.6/envs/clive/bin/python

Operating System

Name Value
System Linux
Release 6.2.6-76060206-generic
Version #202303130630167942497222.04~4a8cde1 SMP PREEMPT_DYNAMIC Tue M

Terminal

Name Value
Terminal Application Unknown
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=121, height=32
legacy_windows False
min_width 1
max_width 121
is_terminal True
encoding utf-8
max_height 32
justify None
overflow None
no_wrap False
highlight None
markup None
height None
@github-actions
Copy link

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

@darrenburns
Copy link
Member

This is fixed and will be in the next release, which should be pretty soon 🙂

@mzebrak
Copy link
Author

mzebrak commented Oct 27, 2023

This is fixed and will be in the next release, which should be pretty soon 🙂

Thanks for the really quick response! Is it already on the current main branch? I might give it a try

Unfortunately, I don't see anything related in https://github.com/Textualize/textual/blob/41cadfcbf10858ad4afc6c99b52b17cac1b58fbb/CHANGELOG.md

@darrenburns
Copy link
Member

darrenburns commented Oct 27, 2023

Yes, it's already in main. It's just missing from the changelog - not sure why.

Edit: Updating the changelog here - #3601

@darrenburns
Copy link
Member

Going to close this as I'm fairly certain it's resolved - if I'm wrong, don't hesitate to re-open. Thanks!

@github-actions
Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants