textual icon indicating copy to clipboard operation
textual copied to clipboard

Interacting with STDIN before creating an app prevents the app from running properly

Open mw-23 opened this issue 2 years ago • 4 comments

Windows Python 3.9 rich==12.5.1 textual==0.1.18

Behavior when calling below script in cmd.exe is unexpected. Command: echo "tmp" | .\script.py

expected behavior: prints "tmp". Then runs the App (accepting inputs).

seen behaviour: App takes over terminal, but does not accept / launch anything.

script.py:

from rich.console import RenderableType
from rich.text import Text
from textual import events
from textual.app import App
from textual.reactive import Reactive
from textual.widget import Widget


class InputText(Widget):
    content: Reactive[RenderableType] = Reactive("")

    def __init__(self, title: str):
        super().__init__(title)
        self.title = title

    def on_key(self, event: events.Key) -> None:
        self.content = event.key

    def render(self) -> RenderableType:
        renderable = Align.left(Text(self.content, style="bold"))
        return renderable


class MainApp(App):
    username: Reactive[RenderableType] = Reactive("")

    async def on_mount(self) -> None:
        grid = await self.view.dock_grid(edge="left", name="left")

        grid.add_column(fraction=1, name="center", min_size=20)
        grid.add_row(name="top", min_size=2, max_size=2)

        grid.add_areas(
            area1="center,top",
        )
        self.input = InputText("input")

        grid.place(
            area1=self.input,
        )
        await self.view.dock(self.input, edge="bottom")
        await self.input.focus()


if __name__ == "__main__":
    import sys

    for i, line in enumerate(sys.stdin):
        print(line)
        if i == 0:
            break
    MainApp.run(log="textual.log")

mw-23 avatar Jul 20 '22 20:07 mw-23

I would also like to use textual in a context where stdin is a pipe. You can easily see a problem--I assume it's the same problem, more or less--with the calculator example.

I made an asciicast to demonstrate the issue: https://asciinema.org/a/mOC6vR7aApEUSBXYO6Ro49R2C

The firs time, when I run python calculator.py, it works as expected. But if I run echo foo | python calculator.py I get all of this weird output, and the calculator doesn't accept my clicks.

The weird output correlates with mouse movement and clicks, it's just that the calculator never receives them.

MatrixManAtYrService avatar Oct 15 '22 02:10 MatrixManAtYrService

Exactly the same issue!

mw-23 avatar Oct 15 '22 05:10 mw-23

@ohle has suggested a viable (for my use case) workaround in https://github.com/Textualize/textual/issues/153#issuecomment-1256933121. Does that work for you?

AdrianoKF avatar Oct 15 '22 06:10 AdrianoKF

Yes that works, thanks for pointing it out.

MatrixManAtYrService avatar Oct 16 '22 17:10 MatrixManAtYrService

https://github.com/Textualize/textual/wiki/Sorry-we-closed-your-issue

willmcgugan avatar Oct 25 '22 09:10 willmcgugan

Did we solve your problem?

Glad we could help!

github-actions[bot] avatar Oct 25 '22 09:10 github-actions[bot]

Have this similar issue oleksis/jtree/issues/1 . Think sys.stdin.read block/freeze the app from render on Windows.

In GNU/Linux we need change sys.stdin = open("/dev/tty", "r") for fix the renderables widgets

Any advice or workaround on Windows ?

oleksis avatar Dec 13 '22 00:12 oleksis