mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #192 from willmcgugan/timer-fix
Fix spurious characters on exit, and long delay
This commit is contained in:
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
## [0.1.13] - 2022-01-01
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed spurious characters when exiting app
|
||||||
|
- Fixed increasing delay when exiting
|
||||||
|
|
||||||
## [0.1.12] - 2021-09-20
|
## [0.1.12] - 2021-09-20
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
124
poetry.lock
generated
124
poetry.lock
generated
@@ -1,11 +1,3 @@
|
|||||||
[[package]]
|
|
||||||
name = "appdirs"
|
|
||||||
version = "1.4.4"
|
|
||||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
|
||||||
category = "dev"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "astunparse"
|
name = "astunparse"
|
||||||
version = "1.6.3"
|
version = "1.6.3"
|
||||||
@@ -56,25 +48,30 @@ testing = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "pytest-black (>=0.3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "black"
|
name = "black"
|
||||||
version = "20.8b1"
|
version = "21.12b0"
|
||||||
description = "The uncompromising code formatter."
|
description = "The uncompromising code formatter."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6.2"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
appdirs = "*"
|
|
||||||
click = ">=7.1.2"
|
click = ">=7.1.2"
|
||||||
mypy-extensions = ">=0.4.3"
|
mypy-extensions = ">=0.4.3"
|
||||||
pathspec = ">=0.6,<1"
|
pathspec = ">=0.9.0,<1"
|
||||||
regex = ">=2020.1.8"
|
platformdirs = ">=2"
|
||||||
toml = ">=0.10.1"
|
tomli = ">=0.2.6,<2.0.0"
|
||||||
typed-ast = ">=1.4.0"
|
typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
|
||||||
typing-extensions = ">=3.7.4"
|
typing-extensions = [
|
||||||
|
{version = ">=3.10.0.0", markers = "python_version < \"3.10\""},
|
||||||
|
{version = "!=3.10.0.1", markers = "python_version >= \"3.10\""},
|
||||||
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colorama = ["colorama (>=0.4.3)"]
|
colorama = ["colorama (>=0.4.3)"]
|
||||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
d = ["aiohttp (>=3.7.4)"]
|
||||||
|
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||||
|
python2 = ["typed-ast (>=1.4.3)"]
|
||||||
|
uvloop = ["uvloop (>=0.15.2)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cached-property"
|
name = "cached-property"
|
||||||
@@ -537,27 +534,19 @@ python-versions = ">=3.6"
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyyaml = "*"
|
pyyaml = "*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "2021.8.21"
|
|
||||||
description = "Alternative regular expression module, to replace re."
|
|
||||||
category = "dev"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "10.7.0"
|
version = "10.16.1"
|
||||||
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
|
||||||
python-versions = ">=3.6,<4.0"
|
python-versions = ">=3.6.2,<4.0.0"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
colorama = ">=0.4.0,<0.5.0"
|
colorama = ">=0.4.0,<0.5.0"
|
||||||
commonmark = ">=0.9.0,<0.10.0"
|
commonmark = ">=0.9.0,<0.10.0"
|
||||||
pygments = ">=2.6.0,<3.0.0"
|
pygments = ">=2.6.0,<3.0.0"
|
||||||
typing-extensions = {version = ">=3.7.4,<4.0.0", markers = "python_version < \"3.8\""}
|
typing-extensions = {version = ">=3.7.4,<5.0", markers = "python_version < \"3.8\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
|
jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
|
||||||
@@ -578,6 +567,14 @@ category = "dev"
|
|||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomli"
|
||||||
|
version = "1.2.3"
|
||||||
|
description = "A lil' TOML parser"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-ast"
|
name = "typed-ast"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
@@ -594,6 +591,14 @@ category = "main"
|
|||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "3.10.0.2"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.5+"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
version = "20.7.2"
|
version = "20.7.2"
|
||||||
@@ -640,13 +645,9 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "a561498403eccf382232162785fccae98ca23115b35849a7dd7331a338d8d7a4"
|
content-hash = "4e81046724f8d03d079e07d047f8bb6f14a0889716fac3938647934a0052d834"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
appdirs = [
|
|
||||||
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
|
|
||||||
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
|
|
||||||
]
|
|
||||||
astunparse = [
|
astunparse = [
|
||||||
{file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
|
{file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
|
||||||
{file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
|
{file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
|
||||||
@@ -664,7 +665,8 @@ attrs = [
|
|||||||
{file = "backports.entry_points_selectable-1.1.0.tar.gz", hash = "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a"},
|
{file = "backports.entry_points_selectable-1.1.0.tar.gz", hash = "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a"},
|
||||||
]
|
]
|
||||||
black = [
|
black = [
|
||||||
{file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
|
{file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"},
|
||||||
|
{file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"},
|
||||||
]
|
]
|
||||||
cached-property = [
|
cached-property = [
|
||||||
{file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
|
{file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
|
||||||
@@ -951,52 +953,9 @@ pyyaml-env-tag = [
|
|||||||
{file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
|
{file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
|
||||||
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
|
{file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
|
||||||
]
|
]
|
||||||
regex = [
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b0c211c55d4aac4309c3209833c803fada3fc21cdf7b74abedda42a0c9dc3ce"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d5209c3ba25864b1a57461526ebde31483db295fc6195fdfc4f8355e10f7376"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c835c30f3af5c63a80917b72115e1defb83de99c73bc727bddd979a3b449e183"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:615fb5a524cffc91ab4490b69e10ae76c1ccbfa3383ea2fad72e54a85c7d47dd"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9966337353e436e6ba652814b0a957a517feb492a98b8f9d3b6ba76d22301dcc"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a49f85f0a099a5755d0a2cc6fc337e3cb945ad6390ec892332c691ab0a045882"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-win32.whl", hash = "sha256:f93a9d8804f4cec9da6c26c8cfae2c777028b4fdd9f49de0302e26e00bb86504"},
|
|
||||||
{file = "regex-2021.8.21-cp310-cp310-win_amd64.whl", hash = "sha256:a795829dc522227265d72b25d6ee6f6d41eb2105c15912c230097c8f5bfdbcdc"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bca14dfcfd9aae06d7d8d7e105539bd77d39d06caaae57a1ce945670bae744e0"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41acdd6d64cd56f857e271009966c2ffcbd07ec9149ca91f71088574eaa4278a"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96f0c79a70642dfdf7e6a018ebcbea7ea5205e27d8e019cad442d2acfc9af267"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45f97ade892ace20252e5ccecdd7515c7df5feeb42c3d2a8b8c55920c3551c30"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f9974826aeeda32a76648fc677e3125ade379869a84aa964b683984a2dea9f1"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea9753d64cba6f226947c318a923dadaf1e21cd8db02f71652405263daa1f033"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-win32.whl", hash = "sha256:ef9326c64349e2d718373415814e754183057ebc092261387a2c2f732d9172b2"},
|
|
||||||
{file = "regex-2021.8.21-cp36-cp36m-win_amd64.whl", hash = "sha256:6dbd51c3db300ce9d3171f4106da18fe49e7045232630fe3d4c6e37cb2b39ab9"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a89ca4105f8099de349d139d1090bad387fe2b208b717b288699ca26f179acbe"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6c2b1d78ceceb6741d703508cd0e9197b34f6bf6864dab30f940f8886e04ade"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34ba9e39f8269fd66ab4f7a802794ffea6d6ac500568ec05b327a862c21ce23"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ecb6e7c45f9cd199c10ec35262b53b2247fb9a408803ed00ee5bb2b54aa626f5"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:330836ad89ff0be756b58758878409f591d4737b6a8cef26a162e2a4961c3321"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:71a904da8c9c02aee581f4452a5a988c3003207cb8033db426f29e5b2c0b7aea"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-win32.whl", hash = "sha256:b511c6009d50d5c0dd0bab85ed25bc8ad6b6f5611de3a63a59786207e82824bb"},
|
|
||||||
{file = "regex-2021.8.21-cp37-cp37m-win_amd64.whl", hash = "sha256:93f9f720081d97acee38a411e861d4ce84cbc8ea5319bc1f8e38c972c47af49f"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a195e26df1fbb40ebee75865f9b64ba692a5824ecb91c078cc665b01f7a9a36"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06ba444bbf7ede3890a912bd4904bb65bf0da8f0d8808b90545481362c978642"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8d551f1bd60b3e1c59ff55b9e8d74607a5308f66e2916948cafd13480b44a3"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebbceefbffae118ab954d3cd6bf718f5790db66152f95202ebc231d58ad4e2c2"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccd721f1d4fc42b541b633d6e339018a08dd0290dc67269df79552843a06ca92"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ae87ab669431f611c56e581679db33b9a467f87d7bf197ac384e71e4956b4456"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-win32.whl", hash = "sha256:38600fd58c2996829480de7d034fb2d3a0307110e44dae80b6b4f9b3d2eea529"},
|
|
||||||
{file = "regex-2021.8.21-cp38-cp38-win_amd64.whl", hash = "sha256:61e734c2bcb3742c3f454dfa930ea60ea08f56fd1a0eb52d8cb189a2f6be9586"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b091dcfee169ad8de21b61eb2c3a75f9f0f859f851f64fdaf9320759a3244239"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:640ccca4d0a6fcc6590f005ecd7b16c3d8f5d52174e4854f96b16f34c39d6cb7"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac95101736239260189f426b1e361dc1b704513963357dc474beb0f39f5b7759"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b79dc2b2e313565416c1e62807c7c25c67a6ff0a0f8d83a318df464555b65948"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b623fc429a38a881ab2d9a56ef30e8ea20c72a891c193f5ebbddc016e083ee"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8021dee64899f993f4b5cca323aae65aabc01a546ed44356a0965e29d7893c94"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-win32.whl", hash = "sha256:d6ec4ae13760ceda023b2e5ef1f9bc0b21e4b0830458db143794a117fdbdc044"},
|
|
||||||
{file = "regex-2021.8.21-cp39-cp39-win_amd64.whl", hash = "sha256:03840a07a402576b8e3a6261f17eb88abd653ad4e18ec46ef10c9a63f8c99ebd"},
|
|
||||||
{file = "regex-2021.8.21.tar.gz", hash = "sha256:faf08b0341828f6a29b8f7dd94d5cf8cc7c39bfc3e67b78514c54b494b66915a"},
|
|
||||||
]
|
|
||||||
rich = [
|
rich = [
|
||||||
{file = "rich-10.7.0-py3-none-any.whl", hash = "sha256:517b4e0efd064dd1fe821ca93dd3095d73380ceac1f0a07173d507d9b18f1396"},
|
{file = "rich-10.16.1-py3-none-any.whl", hash = "sha256:bbe04dd6ac09e4b00d22cb1051aa127beaf6e16c3d8687b026e96d3fca6aad52"},
|
||||||
{file = "rich-10.7.0.tar.gz", hash = "sha256:13ac80676e12cf528dc4228dc682c8402f82577c2aa67191e294350fa2c3c4e9"},
|
{file = "rich-10.16.1.tar.gz", hash = "sha256:4949e73de321784ef6664ebbc854ac82b20ff60b2865097b93f3b9b41e30da27"},
|
||||||
]
|
]
|
||||||
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"},
|
||||||
@@ -1006,6 +965,10 @@ toml = [
|
|||||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||||
]
|
]
|
||||||
|
tomli = [
|
||||||
|
{file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"},
|
||||||
|
{file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"},
|
||||||
|
]
|
||||||
typed-ast = [
|
typed-ast = [
|
||||||
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
|
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
|
||||||
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
|
{file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
|
||||||
@@ -1042,6 +1005,9 @@ typing-extensions = [
|
|||||||
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
||||||
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
||||||
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
|
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
|
||||||
|
{file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
|
||||||
|
{file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
|
||||||
|
{file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
|
||||||
]
|
]
|
||||||
virtualenv = [
|
virtualenv = [
|
||||||
{file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"},
|
{file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "textual"
|
name = "textual"
|
||||||
version = "0.1.12"
|
version = "0.1.13"
|
||||||
homepage = "https://github.com/willmcgugan/textual"
|
homepage = "https://github.com/willmcgugan/textual"
|
||||||
description = "Text User Interface using Rich"
|
description = "Text User Interface using Rich"
|
||||||
authors = ["Will McGugan <willmcgugan@gmail.com>"]
|
authors = ["Will McGugan <willmcgugan@gmail.com>"]
|
||||||
@@ -27,7 +27,7 @@ typing-extensions = { version = "^3.10.0", python = "<3.8" }
|
|||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
pytest = "^6.2.3"
|
pytest = "^6.2.3"
|
||||||
black = "^20.8b1"
|
black = "^21.11b1"
|
||||||
mypy = "^0.910"
|
mypy = "^0.910"
|
||||||
pytest-cov = "^2.12.1"
|
pytest-cov = "^2.12.1"
|
||||||
mkdocs = "^1.2.1"
|
mkdocs = "^1.2.1"
|
||||||
|
|||||||
@@ -113,10 +113,10 @@ class Animator:
|
|||||||
|
|
||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
if self._timer_task is None:
|
if self._timer_task is None:
|
||||||
self._timer_task = asyncio.get_event_loop().create_task(self._timer.run())
|
self._timer_task = self._timer.start()
|
||||||
|
|
||||||
async def stop(self) -> None:
|
async def stop(self) -> None:
|
||||||
self._timer.stop()
|
await self._timer.stop()
|
||||||
if self._timer_task:
|
if self._timer_task:
|
||||||
await self._timer_task
|
await self._timer_task
|
||||||
self._timer_task = None
|
self._timer_task = None
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import selectors
|
|||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import termios
|
import termios
|
||||||
from time import time
|
|
||||||
import tty
|
import tty
|
||||||
from typing import Any, TYPE_CHECKING
|
from typing import Any, TYPE_CHECKING
|
||||||
from threading import Event, Thread
|
from threading import Event, Thread
|
||||||
@@ -15,12 +14,14 @@ from threading import Event, Thread
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
|
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
|
||||||
from ._types import MessageTarget
|
from ._types import MessageTarget
|
||||||
from ._xterm_parser import XTermParser
|
from ._xterm_parser import XTermParser
|
||||||
|
from ._profile import timer
|
||||||
|
|
||||||
|
|
||||||
class LinuxDriver(Driver):
|
class LinuxDriver(Driver):
|
||||||
@@ -53,7 +54,7 @@ class LinuxDriver(Driver):
|
|||||||
write("\x1b[?1006h") # SET_SGR_EXT_MODE_MOUSE
|
write("\x1b[?1006h") # SET_SGR_EXT_MODE_MOUSE
|
||||||
|
|
||||||
# write("\x1b[?1007h")
|
# write("\x1b[?1007h")
|
||||||
# self.console.file.flush()
|
self.console.file.flush()
|
||||||
|
|
||||||
# Note: E.g. lxterminal understands 1000h, but not the urxvt or sgr
|
# Note: E.g. lxterminal understands 1000h, but not the urxvt or sgr
|
||||||
# extensions.
|
# extensions.
|
||||||
@@ -64,7 +65,7 @@ class LinuxDriver(Driver):
|
|||||||
write("\x1b[?1003l") #
|
write("\x1b[?1003l") #
|
||||||
write("\x1b[?1015l")
|
write("\x1b[?1015l")
|
||||||
write("\x1b[?1006l")
|
write("\x1b[?1006l")
|
||||||
# self.console.file.flush()
|
self.console.file.flush()
|
||||||
|
|
||||||
def start_application_mode(self):
|
def start_application_mode(self):
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ class LinuxDriver(Driver):
|
|||||||
|
|
||||||
self.console.show_cursor(False)
|
self.console.show_cursor(False)
|
||||||
self.console.file.write("\033[?1003h\n")
|
self.console.file.write("\033[?1003h\n")
|
||||||
|
self.console.file.flush()
|
||||||
self._key_thread = Thread(
|
self._key_thread = Thread(
|
||||||
target=self.run_input_thread, args=(asyncio.get_event_loop(),)
|
target=self.run_input_thread, args=(asyncio.get_event_loop(),)
|
||||||
)
|
)
|
||||||
@@ -145,25 +146,30 @@ class LinuxDriver(Driver):
|
|||||||
if not self.exit_event.is_set():
|
if not self.exit_event.is_set():
|
||||||
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
|
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
|
||||||
self._disable_mouse_support()
|
self._disable_mouse_support()
|
||||||
|
termios.tcflush(self.fileno, termios.TCIFLUSH)
|
||||||
self.exit_event.set()
|
self.exit_event.set()
|
||||||
if self._key_thread is not None:
|
if self._key_thread is not None:
|
||||||
self._key_thread.join()
|
self._key_thread.join()
|
||||||
except Exception:
|
except Exception as error:
|
||||||
# TODO: log this
|
# TODO: log this
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def stop_application_mode(self) -> None:
|
def stop_application_mode(self) -> None:
|
||||||
|
|
||||||
self.disable_input()
|
with timer("disable_input"):
|
||||||
|
self.disable_input()
|
||||||
|
|
||||||
if self.attrs_before is not None:
|
with timer("tcsetattr"):
|
||||||
try:
|
if self.attrs_before is not None:
|
||||||
termios.tcsetattr(self.fileno, termios.TCSANOW, self.attrs_before)
|
try:
|
||||||
except termios.error:
|
termios.tcsetattr(self.fileno, termios.TCSANOW, self.attrs_before)
|
||||||
pass
|
except termios.error:
|
||||||
|
pass
|
||||||
|
|
||||||
self.console.set_alt_screen(False)
|
with timer("set_alt_screen False, show cursor"):
|
||||||
self.console.show_cursor(True)
|
with self.console:
|
||||||
|
self.console.set_alt_screen(False)
|
||||||
|
self.console.show_cursor(True)
|
||||||
|
|
||||||
def run_input_thread(self, loop) -> None:
|
def run_input_thread(self, loop) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -180,7 +186,7 @@ class LinuxDriver(Driver):
|
|||||||
|
|
||||||
def more_data() -> bool:
|
def more_data() -> bool:
|
||||||
"""Check if there is more data to parse."""
|
"""Check if there is more data to parse."""
|
||||||
for key, events in selector.select(0.1):
|
for key, events in selector.select(0.01):
|
||||||
if events:
|
if events:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@@ -199,11 +205,11 @@ class LinuxDriver(Driver):
|
|||||||
unicode_data = decode(read(fileno, 1024))
|
unicode_data = decode(read(fileno, 1024))
|
||||||
for event in parser.feed(unicode_data):
|
for event in parser.feed(unicode_data):
|
||||||
self.process_event(event)
|
self.process_event(event)
|
||||||
except Exception:
|
except Exception as error:
|
||||||
pass
|
log(error)
|
||||||
# TODO: log
|
|
||||||
finally:
|
finally:
|
||||||
selector.close()
|
with timer("selector.close"):
|
||||||
|
selector.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import weakref
|
import weakref
|
||||||
from asyncio import CancelledError, Event, TimeoutError, wait_for
|
from asyncio import (
|
||||||
|
get_event_loop,
|
||||||
|
CancelledError,
|
||||||
|
Event,
|
||||||
|
sleep,
|
||||||
|
Task,
|
||||||
|
)
|
||||||
from time import monotonic
|
from time import monotonic
|
||||||
from typing import Awaitable, Callable, Union
|
from typing import Awaitable, Callable, Union
|
||||||
|
|
||||||
@@ -42,7 +48,6 @@ class Timer:
|
|||||||
self._callback = callback
|
self._callback = callback
|
||||||
self._repeat = repeat
|
self._repeat = repeat
|
||||||
self._skip = skip
|
self._skip = skip
|
||||||
self._stop_event = Event()
|
|
||||||
self._active = Event()
|
self._active = Event()
|
||||||
if not pause:
|
if not pause:
|
||||||
self._active.set()
|
self._active.set()
|
||||||
@@ -59,22 +64,33 @@ class Timer:
|
|||||||
raise EventTargetGone()
|
raise EventTargetGone()
|
||||||
return target
|
return target
|
||||||
|
|
||||||
def stop(self) -> None:
|
def start(self) -> Task:
|
||||||
self._active.set()
|
"""Start the timer return the task.
|
||||||
self._stop_event.set()
|
|
||||||
|
Returns:
|
||||||
|
Task: A Task instance for the timer.
|
||||||
|
"""
|
||||||
|
self._task = get_event_loop().create_task(self._run())
|
||||||
|
return self._task
|
||||||
|
|
||||||
|
async def stop(self) -> None:
|
||||||
|
"""Stop the timer, and block until it exists."""
|
||||||
|
self._task.cancel()
|
||||||
|
await self._task
|
||||||
|
|
||||||
def pause(self) -> None:
|
def pause(self) -> None:
|
||||||
|
"""Pause the timer."""
|
||||||
self._active.clear()
|
self._active.clear()
|
||||||
|
|
||||||
def resume(self) -> None:
|
def resume(self) -> None:
|
||||||
|
"""Result a paused timer."""
|
||||||
self._active.set()
|
self._active.set()
|
||||||
|
|
||||||
async def run(self) -> None:
|
async def _run(self) -> None:
|
||||||
|
"""Run the timer."""
|
||||||
count = 0
|
count = 0
|
||||||
_repeat = self._repeat
|
_repeat = self._repeat
|
||||||
_interval = self._interval
|
_interval = self._interval
|
||||||
_wait = self._stop_event.wait
|
|
||||||
_wait_active = self._active.wait
|
|
||||||
start = monotonic()
|
start = monotonic()
|
||||||
try:
|
try:
|
||||||
while _repeat is None or count <= _repeat:
|
while _repeat is None or count <= _repeat:
|
||||||
@@ -82,11 +98,9 @@ class Timer:
|
|||||||
if self._skip and next_timer < monotonic():
|
if self._skip and next_timer < monotonic():
|
||||||
count += 1
|
count += 1
|
||||||
continue
|
continue
|
||||||
try:
|
wait_time = max(0, next_timer - monotonic())
|
||||||
if await wait_for(_wait(), max(0, next_timer - monotonic())):
|
if wait_time:
|
||||||
break
|
await sleep(wait_time)
|
||||||
except TimeoutError:
|
|
||||||
pass
|
|
||||||
event = events.Timer(
|
event = events.Timer(
|
||||||
self.sender, timer=self, count=count, callback=self._callback
|
self.sender, timer=self, count=count, callback=self._callback
|
||||||
)
|
)
|
||||||
@@ -95,7 +109,6 @@ class Timer:
|
|||||||
await self.target.post_message(event)
|
await self.target.post_message(event)
|
||||||
except EventTargetGone:
|
except EventTargetGone:
|
||||||
break
|
break
|
||||||
|
await self._active.wait()
|
||||||
await _wait_active()
|
|
||||||
except CancelledError:
|
except CancelledError:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -127,8 +127,7 @@ class MessagePump:
|
|||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
) -> Timer:
|
) -> Timer:
|
||||||
timer = Timer(self, delay, self, name=name, callback=callback, repeat=0)
|
timer = Timer(self, delay, self, name=name, callback=callback, repeat=0)
|
||||||
timer_task = asyncio.get_event_loop().create_task(timer.run())
|
self._child_tasks.add(timer.start())
|
||||||
self._child_tasks.add(timer_task)
|
|
||||||
return timer
|
return timer
|
||||||
|
|
||||||
def set_interval(
|
def set_interval(
|
||||||
@@ -142,7 +141,7 @@ class MessagePump:
|
|||||||
timer = Timer(
|
timer = Timer(
|
||||||
self, interval, self, name=name, callback=callback, repeat=repeat or None
|
self, interval, self, name=name, callback=callback, repeat=repeat or None
|
||||||
)
|
)
|
||||||
self._child_tasks.add(asyncio.get_event_loop().create_task(timer.run()))
|
self._child_tasks.add(timer.start())
|
||||||
return timer
|
return timer
|
||||||
|
|
||||||
async def call_later(self, callback: Callable, *args, **kwargs) -> None:
|
async def call_later(self, callback: Callable, *args, **kwargs) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user