mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
docs plugin
This commit is contained in:
@@ -1,14 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
|
|
||||||
|
|
||||||
class Colorizer(App):
|
|
||||||
async def on_load(self):
|
|
||||||
await self.bind("r", "color('red')")
|
|
||||||
await self.bind("g", "color('green')")
|
|
||||||
await self.bind("b", "color('blue')")
|
|
||||||
|
|
||||||
def action_color(self, color: str) -> None:
|
|
||||||
self.background = f"on {color}"
|
|
||||||
|
|
||||||
|
|
||||||
Colorizer.run()
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
|
|
||||||
|
|
||||||
class Quiter(App):
|
|
||||||
async def on_load(self):
|
|
||||||
await self.bind("q", "quit")
|
|
||||||
|
|
||||||
|
|
||||||
Quiter.run()
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
|
|
||||||
|
|
||||||
class Beeper(App):
|
|
||||||
def on_key(self):
|
|
||||||
self.console.bell()
|
|
||||||
|
|
||||||
|
|
||||||
Beeper.run()
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
from textual import events
|
|
||||||
|
|
||||||
|
|
||||||
class Beeper(App):
|
|
||||||
async def on_key(self, event: events.Key) -> None:
|
|
||||||
self.console.bell()
|
|
||||||
|
|
||||||
|
|
||||||
Beeper.run()
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
|
|
||||||
|
|
||||||
class ColorChanger(App):
|
|
||||||
def on_key(self, event):
|
|
||||||
if event.key.isdigit():
|
|
||||||
self.background = f"on color({event.key})"
|
|
||||||
|
|
||||||
|
|
||||||
ColorChanger.run(log_path="textual.log")
|
|
||||||
28
docs/examples/simple.py
Normal file
28
docs/examples/simple.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from textual.app import App, ComposeResult
|
||||||
|
from textual.widgets import Static
|
||||||
|
|
||||||
|
|
||||||
|
class TextApp(App):
|
||||||
|
CSS = """
|
||||||
|
Screen {
|
||||||
|
background: darkblue;
|
||||||
|
color: white;
|
||||||
|
layout: vertical;
|
||||||
|
}
|
||||||
|
Static {
|
||||||
|
height: auto;
|
||||||
|
padding: 2;
|
||||||
|
border: heavy white;
|
||||||
|
background: #ffffff 30%;
|
||||||
|
content-align: center middle;
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def compose(self) -> ComposeResult:
|
||||||
|
yield Static("Hello")
|
||||||
|
yield Static("[b]World![/b]")
|
||||||
|
|
||||||
|
|
||||||
|
app = TextApp()
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from rich.align import Align
|
|
||||||
from rich.style import Style
|
|
||||||
|
|
||||||
from textual.app import App
|
|
||||||
from textual.widget import Widget
|
|
||||||
|
|
||||||
|
|
||||||
class Clock(Widget):
|
|
||||||
def on_mount(self):
|
|
||||||
self.set_interval(1, self.refresh)
|
|
||||||
|
|
||||||
def render(self, style: Style):
|
|
||||||
time = datetime.now().strftime("%c")
|
|
||||||
return Align.center(time, vertical="middle")
|
|
||||||
|
|
||||||
|
|
||||||
class ClockApp(App):
|
|
||||||
async def on_mount(self):
|
|
||||||
await self.screen.dock(Clock())
|
|
||||||
|
|
||||||
|
|
||||||
ClockApp.run()
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
from rich.panel import Panel
|
|
||||||
from rich.style import Style
|
|
||||||
|
|
||||||
from textual.app import App
|
|
||||||
from textual.reactive import Reactive
|
|
||||||
from textual.widget import Widget
|
|
||||||
|
|
||||||
|
|
||||||
class Hover(Widget):
|
|
||||||
|
|
||||||
mouse_over = Reactive(False)
|
|
||||||
|
|
||||||
def render(self, style: Style) -> Panel:
|
|
||||||
return Panel("Hello [b]World[/b]", style=("on red" if self.mouse_over else ""))
|
|
||||||
|
|
||||||
def on_enter(self) -> None:
|
|
||||||
self.mouse_over = True
|
|
||||||
|
|
||||||
def on_leave(self) -> None:
|
|
||||||
self.mouse_over = False
|
|
||||||
|
|
||||||
|
|
||||||
class HoverApp(App):
|
|
||||||
"""Demonstrates smooth animation"""
|
|
||||||
|
|
||||||
async def on_mount(self) -> None:
|
|
||||||
"""Build layout here."""
|
|
||||||
|
|
||||||
hovers = (Hover() for _ in range(10))
|
|
||||||
await self.screen.dock(*hovers, edge="top")
|
|
||||||
|
|
||||||
|
|
||||||
HoverApp.run(log_path="textual.log")
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
from textual.app import App
|
|
||||||
from textual.widgets import Placeholder
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleApp(App):
|
|
||||||
"""Demonstrates smooth animation"""
|
|
||||||
|
|
||||||
async def on_mount(self) -> None:
|
|
||||||
"""Build layout here."""
|
|
||||||
|
|
||||||
await self.screen.dock(Placeholder(), edge="left", size=40)
|
|
||||||
await self.screen.dock(Placeholder(), Placeholder(), edge="top")
|
|
||||||
|
|
||||||
|
|
||||||
SimpleApp.run(log_path="textual.log")
|
|
||||||
@@ -4,8 +4,22 @@ Textual is framework for rapidly creating _text user interfaces_ (TUIs from here
|
|||||||
|
|
||||||
A TUI is an application that lives within a terminal, which can have mouse and keyboard support and user interface elements like windows and panels, but is rendered purely with text. They have a number of advantages over GUI applications: they can be launched from the command line, and return to the command line, and they work over ssh.
|
A TUI is an application that lives within a terminal, which can have mouse and keyboard support and user interface elements like windows and panels, but is rendered purely with text. They have a number of advantages over GUI applications: they can be launched from the command line, and return to the command line, and they work over ssh.
|
||||||
|
|
||||||
|
## Foo
|
||||||
|
|
||||||
Creating a TUI can be challenging. It may be easier to create a GUI or web application than it is to build a TUI with traditional techniques. Often projects that could use one or the other never manage to ship either.
|
Creating a TUI can be challenging. It may be easier to create a GUI or web application than it is to build a TUI with traditional techniques. Often projects that could use one or the other never manage to ship either.
|
||||||
|
|
||||||
Textual seeks to lower the difficulty level of building a TUI by borrowing developments from the web world and to a lesser extent desktop applications. The goal is for it to be as easy to develop a TUI for your project as it would be to add a command line interface.
|
Textual seeks to lower the difficulty level of building a TUI by borrowing developments from the web world and to a lesser extent desktop applications. The goal is for it to be as easy to develop a TUI for your project as it would be to add a command line interface.XX
|
||||||
|
|
||||||
|
=== "Python"
|
||||||
|
|
||||||
|
```python
|
||||||
|
--8<-- "docs/examples/simple.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Terminal"
|
||||||
|
|
||||||
|
```{.textual columns="40" lines="10"}
|
||||||
|
--8<-- "docs/examples/simple.py"
|
||||||
|
```
|
||||||
|
|
||||||
Textual also offers a number of enhancements over traditional TUI applications by taking advantage of improvements to terminal software and the hardware it runs on. Terminals are a far cry from their roots in ancient hardware and dial-up modems, yet much of the software that runs on them hasn't kept pace.
|
Textual also offers a number of enhancements over traditional TUI applications by taking advantage of improvements to terminal software and the hardware it runs on. Terminals are a far cry from their roots in ancient hardware and dial-up modems, yet much of the software that runs on them hasn't kept pace.
|
||||||
|
|||||||
20
mkdocs.yml
20
mkdocs.yml
@@ -1,12 +1,26 @@
|
|||||||
site_name: Textual
|
site_name: Textual
|
||||||
site_url: https://example.com/
|
site_url: https://www.textualize.io/
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- pymdownx.highlight
|
- admonition
|
||||||
- pymdownx.superfences
|
- meta
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
- pymdownx.keys
|
||||||
|
- pymdownx.highlight:
|
||||||
|
anchor_linenums: true
|
||||||
|
- pymdownx.superfences:
|
||||||
|
custom_fences:
|
||||||
|
- name: textual
|
||||||
|
class: textual
|
||||||
|
format: !!python/name:textual._doc.format_svg
|
||||||
- pymdownx.inlinehilite
|
- pymdownx.inlinehilite
|
||||||
- pymdownx.superfences
|
- pymdownx.superfences
|
||||||
- pymdownx.snippets
|
- pymdownx.snippets
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
|
- pymdownx.snippets
|
||||||
|
- markdown.extensions.attr_list
|
||||||
|
|
||||||
theme:
|
theme:
|
||||||
name: material
|
name: material
|
||||||
|
|||||||
162
poetry.lock
generated
162
poetry.lock
generated
@@ -166,7 +166,7 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coverage"
|
name = "coverage"
|
||||||
version = "6.3.3"
|
version = "6.4"
|
||||||
description = "Code coverage measurement for Python"
|
description = "Code coverage measurement for Python"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -219,7 +219,7 @@ dev = ["twine", "markdown", "flake8", "wheel"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "identify"
|
name = "identify"
|
||||||
version = "2.5.0"
|
version = "2.5.1"
|
||||||
description = "File identification library for Python"
|
description = "File identification library for Python"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -238,7 +238,7 @@ python-versions = ">=3.5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "importlib-metadata"
|
name = "importlib-metadata"
|
||||||
version = "4.11.3"
|
version = "4.11.4"
|
||||||
description = "Read metadata from Python packages"
|
description = "Read metadata from Python packages"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -263,11 +263,11 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jinja2"
|
name = "jinja2"
|
||||||
version = "3.1.2"
|
version = "3.0.3"
|
||||||
description = "A very fast and expressive template engine."
|
description = "A very fast and expressive template engine."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
MarkupSafe = ">=2.0"
|
MarkupSafe = ">=2.0"
|
||||||
@@ -650,7 +650,7 @@ pyyaml = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "12.4.1"
|
version = "12.4.2"
|
||||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -701,7 +701,7 @@ python-versions = ">=3.7"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-ast"
|
name = "typed-ast"
|
||||||
version = "1.5.3"
|
version = "1.5.4"
|
||||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -773,7 +773,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "3579be8d55deb729ef79984823765900552e19284c205b7bedc92897190fb6fd"
|
content-hash = "f84a265bad38b0894c5f13b1f1abeec5b5a9f4aab3aab44d90e761103a756743"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiohttp = [
|
aiohttp = [
|
||||||
@@ -924,47 +924,47 @@ commonmark = [
|
|||||||
{file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
|
{file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
|
||||||
]
|
]
|
||||||
coverage = [
|
coverage = [
|
||||||
{file = "coverage-6.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df32ee0f4935a101e4b9a5f07b617d884a531ed5666671ff6ac66d2e8e8246d8"},
|
{file = "coverage-6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50ed480b798febce113709846b11f5d5ed1e529c88d8ae92f707806c50297abf"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75b5dbffc334e0beb4f6c503fb95e6d422770fd2d1b40a64898ea26d6c02742d"},
|
{file = "coverage-6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26f8f92699756cb7af2b30720de0c5bb8d028e923a95b6d0c891088025a1ac8f"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114944e6061b68a801c5da5427b9173a0dd9d32cd5fcc18a13de90352843737d"},
|
{file = "coverage-6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60c2147921da7f4d2d04f570e1838db32b95c5509d248f3fe6417e91437eaf41"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab88a01cd180b5640ccc9c47232e31924d5f9967ab7edd7e5c91c68eee47a69"},
|
{file = "coverage-6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750e13834b597eeb8ae6e72aa58d1d831b96beec5ad1d04479ae3772373a8088"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad8f9068f5972a46d50fe5f32c09d6ee11da69c560fcb1b4c3baea246ca4109b"},
|
{file = "coverage-6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af5b9ee0fc146e907aa0f5fb858c3b3da9199d78b7bb2c9973d95550bd40f701"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4cd696aa712e6cd16898d63cf66139dc70d998f8121ab558f0e1936396dbc579"},
|
{file = "coverage-6.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a022394996419142b33a0cf7274cb444c01d2bb123727c4bb0b9acabcb515dea"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c1a9942e282cc9d3ed522cd3e3cab081149b27ea3bda72d6f61f84eaf88c1a63"},
|
{file = "coverage-6.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5a78cf2c43b13aa6b56003707c5203f28585944c277c1f3f109c7b041b16bd39"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c06455121a089252b5943ea682187a4e0a5cf0a3fb980eb8e7ce394b144430a9"},
|
{file = "coverage-6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9229d074e097f21dfe0643d9d0140ee7433814b3f0fc3706b4abffd1e3038632"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-win32.whl", hash = "sha256:cb5311d6ccbd22578c80028c5e292a7ab9adb91bd62c1982087fad75abe2e63d"},
|
{file = "coverage-6.4-cp310-cp310-win32.whl", hash = "sha256:fb45fe08e1abc64eb836d187b20a59172053999823f7f6ef4f18a819c44ba16f"},
|
||||||
{file = "coverage-6.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:6d4a6f30f611e657495cc81a07ff7aa8cd949144e7667c5d3e680d73ba7a70e4"},
|
{file = "coverage-6.4-cp310-cp310-win_amd64.whl", hash = "sha256:3cfd07c5889ddb96a401449109a8b97a165be9d67077df6802f59708bfb07720"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:79bf405432428e989cad7b8bc60581963238f7645ae8a404f5dce90236cc0293"},
|
{file = "coverage-6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:03014a74023abaf5a591eeeaf1ac66a73d54eba178ff4cb1fa0c0a44aae70383"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:338c417613f15596af9eb7a39353b60abec9d8ce1080aedba5ecee6a5d85f8d3"},
|
{file = "coverage-6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c82f2cd69c71698152e943f4a5a6b83a3ab1db73b88f6e769fabc86074c3b08"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db094a6a4ae6329ed322a8973f83630b12715654c197dd392410400a5bfa1a73"},
|
{file = "coverage-6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b546cf2b1974ddc2cb222a109b37c6ed1778b9be7e6b0c0bc0cf0438d9e45a6"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1414e8b124611bf4df8d77215bd32cba6e3425da8ce9c1f1046149615e3a9a31"},
|
{file = "coverage-6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc173f1ce9ffb16b299f51c9ce53f66a62f4d975abe5640e976904066f3c835d"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:93b16b08f94c92cab88073ffd185070cdcb29f1b98df8b28e6649145b7f2c90d"},
|
{file = "coverage-6.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c53ad261dfc8695062fc8811ac7c162bd6096a05a19f26097f411bdf5747aee7"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fbc86ae8cc129c801e7baaafe3addf3c8d49c9c1597c44bdf2d78139707c3c62"},
|
{file = "coverage-6.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:eef5292b60b6de753d6e7f2d128d5841c7915fb1e3321c3a1fe6acfe76c38052"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b5ba058610e8289a07db2a57bce45a1793ec0d3d11db28c047aae2aa1a832572"},
|
{file = "coverage-6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:543e172ce4c0de533fa892034cce260467b213c0ea8e39da2f65f9a477425211"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-win32.whl", hash = "sha256:8329635c0781927a2c6ae068461e19674c564e05b86736ab8eb29c420ee7dc20"},
|
{file = "coverage-6.4-cp37-cp37m-win32.whl", hash = "sha256:00c8544510f3c98476bbd58201ac2b150ffbcce46a8c3e4fb89ebf01998f806a"},
|
||||||
{file = "coverage-6.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e5af1feee71099ae2e3b086ec04f57f9950e1be9ecf6c420696fea7977b84738"},
|
{file = "coverage-6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:b84ab65444dcc68d761e95d4d70f3cfd347ceca5a029f2ffec37d4f124f61311"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e814a4a5a1d95223b08cdb0f4f57029e8eab22ffdbae2f97107aeef28554517e"},
|
{file = "coverage-6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d548edacbf16a8276af13063a2b0669d58bbcfca7c55a255f84aac2870786a61"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f4fbf3633cb0713437291b8848634ea97f89c7e849c2be17a665611e433f53"},
|
{file = "coverage-6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:033ebec282793bd9eb988d0271c211e58442c31077976c19c442e24d827d356f"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3401b0d2ed9f726fadbfa35102e00d1b3547b73772a1de5508ef3bdbcb36afe7"},
|
{file = "coverage-6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742fb8b43835078dd7496c3c25a1ec8d15351df49fb0037bffb4754291ef30ce"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8586b177b4407f988731eb7f41967415b2197f35e2a6ee1a9b9b561f6323c8e9"},
|
{file = "coverage-6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55fae115ef9f67934e9f1103c9ba826b4c690e4c5bcf94482b8b2398311bf9c"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:892e7fe32191960da559a14536768a62e83e87bbb867e1b9c643e7e0fbce2579"},
|
{file = "coverage-6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd698341626f3c77784858427bad0cdd54a713115b423d22ac83a28303d1d95"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:afb03f981fadb5aed1ac6e3dd34f0488e1a0875623d557b6fad09b97a942b38a"},
|
{file = "coverage-6.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62d382f7d77eeeaff14b30516b17bcbe80f645f5cf02bb755baac376591c653c"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cbe91bc84be4e5ef0b1480d15c7b18e29c73bdfa33e07d3725da7d18e1b0aff2"},
|
{file = "coverage-6.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:016d7f5cf1c8c84f533a3c1f8f36126fbe00b2ec0ccca47cc5731c3723d327c6"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:91502bf27cbd5c83c95cfea291ef387469f2387508645602e1ca0fd8a4ba7548"},
|
{file = "coverage-6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:69432946f154c6add0e9ede03cc43b96e2ef2733110a77444823c053b1ff5166"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-win32.whl", hash = "sha256:c488db059848702aff30aa1d90ef87928d4e72e4f00717343800546fdbff0a94"},
|
{file = "coverage-6.4-cp38-cp38-win32.whl", hash = "sha256:83bd142cdec5e4a5c4ca1d4ff6fa807d28460f9db919f9f6a31babaaa8b88426"},
|
||||||
{file = "coverage-6.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6534fcdfb5c503affb6b1130db7b5bfc8a0f77fa34880146f7a5c117987d0"},
|
{file = "coverage-6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4002f9e8c1f286e986fe96ec58742b93484195defc01d5cc7809b8f7acb5ece3"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc692c9ee18f0dd3214843779ba6b275ee4bb9b9a5745ba64265bce911aefd1a"},
|
{file = "coverage-6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e4f52c272fdc82e7c65ff3f17a7179bc5f710ebc8ce8a5cadac81215e8326740"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:462105283de203df8de58a68c1bb4ba2a8a164097c2379f664fa81d6baf94b81"},
|
{file = "coverage-6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b5578efe4038be02d76c344007b13119b2b20acd009a88dde8adec2de4f630b5"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc972d829ad5ef4d4c5fcabd2bbe2add84ce8236f64ba1c0c72185da3a273130"},
|
{file = "coverage-6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8099ea680201c2221f8468c372198ceba9338a5fec0e940111962b03b3f716a"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:06f54765cdbce99901871d50fe9f41d58213f18e98b170a30ca34f47de7dd5e8"},
|
{file = "coverage-6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a00441f5ea4504f5abbc047589d09e0dc33eb447dc45a1a527c8b74bfdd32c65"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7835f76a081787f0ca62a53504361b3869840a1620049b56d803a8cb3a9eeea3"},
|
{file = "coverage-6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e76bd16f0e31bc2b07e0fb1379551fcd40daf8cdf7e24f31a29e442878a827c"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6f5fee77ec3384b934797f1873758f796dfb4f167e1296dc00f8b2e023ce6ee9"},
|
{file = "coverage-6.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d2e80dd3438e93b19e1223a9850fa65425e77f2607a364b6fd134fcd52dc9df"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:baa8be8aba3dd1e976e68677be68a960a633a6d44c325757aefaa4d66175050f"},
|
{file = "coverage-6.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:341e9c2008c481c5c72d0e0dbf64980a4b2238631a7f9780b0fe2e95755fb018"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4d06380e777dd6b35ee936f333d55b53dc4a8271036ff884c909cf6e94be8b6c"},
|
{file = "coverage-6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:21e6686a95025927775ac501e74f5940cdf6fe052292f3a3f7349b0abae6d00f"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-win32.whl", hash = "sha256:f8cabc5fd0091976ab7b020f5708335033e422de25e20ddf9416bdce2b7e07d8"},
|
{file = "coverage-6.4-cp39-cp39-win32.whl", hash = "sha256:968ed5407f9460bd5a591cefd1388cc00a8f5099de9e76234655ae48cfdbe2c3"},
|
||||||
{file = "coverage-6.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c9441d57b0963cf8340268ad62fc83de61f1613034b79c2b1053046af0c5284"},
|
{file = "coverage-6.4-cp39-cp39-win_amd64.whl", hash = "sha256:e35217031e4b534b09f9b9a5841b9344a30a6357627761d4218818b865d45055"},
|
||||||
{file = "coverage-6.3.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:d522f1dc49127eab0bfbba4e90fa068ecff0899bbf61bf4065c790ddd6c177fe"},
|
{file = "coverage-6.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:e637ae0b7b481905358624ef2e81d7fb0b1af55f5ff99f9ba05442a444b11e45"},
|
||||||
{file = "coverage-6.3.3.tar.gz", hash = "sha256:2781c43bffbbec2b8867376d4d61916f5e9c4cc168232528562a61d1b4b01879"},
|
{file = "coverage-6.4.tar.gz", hash = "sha256:727dafd7f67a6e1cad808dc884bd9c5a2f6ef1f8f6d2f22b37b96cb0080d4f49"},
|
||||||
]
|
]
|
||||||
distlib = [
|
distlib = [
|
||||||
{file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
|
{file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
|
||||||
@@ -1040,24 +1040,24 @@ ghp-import = [
|
|||||||
{file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"},
|
{file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"},
|
||||||
]
|
]
|
||||||
identify = [
|
identify = [
|
||||||
{file = "identify-2.5.0-py2.py3-none-any.whl", hash = "sha256:3acfe15a96e4272b4ec5662ee3e231ceba976ef63fd9980ed2ce9cc415df393f"},
|
{file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"},
|
||||||
{file = "identify-2.5.0.tar.gz", hash = "sha256:c83af514ea50bf2be2c4a3f2fb349442b59dc87284558ae9ff54191bff3541d2"},
|
{file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"},
|
||||||
]
|
]
|
||||||
idna = [
|
idna = [
|
||||||
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
|
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
|
||||||
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
|
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
|
||||||
]
|
]
|
||||||
importlib-metadata = [
|
importlib-metadata = [
|
||||||
{file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"},
|
{file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
|
||||||
{file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"},
|
{file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
|
||||||
]
|
]
|
||||||
iniconfig = [
|
iniconfig = [
|
||||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||||
]
|
]
|
||||||
jinja2 = [
|
jinja2 = [
|
||||||
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
|
{file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"},
|
||||||
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
|
{file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"},
|
||||||
]
|
]
|
||||||
markdown = [
|
markdown = [
|
||||||
{file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"},
|
{file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"},
|
||||||
@@ -1360,8 +1360,8 @@ pyyaml-env-tag = [
|
|||||||
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
|
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
|
||||||
]
|
]
|
||||||
rich = [
|
rich = [
|
||||||
{file = "rich-12.4.1-py3-none-any.whl", hash = "sha256:d13c6c90c42e24eb7ce660db397e8c398edd58acb7f92a2a88a95572b838aaa4"},
|
{file = "rich-12.4.2-py3-none-any.whl", hash = "sha256:abcecd4444fa27cf84de412f713305e0d5481c941f12fc202fa4fc6711f80feb"},
|
||||||
{file = "rich-12.4.1.tar.gz", hash = "sha256:d239001c0fb7de985e21ec9a4bb542b5150350330bbc1849f835b9cbc8923b91"},
|
{file = "rich-12.4.2.tar.gz", hash = "sha256:cd8c809da089740f4bd94fa6d544cf23421d4bad34988569c2d03fdbdb858f0d"},
|
||||||
]
|
]
|
||||||
six = [
|
six = [
|
||||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||||
@@ -1418,30 +1418,30 @@ tomli = [
|
|||||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
]
|
]
|
||||||
typed-ast = [
|
typed-ast = [
|
||||||
{file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"},
|
{file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"},
|
||||||
{file = "typed_ast-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:542cd732351ba8235f20faa0fc7398946fe1a57f2cdb289e5497e1e7f48cfedb"},
|
{file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"},
|
||||||
{file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc2c11ae59003d4a26dda637222d9ae924387f96acae9492df663843aefad55"},
|
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"},
|
||||||
{file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd5df1313915dbd70eaaa88c19030b441742e8b05e6103c631c83b75e0435ccc"},
|
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"},
|
||||||
{file = "typed_ast-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:e34f9b9e61333ecb0f7d79c21c28aa5cd63bec15cb7e1310d7d3da6ce886bc9b"},
|
{file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"},
|
||||||
{file = "typed_ast-1.5.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f818c5b81966d4728fec14caa338e30a70dfc3da577984d38f97816c4b3071ec"},
|
{file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"},
|
||||||
{file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3042bfc9ca118712c9809201f55355479cfcdc17449f9f8db5e744e9625c6805"},
|
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"},
|
||||||
{file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fff9fdcce59dc61ec1b317bdb319f8f4e6b69ebbe61193ae0a60c5f9333dc49"},
|
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"},
|
||||||
{file = "typed_ast-1.5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8e0b8528838ffd426fea8d18bde4c73bcb4167218998cc8b9ee0a0f2bfe678a6"},
|
{file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"},
|
||||||
{file = "typed_ast-1.5.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ef1d96ad05a291f5c36895d86d1375c0ee70595b90f6bb5f5fdbee749b146db"},
|
{file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"},
|
||||||
{file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed44e81517364cb5ba367e4f68fca01fba42a7a4690d40c07886586ac267d9b9"},
|
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"},
|
||||||
{file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f60d9de0d087454c91b3999a296d0c4558c1666771e3460621875021bf899af9"},
|
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"},
|
||||||
{file = "typed_ast-1.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9e237e74fd321a55c90eee9bc5d44be976979ad38a29bbd734148295c1ce7617"},
|
{file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"},
|
||||||
{file = "typed_ast-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ee852185964744987609b40aee1d2eb81502ae63ee8eef614558f96a56c1902d"},
|
{file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"},
|
||||||
{file = "typed_ast-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:27e46cdd01d6c3a0dd8f728b6a938a6751f7bd324817501c15fb056307f918c6"},
|
{file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"},
|
||||||
{file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d64dabc6336ddc10373922a146fa2256043b3b43e61f28961caec2a5207c56d5"},
|
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"},
|
||||||
{file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8cdf91b0c466a6c43f36c1964772918a2c04cfa83df8001ff32a89e357f8eb06"},
|
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"},
|
||||||
{file = "typed_ast-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:9cc9e1457e1feb06b075c8ef8aeb046a28ec351b1958b42c7c31c989c841403a"},
|
{file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"},
|
||||||
{file = "typed_ast-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e20d196815eeffb3d76b75223e8ffed124e65ee62097e4e73afb5fec6b993e7a"},
|
{file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"},
|
||||||
{file = "typed_ast-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:37e5349d1d5de2f4763d534ccb26809d1c24b180a477659a12c4bde9dd677d74"},
|
{file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"},
|
||||||
{file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f1a27592fac87daa4e3f16538713d705599b0a27dfe25518b80b6b017f0a6d"},
|
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"},
|
||||||
{file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8831479695eadc8b5ffed06fdfb3e424adc37962a75925668deeb503f446c0a3"},
|
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"},
|
||||||
{file = "typed_ast-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:20d5118e494478ef2d3a2702d964dae830aedd7b4d3b626d003eea526be18718"},
|
{file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"},
|
||||||
{file = "typed_ast-1.5.3.tar.gz", hash = "sha256:27f25232e2dd0edfe1f019d6bfaaf11e86e657d9bdb7b0956db95f560cceb2b3"},
|
{file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"},
|
||||||
]
|
]
|
||||||
typing-extensions = [
|
typing-extensions = [
|
||||||
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
|
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ textual = "textual.cli.cli:run"
|
|||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
rich = "^12.4.0"
|
rich = "^12.4.2"
|
||||||
|
|
||||||
#rich = {git = "git@github.com:willmcgugan/rich", rev = "link-id"}
|
#rich = {git = "git@github.com:willmcgugan/rich", rev = "link-id"}
|
||||||
click = "8.1.2"
|
click = "8.1.2"
|
||||||
@@ -35,12 +35,13 @@ pytest = "^6.2.3"
|
|||||||
black = "^22.3.0"
|
black = "^22.3.0"
|
||||||
mypy = "^0.950"
|
mypy = "^0.950"
|
||||||
pytest-cov = "^2.12.1"
|
pytest-cov = "^2.12.1"
|
||||||
mkdocs = "^1.2.3"
|
mkdocs = "^1.3.0"
|
||||||
mkdocstrings = "^0.17.0"
|
mkdocstrings = "^0.17.0"
|
||||||
mkdocs-material = "^7.3.6"
|
mkdocs-material = "^7.3.6"
|
||||||
pre-commit = "^2.13.0"
|
pre-commit = "^2.13.0"
|
||||||
pytest-aiohttp = "^1.0.4"
|
pytest-aiohttp = "^1.0.4"
|
||||||
time-machine = "^2.6.0"
|
time-machine = "^2.6.0"
|
||||||
|
Jinja2 = "<3.1.0"
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
includes = "src"
|
includes = "src"
|
||||||
|
|||||||
@@ -158,11 +158,7 @@ class BasicApp(App):
|
|||||||
tweet_body.refresh(layout=True)
|
tweet_body.refresh(layout=True)
|
||||||
|
|
||||||
|
|
||||||
app = BasicApp(
|
app = BasicApp(css_path="basic.css")
|
||||||
css_path="basic.css",
|
|
||||||
watch_css=True,
|
|
||||||
log_path="textual.log",
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run()
|
app.run()
|
||||||
|
|||||||
3
sandbox/simplest.py
Normal file
3
sandbox/simplest.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from textual.app import App
|
||||||
|
|
||||||
|
app = App()
|
||||||
@@ -552,7 +552,7 @@ class Compositor:
|
|||||||
]
|
]
|
||||||
return segment_lines
|
return segment_lines
|
||||||
|
|
||||||
def render(self) -> RenderableType:
|
def render(self, full: bool = True) -> RenderableType:
|
||||||
"""Render a layout.
|
"""Render a layout.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -561,11 +561,14 @@ class Compositor:
|
|||||||
width, height = self.size
|
width, height = self.size
|
||||||
screen_region = Region(0, 0, width, height)
|
screen_region = Region(0, 0, width, height)
|
||||||
|
|
||||||
update_regions = self._dirty_regions.copy()
|
if not full:
|
||||||
self._dirty_regions.clear()
|
update_regions = self._dirty_regions.copy()
|
||||||
if screen_region in update_regions:
|
self._dirty_regions.clear()
|
||||||
# If one of the updates is the entire screen, then we only need one update
|
if screen_region in update_regions:
|
||||||
update_regions.clear()
|
# If one of the updates is the entire screen, then we only need one update
|
||||||
|
update_regions.clear()
|
||||||
|
else:
|
||||||
|
update_regions = set()
|
||||||
|
|
||||||
if update_regions:
|
if update_regions:
|
||||||
# Create a crop regions that surrounds all updates
|
# Create a crop regions that surrounds all updates
|
||||||
|
|||||||
14
src/textual/_doc.py
Normal file
14
src/textual/_doc.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def format_svg(source, language, css_class, options, md, attrs, **kwargs):
|
||||||
|
os.environ["TEXTUAL"] = "headless"
|
||||||
|
os.environ["TEXTUAL_SCREENSHOT"] = "0.1"
|
||||||
|
os.environ["COLUMNS"] = attrs.get("columns", "80")
|
||||||
|
os.environ["LINES"] = attrs.get("lines", "24")
|
||||||
|
app_vars = {}
|
||||||
|
exec(source, app_vars)
|
||||||
|
app = app_vars["app"]
|
||||||
|
app.run()
|
||||||
|
svg = app._screenshot
|
||||||
|
return svg
|
||||||
@@ -136,8 +136,13 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
# this will create some first references to an asyncio loop.
|
# this will create some first references to an asyncio loop.
|
||||||
_init_uvloop()
|
_init_uvloop()
|
||||||
|
|
||||||
|
self.features: frozenset[FeatureFlag] = parse_features(os.getenv("TEXTUAL", ""))
|
||||||
|
|
||||||
self.console = Console(
|
self.console = Console(
|
||||||
file=sys.__stdout__, markup=False, highlight=False, emoji=False
|
file=(open(os.devnull, "wt") if self.is_headless else sys.__stdout__),
|
||||||
|
markup=True,
|
||||||
|
highlight=False,
|
||||||
|
emoji=False,
|
||||||
)
|
)
|
||||||
self.error_console = Console(markup=False, stderr=True)
|
self.error_console = Console(markup=False, stderr=True)
|
||||||
self.driver_class = driver_class or self.get_driver_class()
|
self.driver_class = driver_class or self.get_driver_class()
|
||||||
@@ -186,8 +191,6 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
|
|
||||||
self.css_path = css_path
|
self.css_path = css_path
|
||||||
|
|
||||||
self.features: frozenset[FeatureFlag] = parse_features(os.getenv("TEXTUAL", ""))
|
|
||||||
|
|
||||||
self.registry: set[MessagePump] = set()
|
self.registry: set[MessagePump] = set()
|
||||||
self.devtools = DevtoolsClient()
|
self.devtools = DevtoolsClient()
|
||||||
self._return_value: ReturnType | None = None
|
self._return_value: ReturnType | None = None
|
||||||
@@ -215,6 +218,11 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
"""Check if debug mode is enabled."""
|
"""Check if debug mode is enabled."""
|
||||||
return "debug" in self.features
|
return "debug" in self.features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_headless(self) -> bool:
|
||||||
|
"""Check if the app is running in 'headless' mode."""
|
||||||
|
return "headless" in self.features
|
||||||
|
|
||||||
def exit(self, result: ReturnType | None = None) -> None:
|
def exit(self, result: ReturnType | None = None) -> None:
|
||||||
"""Exit the app, and return the supplied result.
|
"""Exit the app, and return the supplied result.
|
||||||
|
|
||||||
@@ -430,7 +438,7 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
color_system="truecolor",
|
color_system="truecolor",
|
||||||
record=True,
|
record=True,
|
||||||
)
|
)
|
||||||
console.print(self.screen._compositor)
|
console.print(self.screen._compositor.render(full=True))
|
||||||
return console.export_svg(title=self.title)
|
return console.export_svg(title=self.title)
|
||||||
|
|
||||||
def save_screenshot(self, path: str | None = None) -> str:
|
def save_screenshot(self, path: str | None = None) -> str:
|
||||||
@@ -443,6 +451,7 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
Returns:
|
Returns:
|
||||||
str: Filename of screenshot.
|
str: Filename of screenshot.
|
||||||
"""
|
"""
|
||||||
|
self.bell()
|
||||||
if path is None:
|
if path is None:
|
||||||
svg_path = f"{self.title.lower()}_{datetime.now().isoformat()}.svg"
|
svg_path = f"{self.title.lower()}_{datetime.now().isoformat()}.svg"
|
||||||
svg_path = svg_path.replace("/", "_").replace("\\", "_")
|
svg_path = svg_path.replace("/", "_").replace("\\", "_")
|
||||||
@@ -727,13 +736,12 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
mount_event = events.Mount(sender=self)
|
mount_event = events.Mount(sender=self)
|
||||||
await self.dispatch_message(mount_event)
|
await self.dispatch_message(mount_event)
|
||||||
|
|
||||||
# TODO: don't override `self.console` here
|
|
||||||
self.console = Console(file=sys.__stdout__)
|
|
||||||
self.title = self._title
|
self.title = self._title
|
||||||
self.refresh()
|
self.refresh()
|
||||||
await self.animator.start()
|
await self.animator.start()
|
||||||
|
|
||||||
with redirect_stdout(StdoutRedirector(self.devtools, self._log_file)): # type: ignore
|
with redirect_stdout(StdoutRedirector(self.devtools, self._log_file)): # type: ignore
|
||||||
|
await self._ready()
|
||||||
await super().process_messages()
|
await super().process_messages()
|
||||||
await self.animator.stop()
|
await self.animator.stop()
|
||||||
await self.close_all()
|
await self.close_all()
|
||||||
@@ -754,6 +762,22 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
self._log_file.close()
|
self._log_file.close()
|
||||||
self._log_console = None
|
self._log_console = None
|
||||||
|
|
||||||
|
async def _ready(self) -> None:
|
||||||
|
try:
|
||||||
|
screenshot_timer = float(os.environ.get("TEXTUAL_SCREENSHOT", "0"))
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not screenshot_timer:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def on_screenshot():
|
||||||
|
svg = self.export_screenshot()
|
||||||
|
self._screenshot = svg
|
||||||
|
await self.shutdown()
|
||||||
|
|
||||||
|
self.set_timer(screenshot_timer, on_screenshot)
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
widgets = list(self.compose())
|
widgets = list(self.compose())
|
||||||
if widgets:
|
if widgets:
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
import click
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from importlib_metadata import version
|
from importlib_metadata import version
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
from textual.devtools.server import _run_devtools
|
from textual.devtools.server import _run_devtools
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from textual.app import App
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@click.version_option(version("textual"))
|
@click.version_option(version("textual"))
|
||||||
@@ -13,3 +21,66 @@ def run():
|
|||||||
@run.command(help="Run the Textual Devtools console")
|
@run.command(help="Run the Textual Devtools console")
|
||||||
def console():
|
def console():
|
||||||
_run_devtools()
|
_run_devtools()
|
||||||
|
|
||||||
|
|
||||||
|
class AppFail(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def import_app(import_name: str) -> App:
|
||||||
|
import inspect
|
||||||
|
import importlib
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from textual.app import App
|
||||||
|
|
||||||
|
sys.path.append("")
|
||||||
|
|
||||||
|
lib, _colon, name = import_name.partition(":")
|
||||||
|
name = name or "app"
|
||||||
|
|
||||||
|
try:
|
||||||
|
module = importlib.import_module(lib)
|
||||||
|
except ImportError as error:
|
||||||
|
raise
|
||||||
|
raise AppFail(str(error))
|
||||||
|
|
||||||
|
try:
|
||||||
|
app = getattr(module, name or "app")
|
||||||
|
except AttributeError:
|
||||||
|
raise AppFail(f"Unable to find {name!r} in {module!r}")
|
||||||
|
|
||||||
|
if inspect.isclass(app) and issubclass(app, App):
|
||||||
|
app = App()
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
@run.command("run")
|
||||||
|
@click.argument("import_name", metavar="IMPORT")
|
||||||
|
@click.option("--dev", "dev", help="Enable development mode", is_flag=True)
|
||||||
|
def run_app(import_name: str, dev: bool) -> None:
|
||||||
|
"""Run a Textual app."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from textual.features import parse_features
|
||||||
|
|
||||||
|
features = set(parse_features(os.environ.get("TEXTUAL", "")))
|
||||||
|
if dev:
|
||||||
|
features.add("debug")
|
||||||
|
features.add("dev")
|
||||||
|
|
||||||
|
os.environ["TEXTUAL"] = ",".join(sorted(features))
|
||||||
|
|
||||||
|
try:
|
||||||
|
app = import_app(import_name)
|
||||||
|
except AppFail as error:
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
console = Console(stderr=True)
|
||||||
|
console.print(str(error))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
app.run()
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ from threading import Event, Thread
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from .. import log
|
import rich.repr
|
||||||
|
|
||||||
|
from .. import log
|
||||||
from .. import events
|
from .. import events
|
||||||
from ..driver import Driver
|
from ..driver import Driver
|
||||||
from ..geometry import Size
|
from ..geometry import Size
|
||||||
@@ -24,6 +25,7 @@ from .._xterm_parser import XTermParser
|
|||||||
from .._profile import timer
|
from .._profile import timer
|
||||||
|
|
||||||
|
|
||||||
|
@rich.repr.auto
|
||||||
class LinuxDriver(Driver):
|
class LinuxDriver(Driver):
|
||||||
"""Powers display and input for Linux / MacOS"""
|
"""Powers display and input for Linux / MacOS"""
|
||||||
|
|
||||||
@@ -36,14 +38,19 @@ class LinuxDriver(Driver):
|
|||||||
self.exit_event = Event()
|
self.exit_event = Event()
|
||||||
self._key_thread: Thread | None = None
|
self._key_thread: Thread | None = None
|
||||||
|
|
||||||
|
def __rich_repr__(self) -> rich.repr.Result:
|
||||||
|
yield "debug", self._debug
|
||||||
|
|
||||||
def _get_terminal_size(self) -> tuple[int, int]:
|
def _get_terminal_size(self) -> tuple[int, int]:
|
||||||
width: int | None = 80
|
width: int | None = 80
|
||||||
height: int | None = 25
|
height: int | None = 25
|
||||||
|
import shutil
|
||||||
|
|
||||||
try:
|
try:
|
||||||
width, height = os.get_terminal_size(sys.__stdin__.fileno())
|
width, height = shutil.get_terminal_size()
|
||||||
except (AttributeError, ValueError, OSError):
|
except (AttributeError, ValueError, OSError):
|
||||||
try:
|
try:
|
||||||
width, height = os.get_terminal_size(sys.__stdout__.fileno())
|
width, height = shutil.get_terminal_size()
|
||||||
except (AttributeError, ValueError, OSError):
|
except (AttributeError, ValueError, OSError):
|
||||||
pass
|
pass
|
||||||
width = width or 80
|
width = width or 80
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ if sys.version_info >= (3, 8):
|
|||||||
else:
|
else:
|
||||||
from typing_extensions import Final, Literal
|
from typing_extensions import Final, Literal
|
||||||
|
|
||||||
FEATURES: Final = {"devtools", "debug"}
|
FEATURES: Final = {"devtools", "debug", "headless"}
|
||||||
|
|
||||||
FeatureFlag = Literal["devtools", "debug"]
|
FeatureFlag = Literal["devtools", "debug", "headless"]
|
||||||
|
|
||||||
|
|
||||||
def parse_features(features: str) -> frozenset[FeatureFlag]:
|
def parse_features(features: str) -> frozenset[FeatureFlag]:
|
||||||
"""Parse features env var
|
"""Parse features env var
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
features (str): Comma seprated feature flags
|
features (str): Comma separated feature flags
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
frozenset[FeatureFlag]: A frozen set of known features.
|
frozenset[FeatureFlag]: A frozen set of known features.
|
||||||
|
|||||||
Reference in New Issue
Block a user