From 6951ff5e60c370de71cd264bb54b156416b328e8 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 13:29:49 +0000 Subject: [PATCH 01/25] Move almost all of the docs config into a "common" file With #631 in mind, start by moving the vast bulk of the documentation configuration into a "common" file, and just keep the `nav` in the main configuration file. The thinking here is that I want two entry points -- one for building the full docs for the Textual website, and one for building a local version of the docs. Because mkdocs doesn't allow for inheriting a configuration and also splicing into the `nav`, we'll be looking to duplicate the `nav` for now -- this will likely change eventually as that'll be a maintenance overhead that we don't really want (will likely look at templating it or something). For now though, let's look at the best way of splitting things up and seeing how we can generate two different versions of the docs. --- mkdocs-common.yml | 113 ++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 116 +--------------------------------------------- 2 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 mkdocs-common.yml diff --git a/mkdocs-common.yml b/mkdocs-common.yml new file mode 100644 index 000000000..0e3c77e1b --- /dev/null +++ b/mkdocs-common.yml @@ -0,0 +1,113 @@ +site_name: Textual +site_url: https://textual.textualize.io/ +repo_url: https://github.com/textualize/textual/ +edit_uri: edit/main/docs/ + +markdown_extensions: + - attr_list + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - md_in_html + - admonition + - def_list + - meta + + - toc: + permalink: true + baselevel: 1 + - pymdownx.keys + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.superfences: + custom_fences: + - name: textual + class: textual + format: !!python/name:textual._doc.format_svg + - name: rich + class: rich + format: !!python/name:textual._doc.rich + - pymdownx.inlinehilite + - pymdownx.superfences + - pymdownx.snippets + - pymdownx.tabbed: + alternate_style: true + - pymdownx.snippets + - markdown.extensions.attr_list + +theme: + name: material + custom_dir: docs/custom_theme + features: + - navigation.tabs + - navigation.indexes + - navigation.tabs.sticky + - navigation.footer + - content.code.annotate + - content.code.copy + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + accent: purple + toggle: + icon: material/weather-sunny + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + toggle: + icon: material/weather-night + name: Switch to light mode + +plugins: + +- blog: +- rss: + match_path: blog/posts/.* + date_from_meta: + as_creation: date + categories: + - categories + - release + - tags +- search: +- autorefs: +- mkdocstrings: + custom_templates: docs/_templates + default_handler: python + handlers: + python: + options: + show_root_heading: true + show_root_full_path: false + show_source: false + filters: + - "!^_" + - "^__init__$" + - "!^can_replace$" + watch: + - src/textual +- exclude: + glob: + - "**/_template.md" + + +extra_css: + - stylesheets/custom.css + + +extra: + social: + - icon: fontawesome/brands/twitter + link: https://twitter.com/textualizeio + name: textualizeio on Twitter + - icon: fontawesome/brands/github + link: https://github.com/textualize/textual/ + name: Textual on Github + - icon: fontawesome/brands/discord + link: https://discord.gg/Enf6Z3qhVr + name: Textual Discord server +copyright: Copyright © Textualize, Inc diff --git a/mkdocs.yml b/mkdocs.yml index 1748de127..87cf933be 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,4 @@ -site_name: Textual -site_url: https://textual.textualize.io/ -repo_url: https://github.com/textualize/textual/ -edit_uri: edit/main/docs/ +INHERIT: mkdocs-common.yml nav: - Introduction: @@ -176,114 +173,3 @@ nav: - "api/widget.md" - "Blog": - blog/index.md - - - -markdown_extensions: - - attr_list - - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg - - md_in_html - - admonition - - def_list - - meta - - - toc: - permalink: true - baselevel: 1 - - pymdownx.keys - - pymdownx.tasklist: - custom_checkbox: true - - pymdownx.highlight: - anchor_linenums: true - - pymdownx.inlinehilite - - pymdownx.superfences: - custom_fences: - - name: textual - class: textual - format: !!python/name:textual._doc.format_svg - - name: rich - class: rich - format: !!python/name:textual._doc.rich - - pymdownx.inlinehilite - - pymdownx.superfences - - pymdownx.snippets - - pymdownx.tabbed: - alternate_style: true - - pymdownx.snippets - - markdown.extensions.attr_list - -theme: - name: material - custom_dir: docs/custom_theme - features: - - navigation.tabs - - navigation.indexes - - navigation.tabs.sticky - - navigation.footer - - content.code.annotate - - content.code.copy - palette: - - media: "(prefers-color-scheme: light)" - scheme: default - accent: purple - toggle: - icon: material/weather-sunny - name: Switch to dark mode - - media: "(prefers-color-scheme: dark)" - scheme: slate - primary: black - toggle: - icon: material/weather-night - name: Switch to light mode - -plugins: - -- blog: -- rss: - match_path: blog/posts/.* - date_from_meta: - as_creation: date - categories: - - categories - - release - - tags -- search: -- autorefs: -- mkdocstrings: - custom_templates: docs/_templates - default_handler: python - handlers: - python: - options: - show_root_heading: true - show_root_full_path: false - show_source: false - filters: - - "!^_" - - "^__init__$" - - "!^can_replace$" - watch: - - src/textual -- exclude: - glob: - - "**/_template.md" - - -extra_css: - - stylesheets/custom.css - - -extra: - social: - - icon: fontawesome/brands/twitter - link: https://twitter.com/textualizeio - name: textualizeio on Twitter - - icon: fontawesome/brands/github - link: https://github.com/textualize/textual/ - name: Textual on Github - - icon: fontawesome/brands/discord - link: https://discord.gg/Enf6Z3qhVr - name: Textual Discord server -copyright: Copyright © Textualize, Inc From dcdad6230fe6b7e898239d6c1d76b9dffeb8a0c2 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 13:58:15 +0000 Subject: [PATCH 02/25] Move the blog config out into the "live site" config --- mkdocs-common.yml | 9 --------- mkdocs.yml | 11 +++++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/mkdocs-common.yml b/mkdocs-common.yml index 0e3c77e1b..f2b4a9d1b 100644 --- a/mkdocs-common.yml +++ b/mkdocs-common.yml @@ -64,15 +64,6 @@ theme: plugins: -- blog: -- rss: - match_path: blog/posts/.* - date_from_meta: - as_creation: date - categories: - - categories - - release - - tags - search: - autorefs: - mkdocstrings: diff --git a/mkdocs.yml b/mkdocs.yml index 87cf933be..00ab04b57 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,16 @@ INHERIT: mkdocs-common.yml +plugins: + - blog: + - rss: + match_path: blog/posts/.* + date_from_meta: + as_creation: date + categories: + - categories + - release + - tags + nav: - Introduction: - "index.md" From 9acbc0cd67717dd355c195f1da7863709a27abc7 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 13:58:44 +0000 Subject: [PATCH 03/25] Add a method of building a local copy of the docs This will build the docs into a directory called docs-local, sans the blog. Note the near-total copy/paste of the `nav` due to how mydocs does configuration inheritance; this is fine for now. --- .gitignore | 1 + Makefile | 2 + mkdocs-local.yml | 175 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 mkdocs-local.yml diff --git a/.gitignore b/.gitignore index f97bd86a6..9922d3d18 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ venv.bak/ # mkdocs documentation /site +/docs-local # mypy .mypy_cache/ diff --git a/Makefile b/Makefile index 9d71e69d7..dac8be349 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ docs-serve: mkdocs serve docs-build: mkdocs build +docs-local-build: + mkdocs build --config-file mkdocs-local.yml docs-deploy: rm -rf .screenshot_cache mkdocs gh-deploy diff --git a/mkdocs-local.yml b/mkdocs-local.yml new file mode 100644 index 000000000..c922851f1 --- /dev/null +++ b/mkdocs-local.yml @@ -0,0 +1,175 @@ +INHERIT: mkdocs-common.yml + +site_dir: docs-local + +nav: + - Introduction: + - "index.md" + - "getting_started.md" + - "help.md" + - "tutorial.md" + - Guide: + - "guide/index.md" + - "guide/devtools.md" + - "guide/app.md" + - "guide/styles.md" + - "guide/CSS.md" + - "guide/design.md" + - "guide/queries.md" + - "guide/layout.md" + - "guide/events.md" + - "guide/input.md" + - "guide/actions.md" + - "guide/reactivity.md" + - "guide/widgets.md" + - "guide/animation.md" + - "guide/screens.md" + - "roadmap.md" + - Reference: + - "reference/index.md" + - CSS Types: + - "css_types/index.md" + - "css_types/border.md" + - "css_types/color.md" + - "css_types/horizontal.md" + - "css_types/integer.md" + - "css_types/name.md" + - "css_types/number.md" + - "css_types/overflow.md" + - "css_types/percentage.md" + - "css_types/scalar.md" + - "css_types/text_align.md" + - "css_types/text_style.md" + - "css_types/vertical.md" + - Events: + - "events/index.md" + - "events/blur.md" + - "events/descendant_blur.md" + - "events/descendant_focus.md" + - "events/enter.md" + - "events/focus.md" + - "events/hide.md" + - "events/key.md" + - "events/leave.md" + - "events/load.md" + - "events/mount.md" + - "events/mouse_capture.md" + - "events/click.md" + - "events/mouse_down.md" + - "events/mouse_move.md" + - "events/mouse_release.md" + - "events/mouse_scroll_down.md" + - "events/mouse_scroll_up.md" + - "events/mouse_up.md" + - "events/paste.md" + - "events/resize.md" + - "events/screen_resume.md" + - "events/screen_suspend.md" + - "events/show.md" + - Styles: + - "styles/index.md" + - "styles/align.md" + - "styles/background.md" + - "styles/border.md" + - "styles/box_sizing.md" + - "styles/color.md" + - "styles/content_align.md" + - "styles/display.md" + - "styles/dock.md" + - Grid: + - "styles/grid/index.md" + - "styles/grid/column_span.md" + - "styles/grid/grid_columns.md" + - "styles/grid/grid_gutter.md" + - "styles/grid/grid_rows.md" + - "styles/grid/grid_size.md" + - "styles/grid/row_span.md" + - "styles/height.md" + - "styles/layer.md" + - "styles/layers.md" + - "styles/layout.md" + - Links: + - "styles/links/index.md" + - "styles/links/link_background.md" + - "styles/links/link_color.md" + - "styles/links/link_hover_background.md" + - "styles/links/link_hover_color.md" + - "styles/links/link_hover_style.md" + - "styles/links/link_style.md" + - "styles/margin.md" + - "styles/max_height.md" + - "styles/max_width.md" + - "styles/min_height.md" + - "styles/min_width.md" + - "styles/offset.md" + - "styles/opacity.md" + - "styles/outline.md" + - "styles/overflow.md" + - "styles/padding.md" + - Scrollbar colors: + - "styles/scrollbar_colors/index.md" + - "styles/scrollbar_colors/scrollbar_background.md" + - "styles/scrollbar_colors/scrollbar_background_active.md" + - "styles/scrollbar_colors/scrollbar_background_hover.md" + - "styles/scrollbar_colors/scrollbar_color.md" + - "styles/scrollbar_colors/scrollbar_color_active.md" + - "styles/scrollbar_colors/scrollbar_color_hover.md" + - "styles/scrollbar_colors/scrollbar_corner_color.md" + - "styles/scrollbar_gutter.md" + - "styles/scrollbar_size.md" + - "styles/text_align.md" + - "styles/text_opacity.md" + - "styles/text_style.md" + - "styles/tint.md" + - "styles/visibility.md" + - "styles/width.md" + - Widgets: + - "widgets/button.md" + - "widgets/checkbox.md" + - "widgets/data_table.md" + - "widgets/directory_tree.md" + - "widgets/footer.md" + - "widgets/header.md" + - "widgets/index.md" + - "widgets/input.md" + - "widgets/label.md" + - "widgets/list_item.md" + - "widgets/list_view.md" + - "widgets/placeholder.md" + - "widgets/static.md" + - "widgets/text_log.md" + - "widgets/tree.md" + - API: + - "api/index.md" + - "api/app.md" + - "api/binding.md" + - "api/button.md" + - "api/checkbox.md" + - "api/color.md" + - "api/containers.md" + - "api/coordinate.md" + - "api/data_table.md" + - "api/directory_tree.md" + - "api/dom_node.md" + - "api/events.md" + - "api/footer.md" + - "api/geometry.md" + - "api/header.md" + - "api/input.md" + - "api/label.md" + - "api/list_view.md" + - "api/list_item.md" + - "api/message_pump.md" + - "api/message.md" + - "api/pilot.md" + - "api/placeholder.md" + - "api/query.md" + - "api/reactive.md" + - "api/screen.md" + - "api/static.md" + - "api/text_log.md" + - "api/timer.md" + - "api/tree.md" + - "api/tree_node.md" + - "api/walk.md" + - "api/widget.md" From e6fbe71c0475c791136579fab630c77c15342e53 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 14:05:21 +0000 Subject: [PATCH 04/25] Solve the problem of local docs and directory/index.html links See https://github.com/Textualize/textual/issues/631#issuecomment-1418960080 -- this addresses that problem pretty much perfectly. --- mkdocs-local.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs-local.yml b/mkdocs-local.yml index c922851f1..d6249854f 100644 --- a/mkdocs-local.yml +++ b/mkdocs-local.yml @@ -1,6 +1,7 @@ INHERIT: mkdocs-common.yml site_dir: docs-local +use_directory_urls: false nav: - Introduction: From a8ded8f0a6720239649574360110c7fbbfb3b8ae Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 14:28:13 +0000 Subject: [PATCH 05/25] Move some more live-site config into the correct config file --- mkdocs-common.yml | 4 +--- mkdocs.yml | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mkdocs-common.yml b/mkdocs-common.yml index f2b4a9d1b..4f1fe51f4 100644 --- a/mkdocs-common.yml +++ b/mkdocs-common.yml @@ -1,7 +1,6 @@ site_name: Textual -site_url: https://textual.textualize.io/ + repo_url: https://github.com/textualize/textual/ -edit_uri: edit/main/docs/ markdown_extensions: - attr_list @@ -64,7 +63,6 @@ theme: plugins: -- search: - autorefs: - mkdocstrings: custom_templates: docs/_templates diff --git a/mkdocs.yml b/mkdocs.yml index 00ab04b57..d75186c46 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,10 @@ INHERIT: mkdocs-common.yml +site_url: https://textual.textualize.io/ +edit_uri: edit/main/docs/ + plugins: + - search: - blog: - rss: match_path: blog/posts/.* From 4e4353b2ce1c1eebe0e50d64f0df6a2d2900db91 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 16:04:52 +0000 Subject: [PATCH 06/25] Remove the dictionary example from the front page of the docs Sometimes, when building the docs, this would end up being a bit of an "empty" example in that the time taken to get the result back from the API would be so long that the output would be of the request just in progress. So we've decided to drop this from the front page. --- docs/index.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index 4d1c05832..1ce69322d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -81,10 +81,6 @@ Build sophisticated user interfaces with a simple Python API. Run your apps in t ``` -```{.textual path="docs/examples/events/dictionary.py" columns="100" lines="30" press="tab,_,t,e,x,t,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_"} -``` - - ```{.textual path="docs/examples/guide/layout/combining_layouts.py" columns="100", lines="30"} ``` From aece00e1dca8fc688149c1fe47ded3b6e2601a4d Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 6 Feb 2023 16:06:50 +0000 Subject: [PATCH 07/25] Remove the keystrokes from the dictionary example in events guide As well as not being necessary for the example, it also had the problem of not actually having the input in focus (there was no press of 'tab' to kick things off) and so the other keys didn't go into the `Input` as they were supposed to. --- docs/guide/events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/events.md b/docs/guide/events.md index 2fa5195c2..1b50d56a4 100644 --- a/docs/guide/events.md +++ b/docs/guide/events.md @@ -183,7 +183,7 @@ Let's look at an example which looks up word definitions from an [api](https://d === "Output" - ```{.textual path="docs/examples/events/dictionary.py" press="t,e,x,t,_,_,_,_,_,_,_,_,_,_,_"} + ```{.textual path="docs/examples/events/dictionary.py"} ``` Note the highlighted line in the above code which calls `asyncio.create_task` to run a coroutine in the background. Without this you would find typing in to the text box to be unresponsive. From a8aaa7ad820afab39202f5a89ad0cb9d755214d1 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 10:06:05 +0000 Subject: [PATCH 08/25] Experiment with the mkdocs offline plugin In doing so, don't emphasise online docs over offline, but instead make this about an online/offline split and both are as important as each other. --- .gitignore | 2 +- Makefile | 8 ++++---- mkdocs-common.yml | 18 +++++++++--------- mkdocs-local.yml => mkdocs-offline.yml | 6 ++++-- mkdocs.yml => mkdocs-online.yml | 1 - 5 files changed, 18 insertions(+), 17 deletions(-) rename mkdocs-local.yml => mkdocs-offline.yml (99%) rename mkdocs.yml => mkdocs-online.yml (99%) diff --git a/.gitignore b/.gitignore index 9922d3d18..61f16442a 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,7 @@ venv.bak/ # mkdocs documentation /site -/docs-local +/docs-offline # mypy .mypy_cache/ diff --git a/Makefile b/Makefile index dac8be349..44a28966a 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,11 @@ format-check: black --check src docs-serve: rm -rf .screenshot_cache - mkdocs serve + mkdocs serve --config-file mkdocs-online.yml docs-build: - mkdocs build -docs-local-build: - mkdocs build --config-file mkdocs-local.yml + mkdocs build --config-file mkdocs-online.yml +docs-build-offline: + mkdocs build --config-file mkdocs-offline.yml docs-deploy: rm -rf .screenshot_cache mkdocs gh-deploy diff --git a/mkdocs-common.yml b/mkdocs-common.yml index 4f1fe51f4..995a1aef9 100644 --- a/mkdocs-common.yml +++ b/mkdocs-common.yml @@ -62,12 +62,12 @@ theme: name: Switch to light mode plugins: - -- autorefs: -- mkdocstrings: - custom_templates: docs/_templates - default_handler: python - handlers: + - search: + - autorefs: + - mkdocstrings: + custom_templates: docs/_templates + default_handler: python + handlers: python: options: show_root_heading: true @@ -79,9 +79,9 @@ plugins: - "!^can_replace$" watch: - src/textual -- exclude: - glob: - - "**/_template.md" + - exclude: + glob: + - "**/_template.md" extra_css: diff --git a/mkdocs-local.yml b/mkdocs-offline.yml similarity index 99% rename from mkdocs-local.yml rename to mkdocs-offline.yml index d6249854f..6a8a5b37e 100644 --- a/mkdocs-local.yml +++ b/mkdocs-offline.yml @@ -1,7 +1,9 @@ INHERIT: mkdocs-common.yml -site_dir: docs-local -use_directory_urls: false +plugins: + - offline + +site_dir: docs-offline nav: - Introduction: diff --git a/mkdocs.yml b/mkdocs-online.yml similarity index 99% rename from mkdocs.yml rename to mkdocs-online.yml index d75186c46..2e4f2d1ca 100644 --- a/mkdocs.yml +++ b/mkdocs-online.yml @@ -4,7 +4,6 @@ site_url: https://textual.textualize.io/ edit_uri: edit/main/docs/ plugins: - - search: - blog: - rss: match_path: blog/posts/.* From 496667abedf7340cc217db75bfc924961f4c7280 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 10:29:20 +0000 Subject: [PATCH 09/25] Tidy up the Makefile a bit This removes the duplication of the screen cache cleaning, and also turns it into a target so you can do it yourself from the command line if needed. It also marks all the phony targets as such (that is, targets that aren't actually items in the filesystem). --- Makefile | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 44a28966a..c72c8d742 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,43 @@ +.PHONY: test test: pytest --cov-report term-missing --cov=textual tests/ -vv + +.PHONY: unit-test unit-test: pytest --cov-report term-missing --cov=textual tests/ -vv -m "not integration_test" + +.PHONY: test-snapshot-update test-snapshot-update: pytest --cov-report term-missing --cov=textual tests/ -vv --snapshot-update + +.PHONY: typecheck typecheck: mypy src/textual + +.PHONY: format format: black src + +.PHONY: format-check format-check: black --check src -docs-serve: + +.PHONY: clean-screenshot-cache +clean-screenshot-cache: rm -rf .screenshot_cache + +.PHONY: docs-serve +docs-serve: clean-screenshot-cache mkdocs serve --config-file mkdocs-online.yml + +.PHONY: docs-build docs-build: mkdocs build --config-file mkdocs-online.yml + +.PHONY: docs-build-offline docs-build-offline: mkdocs build --config-file mkdocs-offline.yml -docs-deploy: - rm -rf .screenshot_cache + +.PHONY: docs-deploy +docs-deploy: clean-screenshot-cache mkdocs gh-deploy From 19bde351a650b2a8ff5326405ebc66184679c6d9 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 10:52:46 +0000 Subject: [PATCH 10/25] Get search appearing again Search had gone from everywhere. Turns out that there's a very particular way you have to specify the plugins in YAML if you want to use INHERIT. --- mkdocs-common.yml | 36 ++++++++++++++++++------------------ mkdocs-offline.yml | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/mkdocs-common.yml b/mkdocs-common.yml index 995a1aef9..231012723 100644 --- a/mkdocs-common.yml +++ b/mkdocs-common.yml @@ -62,26 +62,26 @@ theme: name: Switch to light mode plugins: - - search: - - autorefs: - - mkdocstrings: - custom_templates: docs/_templates - default_handler: python - handlers: - python: - options: - show_root_heading: true - show_root_full_path: false - show_source: false - filters: - - "!^_" - - "^__init__$" - - "!^can_replace$" + search: + autorefs: + mkdocstrings: + custom_templates: docs/_templates + default_handler: python + handlers: + python: + options: + show_root_heading: true + show_root_full_path: false + show_source: false + filters: + - "!^_" + - "^__init__$" + - "!^can_replace$" watch: - src/textual - - exclude: - glob: - - "**/_template.md" + exclude: + glob: + - "**/_template.md" extra_css: diff --git a/mkdocs-offline.yml b/mkdocs-offline.yml index 6a8a5b37e..417646d1d 100644 --- a/mkdocs-offline.yml +++ b/mkdocs-offline.yml @@ -1,7 +1,7 @@ INHERIT: mkdocs-common.yml plugins: - - offline + offline: site_dir: docs-offline From f2f33233d9ae53f240874539d05f1396af749498 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 13:25:12 +0000 Subject: [PATCH 11/25] Upgrade mkdocs-material --- poetry.lock | 168 +++++++++++++++++++++++++++++++++++++++---------- pyproject.toml | 2 +- 2 files changed, 135 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7cd75899a..178f54a9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -654,14 +654,14 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "identify" -version = "2.5.15" +version = "2.5.17" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "identify-2.5.15-py2.py3-none-any.whl", hash = "sha256:1f4b36c5f50f3f950864b2a047308743f064eaa6f6645da5e5c780d1c7125487"}, - {file = "identify-2.5.15.tar.gz", hash = "sha256:c22aa206f47cc40486ecf585d27ad5f40adbfc494a3fa41dc3ed0499a23b123f"}, + {file = "identify-2.5.17-py2.py3-none-any.whl", hash = "sha256:7d526dd1283555aafcc91539acc061d8f6f59adb0a7bba462735b0a318bff7ed"}, + {file = "identify-2.5.17.tar.gz", hash = "sha256:93cc61a861052de9d4c541a7acb7e3dcc9c11b398a2144f6e52ae5285f5f4f06"}, ] [package.extras] @@ -920,23 +920,25 @@ mkdocs = "*" [[package]] name = "mkdocs-material" -version = "8.5.11" +version = "9.0.11" description = "Documentation that simply works" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "mkdocs_material-8.5.11-py3-none-any.whl", hash = "sha256:c907b4b052240a5778074a30a78f31a1f8ff82d7012356dc26898b97559f082e"}, - {file = "mkdocs_material-8.5.11.tar.gz", hash = "sha256:b0ea0513fd8cab323e8a825d6692ea07fa83e917bb5db042e523afecc7064ab7"}, + {file = "mkdocs_material-9.0.11-py3-none-any.whl", hash = "sha256:90a1e1ed41e90de5d0ab97c874b7bf6af488d0faf4aaea8e5868e01f3f1ed923"}, + {file = "mkdocs_material-9.0.11.tar.gz", hash = "sha256:aff49e4ce622a107ed563b3a6a37dc3660a45a0e4d9e7d4d2c13ce9dc02a7faf"}, ] [package.dependencies] -jinja2 = ">=3.0.2" +colorama = ">=0.4" +jinja2 = ">=3.0" markdown = ">=3.2" -mkdocs = ">=1.4.0" +mkdocs = ">=1.4.2" mkdocs-material-extensions = ">=1.1" -pygments = ">=2.12" -pymdown-extensions = ">=9.4" +pygments = ">=2.14" +pymdown-extensions = ">=9.9.1" +regex = ">=2022.4.24" requests = ">=2.26" [[package]] @@ -1215,14 +1217,14 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] @@ -1541,6 +1543,104 @@ files = [ [package.dependencies] pyyaml = "*" +[[package]] +name = "regex" +version = "2022.10.31" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, + {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, + {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, + {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, + {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, + {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, + {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, + {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, + {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, + {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, + {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, + {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, + {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, + {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, + {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, + {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, + {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, + {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, + {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, + {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, + {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, + {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, + {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, +] + [[package]] name = "requests" version = "2.28.2" @@ -1583,34 +1683,34 @@ idna2008 = ["idna"] [[package]] name = "rich" -version = "13.2.0" +version = "13.3.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.2.0-py3-none-any.whl", hash = "sha256:7c963f0d03819221e9ac561e1bc866e3f95a02248c1234daa48954e6d381c003"}, - {file = "rich-13.2.0.tar.gz", hash = "sha256:f1a00cdd3eebf999a15d85ec498bfe0b1a77efe9b34f645768a54132ef444ac5"}, + {file = "rich-13.3.1-py3-none-any.whl", hash = "sha256:8aa57747f3fc3e977684f0176a88e789be314a99f99b43b75d1e9cb5dc6db9e9"}, + {file = "rich-13.3.1.tar.gz", hash = "sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f"}, ] [package.dependencies] markdown-it-py = ">=2.1.0,<3.0.0" -pygments = ">=2.6.0,<3.0.0" +pygments = ">=2.14.0,<3.0.0" typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] -jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] +jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "66.1.1" +version = "67.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-66.1.1-py3-none-any.whl", hash = "sha256:6f590d76b713d5de4e49fe4fbca24474469f53c83632d5d0fd056f7ff7e8112b"}, - {file = "setuptools-66.1.1.tar.gz", hash = "sha256:ac4008d396bc9cd983ea483cb7139c0240a07bbc74ffb6232fceffedc6cf03a8"}, + {file = "setuptools-67.2.0-py3-none-any.whl", hash = "sha256:16ccf598aab3b506593c17378473978908a2734d7336755a8769b480906bec1c"}, + {file = "setuptools-67.2.0.tar.gz", hash = "sha256:b440ee5f7e607bb8c9de15259dba2583dd41a38879a7abc1d43a71c59524da48"}, ] [package.extras] @@ -1837,14 +1937,14 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.17.1" +version = "20.18.0" description = "Virtual Python Environment builder" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, - {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, + {file = "virtualenv-20.18.0-py3-none-any.whl", hash = "sha256:9d61e4ec8d2c0345dab329fb825eb05579043766a4b26a2f66b28948de68c722"}, + {file = "virtualenv-20.18.0.tar.gz", hash = "sha256:f262457a4d7298a6b733b920a196bf8b46c8af15bf1fd9da7142995eff15118e"}, ] [package.dependencies] @@ -1854,8 +1954,8 @@ importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} platformdirs = ">=2.4,<3" [package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] +test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] [[package]] name = "watchdog" @@ -1989,18 +2089,18 @@ typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [[package]] name = "zipp" -version = "3.11.0" +version = "3.12.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, - {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, + {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"}, + {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] @@ -2009,4 +2109,4 @@ dev = ["aiohttp", "click", "msgpack"] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "b70dc64a3c9e7a7b765252f5dd1a5de8ed6efacd0695cde32ff983b14ec55ca6" +content-hash = "8b7c3330ea6ad356b3d0c2e0ee7a2bea7674b482982dc57fe36e88638ca0b4ce" diff --git a/pyproject.toml b/pyproject.toml index 6d283c933..3bfc8dbe4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ mypy = "^0.990" pytest-cov = "^2.12.1" mkdocs = "^1.3.0" mkdocstrings = {extras = ["python"], version = "^0.20.0"} -mkdocs-material = "^8.2.15" +mkdocs-material = "^9.0.11" pre-commit = "^2.13.0" pytest-aiohttp = "^1.0.4" time-machine = "^2.6.0" From 45af25a248afc509b697612283cf14844959f972 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 13:25:39 +0000 Subject: [PATCH 12/25] Use the privacy plugin when building the offline docs This has the effect of bundling up a bunch of files that would otherwise be pulled in from the net on the client side. As well as enhancing the viewer's privacy, it also means that we increase someone's ability to view documentation locally without the need for any sort of working net connection. --- mkdocs-offline.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs-offline.yml b/mkdocs-offline.yml index 417646d1d..16b3d7993 100644 --- a/mkdocs-offline.yml +++ b/mkdocs-offline.yml @@ -2,6 +2,7 @@ INHERIT: mkdocs-common.yml plugins: offline: + privacy: site_dir: docs-offline From fcd84c564c107ccadf47079dbe03afb8e44fee60 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 7 Feb 2023 16:46:34 +0000 Subject: [PATCH 13/25] Add a build command that also builds offline docs Also include them in the source tarball. --- Makefile | 4 ++++ pyproject.toml | 1 + 2 files changed, 5 insertions(+) diff --git a/Makefile b/Makefile index c72c8d742..d1fab0705 100644 --- a/Makefile +++ b/Makefile @@ -41,3 +41,7 @@ docs-build-offline: .PHONY: docs-deploy docs-deploy: clean-screenshot-cache mkdocs gh-deploy + +.PHONY: build +build: docs-build-offline + poetry build diff --git a/pyproject.toml b/pyproject.toml index 3bfc8dbe4..4dc9fedbf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ include = [ "src/textual/py.typed", { path = "docs/examples", format = "sdist" }, + { path = "docs-offline/**/*", format = "sdist" }, { path = "tests", format = "sdist" } ] From e9fab413779a6f1e01b5b8fbdbff380fb29f7fc9 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 08:24:08 +0000 Subject: [PATCH 14/25] Relock Updating mkdocs insiders' on my personal machine so I can test building docs there and it wanted to relock again. --- poetry.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 178f54a9c..cf9699dca 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1280,22 +1280,22 @@ files = [ [[package]] name = "platformdirs" -version = "2.6.2" +version = "3.0.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"}, + {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"}, ] [package.dependencies] typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1937,21 +1937,21 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.18.0" +version = "20.19.0" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.18.0-py3-none-any.whl", hash = "sha256:9d61e4ec8d2c0345dab329fb825eb05579043766a4b26a2f66b28948de68c722"}, - {file = "virtualenv-20.18.0.tar.gz", hash = "sha256:f262457a4d7298a6b733b920a196bf8b46c8af15bf1fd9da7142995eff15118e"}, + {file = "virtualenv-20.19.0-py3-none-any.whl", hash = "sha256:54eb59e7352b573aa04d53f80fc9736ed0ad5143af445a1e539aada6eb947dd1"}, + {file = "virtualenv-20.19.0.tar.gz", hash = "sha256:37a640ba82ed40b226599c522d411e4be5edb339a0c0de030c0dc7b646d61590"}, ] [package.dependencies] distlib = ">=0.3.6,<1" filelock = ">=3.4.1,<4" importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""} -platformdirs = ">=2.4,<3" +platformdirs = ">=2.4,<4" [package.extras] docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] From 4055373725165495153910d74561ef3e1be2c3ba Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 08:24:50 +0000 Subject: [PATCH 15/25] Add a Makefile target for cleaning up the offline docs Sometimes I want to be able to test from a fresh start, so this will be helpful. --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index d1fab0705..cdc58649e 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,10 @@ docs-build: docs-build-offline: mkdocs build --config-file mkdocs-offline.yml +.PHONY: clean-offline-docs +clean-offline-docs: + rm -rf docs-offline + .PHONY: docs-deploy docs-deploy: clean-screenshot-cache mkdocs gh-deploy From 9500fa925a49c90bb7ad603f1c8a81deb6bf7cd9 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 08:26:34 +0000 Subject: [PATCH 16/25] Add a Makefile target that cleans everything cleanable --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index cdc58649e..08665bd2c 100644 --- a/Makefile +++ b/Makefile @@ -49,3 +49,6 @@ docs-deploy: clean-screenshot-cache .PHONY: build build: docs-build-offline poetry build + +.PHONY: clean +clean: clean-screenshot-cache clean-offline-docs From fb5346c8943c493758b0213113d0e88617be5579 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 08:40:47 +0000 Subject: [PATCH 17/25] Don't show the repository stats in offline mode They require a connection, which isn't very offline... --- mkdocs-common.yml | 2 -- mkdocs-online.yml | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mkdocs-common.yml b/mkdocs-common.yml index 231012723..5b21dd4fc 100644 --- a/mkdocs-common.yml +++ b/mkdocs-common.yml @@ -1,7 +1,5 @@ site_name: Textual -repo_url: https://github.com/textualize/textual/ - markdown_extensions: - attr_list - pymdownx.emoji: diff --git a/mkdocs-online.yml b/mkdocs-online.yml index 2e4f2d1ca..57b7e98f5 100644 --- a/mkdocs-online.yml +++ b/mkdocs-online.yml @@ -1,5 +1,6 @@ INHERIT: mkdocs-common.yml +repo_url: https://github.com/textualize/textual/ site_url: https://textual.textualize.io/ edit_uri: edit/main/docs/ From 93f449366fcb6f12585d885ba9c407086cc58f2e Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 08:41:16 +0000 Subject: [PATCH 18/25] Modify blog/rss plugin config to make search work again Inheriting config for mkdocs requires that you use key/value pairs for the plugins not a list of objects. --- mkdocs-online.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mkdocs-online.yml b/mkdocs-online.yml index 57b7e98f5..274f90ee9 100644 --- a/mkdocs-online.yml +++ b/mkdocs-online.yml @@ -5,15 +5,15 @@ site_url: https://textual.textualize.io/ edit_uri: edit/main/docs/ plugins: - - blog: - - rss: - match_path: blog/posts/.* - date_from_meta: - as_creation: date - categories: - - categories - - release - - tags + blog: + rss: + match_path: blog/posts/.* + date_from_meta: + as_creation: date + categories: + - categories + - release + - tags nav: - Introduction: From fbdbd8928dd39ce14ae385ff27ba58ce48997733 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 09:46:47 +0000 Subject: [PATCH 19/25] Always `poetry run` commands that need a venv It's a `Makefile` so it's handy to not have to think about if you need to be within a poetry venv when running `make`. This commit adds a `poetry run` before any command that needs the venv. This means that people who aren't in a venv can just `make something` and it'll "just work", and the same is true for those who are in a venv. --- Makefile | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 08665bd2c..22c059f59 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,28 @@ +run := poetry run + .PHONY: test test: - pytest --cov-report term-missing --cov=textual tests/ -vv + $(run) pytest --cov-report term-missing --cov=textual tests/ -vv .PHONY: unit-test unit-test: - pytest --cov-report term-missing --cov=textual tests/ -vv -m "not integration_test" + $(run) pytest --cov-report term-missing --cov=textual tests/ -vv -m "not integration_test" .PHONY: test-snapshot-update test-snapshot-update: - pytest --cov-report term-missing --cov=textual tests/ -vv --snapshot-update + $(run) pytest --cov-report term-missing --cov=textual tests/ -vv --snapshot-update .PHONY: typecheck typecheck: - mypy src/textual + $(run) mypy src/textual .PHONY: format format: - black src + $(run) black src .PHONY: format-check format-check: - black --check src + $(run) black --check src .PHONY: clean-screenshot-cache clean-screenshot-cache: @@ -28,15 +30,15 @@ clean-screenshot-cache: .PHONY: docs-serve docs-serve: clean-screenshot-cache - mkdocs serve --config-file mkdocs-online.yml + $(run) mkdocs serve --config-file mkdocs-online.yml .PHONY: docs-build docs-build: - mkdocs build --config-file mkdocs-online.yml + $(run) mkdocs build --config-file mkdocs-online.yml .PHONY: docs-build-offline docs-build-offline: - mkdocs build --config-file mkdocs-offline.yml + $(run) mkdocs build --config-file mkdocs-offline.yml .PHONY: clean-offline-docs clean-offline-docs: @@ -44,7 +46,7 @@ clean-offline-docs: .PHONY: docs-deploy docs-deploy: clean-screenshot-cache - mkdocs gh-deploy + $(run) mkdocs gh-deploy .PHONY: build build: docs-build-offline From 35be18f0e6524a88e31450ba26c1126a7c1308fd Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 10:00:48 +0000 Subject: [PATCH 20/25] Explain the elaborate include path for docs in pyproject.toml While it's still fresh in my mind as to why I wrote it like this, comment to the effect so I'm not surprised by it in the future, or so someone else reading it can know what the thinking was here. --- pyproject.toml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4dc9fedbf..086780ec1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,8 +24,13 @@ classifiers = [ include = [ "src/textual/py.typed", { path = "docs/examples", format = "sdist" }, - { path = "docs-offline/**/*", format = "sdist" }, - { path = "tests", format = "sdist" } + { path = "tests", format = "sdist" }, + # The reason for the slightly convoluted path specification here is that + # poetry populates the exclude list with the content of .gitignore, and + # it also seems like exclude tumps include. So here we specify that we + # want to package up the content of the docs-offline directory in a way + # that works around that. + { path = "docs-offline/**/*", format = "sdist" } ] [tool.poetry.scripts] From 5e172dd6357d7d35635ae6b16db3cea619b07592 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 10:02:02 +0000 Subject: [PATCH 21/25] Fully exclude the blog files from the offline docs build The blog files were still getting included and packages, just not linked to from the resulting "site". This meant that the final tarball was much bigger than it needed to be, due to animated gifs and movs an the like. This brings the tarball down from around 27M to 6.4M. --- mkdocs-offline.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkdocs-offline.yml b/mkdocs-offline.yml index 16b3d7993..228d03b9f 100644 --- a/mkdocs-offline.yml +++ b/mkdocs-offline.yml @@ -3,6 +3,10 @@ INHERIT: mkdocs-common.yml plugins: offline: privacy: + exclude: + glob: + - "**/_template.md" + - blog/* site_dir: docs-offline From a295c5f9687ce4ce2ddcae373d6889ae48bfe351 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 14:36:56 +0000 Subject: [PATCH 22/25] Work towards having a single nav file The idea here is that there is a single file for the nav for all the docs, both online and offline. The nav will be the full online nav in all its blog glory, and then the build system will strip out the nav items relating to the blog when building the offline version. There's a wrinkle or two still in here; the main one being that when doing a docs-serve, it seems that the cleaning up of the online nav doesn't happen when you Ctrl-C out of the server. I'm not 100% sure of the cause of this (there could be a couple of different reasons). For now... I'm ensuring that the online/offline nav files are excluded from git. It would be nice to find out how best to always ensure that the online nav file is removed so nobody attempting to update the docs gets confused about what to edit. --- .gitignore | 2 + Makefile | 25 +++++-- mkdocs-nav.yml | 175 ++++++++++++++++++++++++++++++++++++++++++++ mkdocs-offline.yml | 172 -------------------------------------------- mkdocs-online.yml | 176 --------------------------------------------- 5 files changed, 196 insertions(+), 354 deletions(-) create mode 100644 mkdocs-nav.yml diff --git a/.gitignore b/.gitignore index 61f16442a..d0620ea4a 100644 --- a/.gitignore +++ b/.gitignore @@ -111,6 +111,8 @@ venv.bak/ # mkdocs documentation /site /docs-offline +/mkdocs-nav-online.yml +/mkdocs-nav-offline.yml # mypy .mypy_cache/ diff --git a/Makefile b/Makefile index 22c059f59..788471e86 100644 --- a/Makefile +++ b/Makefile @@ -28,17 +28,30 @@ format-check: clean-screenshot-cache: rm -rf .screenshot_cache +.PHONY: docs-offline-nav +docs-offline-nav: + echo "INHERIT: mkdocs-offline.yml" > mkdocs-nav-offline.yml + grep -v "\- \"*[Bb]log" mkdocs-nav.yml >> mkdocs-nav-offline.yml + +.PHONY: docs-online-nav +docs-online-nav: + echo "INHERIT: mkdocs-online.yml" > mkdocs-nav-online.yml + cat mkdocs-nav.yml >> mkdocs-nav-online.yml + .PHONY: docs-serve -docs-serve: clean-screenshot-cache - $(run) mkdocs serve --config-file mkdocs-online.yml +docs-serve: clean-screenshot-cache docs-online-nav + $(run) mkdocs serve --config-file mkdocs-nav-online.yml + rm -f mkdocs-nav-online.yml .PHONY: docs-build -docs-build: - $(run) mkdocs build --config-file mkdocs-online.yml +docs-build: docs-online-nav + $(run) mkdocs build --config-file mkdocs-nav-online.yml + rm -f mkdocs-nav-online.yml .PHONY: docs-build-offline -docs-build-offline: - $(run) mkdocs build --config-file mkdocs-offline.yml +docs-build-offline: docs-offline-nav + $(run) mkdocs build --config-file mkdocs-nav-offline.yml + rm -f mkdocs-nav-offline.yml .PHONY: clean-offline-docs clean-offline-docs: diff --git a/mkdocs-nav.yml b/mkdocs-nav.yml new file mode 100644 index 000000000..e453e9276 --- /dev/null +++ b/mkdocs-nav.yml @@ -0,0 +1,175 @@ +nav: + - Introduction: + - "index.md" + - "getting_started.md" + - "help.md" + - "tutorial.md" + - Guide: + - "guide/index.md" + - "guide/devtools.md" + - "guide/app.md" + - "guide/styles.md" + - "guide/CSS.md" + - "guide/design.md" + - "guide/queries.md" + - "guide/layout.md" + - "guide/events.md" + - "guide/input.md" + - "guide/actions.md" + - "guide/reactivity.md" + - "guide/widgets.md" + - "guide/animation.md" + - "guide/screens.md" + - "roadmap.md" + - Reference: + - "reference/index.md" + - CSS Types: + - "css_types/index.md" + - "css_types/border.md" + - "css_types/color.md" + - "css_types/horizontal.md" + - "css_types/integer.md" + - "css_types/name.md" + - "css_types/number.md" + - "css_types/overflow.md" + - "css_types/percentage.md" + - "css_types/scalar.md" + - "css_types/text_align.md" + - "css_types/text_style.md" + - "css_types/vertical.md" + - Events: + - "events/index.md" + - "events/blur.md" + - "events/descendant_blur.md" + - "events/descendant_focus.md" + - "events/enter.md" + - "events/focus.md" + - "events/hide.md" + - "events/key.md" + - "events/leave.md" + - "events/load.md" + - "events/mount.md" + - "events/mouse_capture.md" + - "events/click.md" + - "events/mouse_down.md" + - "events/mouse_move.md" + - "events/mouse_release.md" + - "events/mouse_scroll_down.md" + - "events/mouse_scroll_up.md" + - "events/mouse_up.md" + - "events/paste.md" + - "events/resize.md" + - "events/screen_resume.md" + - "events/screen_suspend.md" + - "events/show.md" + - Styles: + - "styles/index.md" + - "styles/align.md" + - "styles/background.md" + - "styles/border.md" + - "styles/box_sizing.md" + - "styles/color.md" + - "styles/content_align.md" + - "styles/display.md" + - "styles/dock.md" + - Grid: + - "styles/grid/index.md" + - "styles/grid/column_span.md" + - "styles/grid/grid_columns.md" + - "styles/grid/grid_gutter.md" + - "styles/grid/grid_rows.md" + - "styles/grid/grid_size.md" + - "styles/grid/row_span.md" + - "styles/height.md" + - "styles/layer.md" + - "styles/layers.md" + - "styles/layout.md" + - Links: + - "styles/links/index.md" + - "styles/links/link_background.md" + - "styles/links/link_color.md" + - "styles/links/link_hover_background.md" + - "styles/links/link_hover_color.md" + - "styles/links/link_hover_style.md" + - "styles/links/link_style.md" + - "styles/margin.md" + - "styles/max_height.md" + - "styles/max_width.md" + - "styles/min_height.md" + - "styles/min_width.md" + - "styles/offset.md" + - "styles/opacity.md" + - "styles/outline.md" + - "styles/overflow.md" + - "styles/padding.md" + - Scrollbar colors: + - "styles/scrollbar_colors/index.md" + - "styles/scrollbar_colors/scrollbar_background.md" + - "styles/scrollbar_colors/scrollbar_background_active.md" + - "styles/scrollbar_colors/scrollbar_background_hover.md" + - "styles/scrollbar_colors/scrollbar_color.md" + - "styles/scrollbar_colors/scrollbar_color_active.md" + - "styles/scrollbar_colors/scrollbar_color_hover.md" + - "styles/scrollbar_colors/scrollbar_corner_color.md" + - "styles/scrollbar_gutter.md" + - "styles/scrollbar_size.md" + - "styles/text_align.md" + - "styles/text_opacity.md" + - "styles/text_style.md" + - "styles/tint.md" + - "styles/visibility.md" + - "styles/width.md" + - Widgets: + - "widgets/button.md" + - "widgets/checkbox.md" + - "widgets/data_table.md" + - "widgets/directory_tree.md" + - "widgets/footer.md" + - "widgets/header.md" + - "widgets/index.md" + - "widgets/input.md" + - "widgets/label.md" + - "widgets/list_item.md" + - "widgets/list_view.md" + - "widgets/placeholder.md" + - "widgets/static.md" + - "widgets/text_log.md" + - "widgets/tree.md" + - API: + - "api/index.md" + - "api/app.md" + - "api/binding.md" + - "api/button.md" + - "api/checkbox.md" + - "api/color.md" + - "api/containers.md" + - "api/coordinate.md" + - "api/data_table.md" + - "api/directory_tree.md" + - "api/dom_node.md" + - "api/events.md" + - "api/footer.md" + - "api/geometry.md" + - "api/header.md" + - "api/input.md" + - "api/label.md" + - "api/list_view.md" + - "api/list_item.md" + - "api/message_pump.md" + - "api/message.md" + - "api/pilot.md" + - "api/placeholder.md" + - "api/query.md" + - "api/reactive.md" + - "api/screen.md" + - "api/scroll_view.md" + - "api/static.md" + - "api/strip.md" + - "api/text_log.md" + - "api/timer.md" + - "api/tree.md" + - "api/tree_node.md" + - "api/walk.md" + - "api/widget.md" + - "Blog": + - blog/index.md diff --git a/mkdocs-offline.yml b/mkdocs-offline.yml index 228d03b9f..0d367af42 100644 --- a/mkdocs-offline.yml +++ b/mkdocs-offline.yml @@ -9,175 +9,3 @@ plugins: - blog/* site_dir: docs-offline - -nav: - - Introduction: - - "index.md" - - "getting_started.md" - - "help.md" - - "tutorial.md" - - Guide: - - "guide/index.md" - - "guide/devtools.md" - - "guide/app.md" - - "guide/styles.md" - - "guide/CSS.md" - - "guide/design.md" - - "guide/queries.md" - - "guide/layout.md" - - "guide/events.md" - - "guide/input.md" - - "guide/actions.md" - - "guide/reactivity.md" - - "guide/widgets.md" - - "guide/animation.md" - - "guide/screens.md" - - "roadmap.md" - - Reference: - - "reference/index.md" - - CSS Types: - - "css_types/index.md" - - "css_types/border.md" - - "css_types/color.md" - - "css_types/horizontal.md" - - "css_types/integer.md" - - "css_types/name.md" - - "css_types/number.md" - - "css_types/overflow.md" - - "css_types/percentage.md" - - "css_types/scalar.md" - - "css_types/text_align.md" - - "css_types/text_style.md" - - "css_types/vertical.md" - - Events: - - "events/index.md" - - "events/blur.md" - - "events/descendant_blur.md" - - "events/descendant_focus.md" - - "events/enter.md" - - "events/focus.md" - - "events/hide.md" - - "events/key.md" - - "events/leave.md" - - "events/load.md" - - "events/mount.md" - - "events/mouse_capture.md" - - "events/click.md" - - "events/mouse_down.md" - - "events/mouse_move.md" - - "events/mouse_release.md" - - "events/mouse_scroll_down.md" - - "events/mouse_scroll_up.md" - - "events/mouse_up.md" - - "events/paste.md" - - "events/resize.md" - - "events/screen_resume.md" - - "events/screen_suspend.md" - - "events/show.md" - - Styles: - - "styles/index.md" - - "styles/align.md" - - "styles/background.md" - - "styles/border.md" - - "styles/box_sizing.md" - - "styles/color.md" - - "styles/content_align.md" - - "styles/display.md" - - "styles/dock.md" - - Grid: - - "styles/grid/index.md" - - "styles/grid/column_span.md" - - "styles/grid/grid_columns.md" - - "styles/grid/grid_gutter.md" - - "styles/grid/grid_rows.md" - - "styles/grid/grid_size.md" - - "styles/grid/row_span.md" - - "styles/height.md" - - "styles/layer.md" - - "styles/layers.md" - - "styles/layout.md" - - Links: - - "styles/links/index.md" - - "styles/links/link_background.md" - - "styles/links/link_color.md" - - "styles/links/link_hover_background.md" - - "styles/links/link_hover_color.md" - - "styles/links/link_hover_style.md" - - "styles/links/link_style.md" - - "styles/margin.md" - - "styles/max_height.md" - - "styles/max_width.md" - - "styles/min_height.md" - - "styles/min_width.md" - - "styles/offset.md" - - "styles/opacity.md" - - "styles/outline.md" - - "styles/overflow.md" - - "styles/padding.md" - - Scrollbar colors: - - "styles/scrollbar_colors/index.md" - - "styles/scrollbar_colors/scrollbar_background.md" - - "styles/scrollbar_colors/scrollbar_background_active.md" - - "styles/scrollbar_colors/scrollbar_background_hover.md" - - "styles/scrollbar_colors/scrollbar_color.md" - - "styles/scrollbar_colors/scrollbar_color_active.md" - - "styles/scrollbar_colors/scrollbar_color_hover.md" - - "styles/scrollbar_colors/scrollbar_corner_color.md" - - "styles/scrollbar_gutter.md" - - "styles/scrollbar_size.md" - - "styles/text_align.md" - - "styles/text_opacity.md" - - "styles/text_style.md" - - "styles/tint.md" - - "styles/visibility.md" - - "styles/width.md" - - Widgets: - - "widgets/button.md" - - "widgets/checkbox.md" - - "widgets/data_table.md" - - "widgets/directory_tree.md" - - "widgets/footer.md" - - "widgets/header.md" - - "widgets/index.md" - - "widgets/input.md" - - "widgets/label.md" - - "widgets/list_item.md" - - "widgets/list_view.md" - - "widgets/placeholder.md" - - "widgets/static.md" - - "widgets/text_log.md" - - "widgets/tree.md" - - API: - - "api/index.md" - - "api/app.md" - - "api/binding.md" - - "api/button.md" - - "api/checkbox.md" - - "api/color.md" - - "api/containers.md" - - "api/coordinate.md" - - "api/data_table.md" - - "api/directory_tree.md" - - "api/dom_node.md" - - "api/events.md" - - "api/footer.md" - - "api/geometry.md" - - "api/header.md" - - "api/input.md" - - "api/label.md" - - "api/list_view.md" - - "api/list_item.md" - - "api/message_pump.md" - - "api/message.md" - - "api/pilot.md" - - "api/placeholder.md" - - "api/query.md" - - "api/reactive.md" - - "api/screen.md" - - "api/static.md" - - "api/text_log.md" - - "api/timer.md" - - "api/tree.md" - - "api/tree_node.md" - - "api/walk.md" - - "api/widget.md" diff --git a/mkdocs-online.yml b/mkdocs-online.yml index f35acfe80..58aea3fc7 100644 --- a/mkdocs-online.yml +++ b/mkdocs-online.yml @@ -14,179 +14,3 @@ plugins: - categories - release - tags - -nav: - - Introduction: - - "index.md" - - "getting_started.md" - - "help.md" - - "tutorial.md" - - Guide: - - "guide/index.md" - - "guide/devtools.md" - - "guide/app.md" - - "guide/styles.md" - - "guide/CSS.md" - - "guide/design.md" - - "guide/queries.md" - - "guide/layout.md" - - "guide/events.md" - - "guide/input.md" - - "guide/actions.md" - - "guide/reactivity.md" - - "guide/widgets.md" - - "guide/animation.md" - - "guide/screens.md" - - "roadmap.md" - - Reference: - - "reference/index.md" - - CSS Types: - - "css_types/index.md" - - "css_types/border.md" - - "css_types/color.md" - - "css_types/horizontal.md" - - "css_types/integer.md" - - "css_types/name.md" - - "css_types/number.md" - - "css_types/overflow.md" - - "css_types/percentage.md" - - "css_types/scalar.md" - - "css_types/text_align.md" - - "css_types/text_style.md" - - "css_types/vertical.md" - - Events: - - "events/index.md" - - "events/blur.md" - - "events/descendant_blur.md" - - "events/descendant_focus.md" - - "events/enter.md" - - "events/focus.md" - - "events/hide.md" - - "events/key.md" - - "events/leave.md" - - "events/load.md" - - "events/mount.md" - - "events/mouse_capture.md" - - "events/click.md" - - "events/mouse_down.md" - - "events/mouse_move.md" - - "events/mouse_release.md" - - "events/mouse_scroll_down.md" - - "events/mouse_scroll_up.md" - - "events/mouse_up.md" - - "events/paste.md" - - "events/resize.md" - - "events/screen_resume.md" - - "events/screen_suspend.md" - - "events/show.md" - - Styles: - - "styles/index.md" - - "styles/align.md" - - "styles/background.md" - - "styles/border.md" - - "styles/box_sizing.md" - - "styles/color.md" - - "styles/content_align.md" - - "styles/display.md" - - "styles/dock.md" - - Grid: - - "styles/grid/index.md" - - "styles/grid/column_span.md" - - "styles/grid/grid_columns.md" - - "styles/grid/grid_gutter.md" - - "styles/grid/grid_rows.md" - - "styles/grid/grid_size.md" - - "styles/grid/row_span.md" - - "styles/height.md" - - "styles/layer.md" - - "styles/layers.md" - - "styles/layout.md" - - Links: - - "styles/links/index.md" - - "styles/links/link_background.md" - - "styles/links/link_color.md" - - "styles/links/link_hover_background.md" - - "styles/links/link_hover_color.md" - - "styles/links/link_hover_style.md" - - "styles/links/link_style.md" - - "styles/margin.md" - - "styles/max_height.md" - - "styles/max_width.md" - - "styles/min_height.md" - - "styles/min_width.md" - - "styles/offset.md" - - "styles/opacity.md" - - "styles/outline.md" - - "styles/overflow.md" - - "styles/padding.md" - - Scrollbar colors: - - "styles/scrollbar_colors/index.md" - - "styles/scrollbar_colors/scrollbar_background.md" - - "styles/scrollbar_colors/scrollbar_background_active.md" - - "styles/scrollbar_colors/scrollbar_background_hover.md" - - "styles/scrollbar_colors/scrollbar_color.md" - - "styles/scrollbar_colors/scrollbar_color_active.md" - - "styles/scrollbar_colors/scrollbar_color_hover.md" - - "styles/scrollbar_colors/scrollbar_corner_color.md" - - "styles/scrollbar_gutter.md" - - "styles/scrollbar_size.md" - - "styles/text_align.md" - - "styles/text_opacity.md" - - "styles/text_style.md" - - "styles/tint.md" - - "styles/visibility.md" - - "styles/width.md" - - Widgets: - - "widgets/button.md" - - "widgets/checkbox.md" - - "widgets/data_table.md" - - "widgets/directory_tree.md" - - "widgets/footer.md" - - "widgets/header.md" - - "widgets/index.md" - - "widgets/input.md" - - "widgets/label.md" - - "widgets/list_item.md" - - "widgets/list_view.md" - - "widgets/placeholder.md" - - "widgets/static.md" - - "widgets/text_log.md" - - "widgets/tree.md" - - API: - - "api/index.md" - - "api/app.md" - - "api/binding.md" - - "api/button.md" - - "api/checkbox.md" - - "api/color.md" - - "api/containers.md" - - "api/coordinate.md" - - "api/data_table.md" - - "api/directory_tree.md" - - "api/dom_node.md" - - "api/events.md" - - "api/footer.md" - - "api/geometry.md" - - "api/header.md" - - "api/input.md" - - "api/label.md" - - "api/list_view.md" - - "api/list_item.md" - - "api/message_pump.md" - - "api/message.md" - - "api/pilot.md" - - "api/placeholder.md" - - "api/query.md" - - "api/reactive.md" - - "api/screen.md" - - "api/scroll_view.md" - - "api/static.md" - - "api/strip.md" - - "api/text_log.md" - - "api/timer.md" - - "api/tree.md" - - "api/tree_node.md" - - "api/walk.md" - - "api/widget.md" - - "Blog": - - blog/index.md From 5376b015f58bdf8eed5af54f5331ca759eb869dc Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 8 Feb 2023 14:58:06 +0000 Subject: [PATCH 23/25] Bring the docs deployment target into the new approach This one's a little vague right now, and I'm not sure how best to test this. Looking at the mkdocs documentation it isn't clear to me that you *can* provide the config file to the gh-build command, but there's example command lines in the docs showing that you can. Need to see if there's a safe way to test this out -- the last thing I want to do is nuke our website. --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 788471e86..6daaa8e39 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,9 @@ clean-offline-docs: rm -rf docs-offline .PHONY: docs-deploy -docs-deploy: clean-screenshot-cache - $(run) mkdocs gh-deploy +docs-deploy: clean-screenshot-cache docs-online-nav + $(run) mkdocs gh-deploy --config-file mkdocs-nav-online.yml + rm -f mkdocs-nav-online.yml .PHONY: build build: docs-build-offline From 9287f64a6690c4ccef37119aba8d5116c96e29d2 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Thu, 9 Feb 2023 13:28:08 +0000 Subject: [PATCH 24/25] Add isort pre-commit hook, sort imports in src and test directories --- .pre-commit-config.yaml | 23 ++++++--- src/textual/__init__.py | 3 +- src/textual/__main__.py | 1 - src/textual/_arrange.py | 4 +- src/textual/_asyncio.py | 1 - src/textual/_border.py | 3 +- src/textual/_callback.py | 4 +- src/textual/_clock.py | 1 - src/textual/_compositor.py | 6 +-- src/textual/_context.py | 3 +- src/textual/_doc.py | 5 +- src/textual/_easing.py | 2 +- src/textual/_immutable_sequence_view.py | 3 +- src/textual/_import_app.py | 9 ++-- src/textual/_layout.py | 3 +- src/textual/_node_list.py | 2 +- src/textual/_parser.py | 12 +---- src/textual/_partition.py | 1 - src/textual/_profile.py | 2 +- src/textual/_resolve.py | 2 +- src/textual/_sleep.py | 7 ++- src/textual/_wait.py | 2 +- src/textual/_win_sleep.py | 1 - src/textual/_xterm_parser.py | 6 +-- src/textual/app.py | 1 - src/textual/case.py | 1 - src/textual/cli/cli.py | 3 +- src/textual/cli/previews/borders.py | 3 +- src/textual/cli/previews/colors.py | 2 +- src/textual/cli/previews/easing.py | 3 +- src/textual/cli/previews/keys.py | 6 +-- src/textual/cli/tools/diagnose.py | 6 ++- src/textual/css/_help_text.py | 12 ++--- src/textual/css/_style_properties.py | 16 ++---- src/textual/css/constants.py | 1 + src/textual/css/errors.py | 2 +- src/textual/css/match.py | 4 +- src/textual/css/model.py | 7 ++- src/textual/css/parse.py | 12 ++--- src/textual/css/scalar.py | 2 +- src/textual/css/scalar_animation.py | 7 +-- src/textual/css/styles.py | 3 +- src/textual/css/tokenize.py | 2 +- src/textual/css/tokenizer.py | 2 +- src/textual/css/types.py | 1 + src/textual/demo.py | 2 +- src/textual/design.py | 3 +- src/textual/devtools/client.py | 13 ++--- src/textual/devtools/redirect_output.py | 4 +- src/textual/devtools/server.py | 1 + src/textual/devtools/service.py | 4 +- src/textual/drivers/headless_driver.py | 3 +- src/textual/drivers/linux_driver.py | 13 +++-- src/textual/geometry.py | 2 +- src/textual/layouts/factory.py | 2 +- src/textual/layouts/horizontal.py | 4 +- src/textual/layouts/vertical.py | 2 +- src/textual/message.py | 6 +-- src/textual/messages.py | 4 +- src/textual/pilot.py | 6 +-- src/textual/reactive.py | 2 +- src/textual/renderables/blank.py | 2 +- src/textual/renderables/gradient.py | 3 +- src/textual/renderables/sparkline.py | 4 +- src/textual/renderables/text_opacity.py | 2 +- src/textual/renderables/tint.py | 2 +- src/textual/renderables/underline_bar.py | 3 +- src/textual/screen.py | 6 +-- src/textual/walk.py | 2 +- src/textual/widget.py | 2 +- src/textual/widgets/__init__.py | 5 +- src/textual/widgets/__init__.pyi | 6 +-- src/textual/widgets/_button.py | 3 +- src/textual/widgets/_checkbox.py | 2 +- src/textual/widgets/_data_table.py | 2 +- src/textual/widgets/_directory_tree.py | 4 +- src/textual/widgets/_header.py | 2 +- src/textual/widgets/_input.py | 2 +- src/textual/widgets/_list_view.py | 1 + src/textual/widgets/_placeholder.py | 3 +- src/textual/widgets/_pretty.py | 1 + src/textual/widgets/_welcome.py | 10 ++-- src/textual/widgets/tabs.py | 4 +- tests/css/test_help_text.py | 18 +++---- tests/css/test_parse.py | 2 +- tests/css/test_styles.py | 3 +- tests/devtools/__init__.py | 4 +- tests/devtools/test_devtools_client.py | 1 - .../test_input_key_modification_actions.py | 1 - tests/input/test_input_value_visibility.py | 1 + tests/layouts/test_content_dimensions.py | 3 +- tests/layouts/test_factory.py | 2 +- tests/listview/test_inherit_listview.py | 2 +- tests/renderables/test_sparkline.py | 27 +++++++--- tests/renderables/test_text_opacity.py | 12 +++-- tests/renderables/test_underline_bar.py | 50 +++++++------------ tests/test_animator.py | 2 +- tests/test_arrange.py | 2 +- tests/test_auto_pilot.py | 4 +- tests/test_binding.py | 2 +- tests/test_border.py | 1 - tests/test_cache.py | 3 +- tests/test_call_later.py | 1 + tests/test_color.py | 1 - tests/test_concurrency.py | 3 +- tests/test_dom.py | 2 +- tests/test_geometry.py | 3 +- tests/test_immutable_sequence_view.py | 3 +- tests/test_loop.py | 2 +- tests/test_node_list.py | 2 +- tests/test_overflow_change.py | 1 - tests/test_paste.py | 2 +- tests/test_path.py | 2 + tests/test_query.py | 2 +- tests/test_reactive.py | 2 - tests/test_screens.py | 10 ++-- tests/test_segment_tools.py | 2 +- tests/test_strip.py | 2 +- tests/test_table.py | 2 +- tests/test_test_runner.py | 2 +- tests/test_text_backend.py | 6 +++ tests/test_unmount.py | 2 +- tests/test_widget.py | 2 +- tests/test_widget_mount_point.py | 3 +- tests/test_widget_mounting.py | 4 +- tests/test_widget_removing.py | 5 +- tests/test_xterm_parser.py | 4 +- tests/tree/test_tree_get_node_by_id.py | 4 +- tests/tree/test_tree_messages.py | 3 +- tests/tree/test_tree_node_children.py | 1 + tests/tree/test_tree_node_label.py | 3 +- 131 files changed, 268 insertions(+), 297 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bee80413b..b68fd5121 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,22 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: -- repo: https://github.com/pre-commit/pre-commit-hooks + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - args: ['--unsafe'] -- repo: https://github.com/psf/black - rev: 22.10.0 + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + args: [ '--unsafe' ] + - repo: https://github.com/pycqa/isort + rev: 5.12.0 hooks: - - id: black + - id: isort + name: isort (python) + language_version: '3.11' + args: ["--profile", "black", "--filter-files"] + - repo: https://github.com/psf/black + rev: 23.1.0 + hooks: + - id: black exclude: ^tests/snapshot_tests diff --git a/src/textual/__init__.py b/src/textual/__init__.py index 8f10728b4..0ffb3533c 100644 --- a/src/textual/__init__.py +++ b/src/textual/__init__.py @@ -1,15 +1,14 @@ from __future__ import annotations import inspect +from typing import TYPE_CHECKING, Callable import rich.repr from rich.console import RenderableType -from typing import Callable, TYPE_CHECKING from ._context import active_app from ._log import LogGroup, LogVerbosity - if TYPE_CHECKING: from typing_extensions import TypeAlias diff --git a/src/textual/__main__.py b/src/textual/__main__.py index de8c1b79f..212d16b92 100644 --- a/src/textual/__main__.py +++ b/src/textual/__main__.py @@ -1,6 +1,5 @@ from .demo import DemoApp - if __name__ == "__main__": app = DemoApp() app.run() diff --git a/src/textual/_arrange.py b/src/textual/_arrange.py index 2dc70d8ba..d14f0ddc4 100644 --- a/src/textual/_arrange.py +++ b/src/textual/_arrange.py @@ -3,11 +3,11 @@ from __future__ import annotations from collections import defaultdict from fractions import Fraction from operator import attrgetter -from typing import Sequence, TYPE_CHECKING +from typing import TYPE_CHECKING, Sequence -from .geometry import Region, Size, Spacing from ._layout import DockArrangeResult, WidgetPlacement from ._partition import partition +from .geometry import Region, Size, Spacing if TYPE_CHECKING: from .widget import Widget diff --git a/src/textual/_asyncio.py b/src/textual/_asyncio.py index f5c4aa5a4..ea9bf0835 100644 --- a/src/textual/_asyncio.py +++ b/src/textual/_asyncio.py @@ -5,7 +5,6 @@ Compatibility layer for asyncio. from __future__ import annotations - import sys __all__ = ["create_task"] diff --git a/src/textual/_border.py b/src/textual/_border.py index cded7790a..2da79b0ee 100644 --- a/src/textual/_border.py +++ b/src/textual/_border.py @@ -1,8 +1,7 @@ from __future__ import annotations from functools import lru_cache -from typing import cast, Tuple, Union -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Tuple, Union, cast from rich.segment import Segment from rich.style import Style diff --git a/src/textual/_callback.py b/src/textual/_callback.py index 2759e3de4..ee3801454 100644 --- a/src/textual/_callback.py +++ b/src/textual/_callback.py @@ -2,8 +2,8 @@ from __future__ import annotations import asyncio from functools import lru_cache -from inspect import signature, isawaitable -from typing import Any, Callable, TYPE_CHECKING +from inspect import isawaitable, signature +from typing import TYPE_CHECKING, Any, Callable from . import active_app diff --git a/src/textual/_clock.py b/src/textual/_clock.py index 9867ba848..408b64f87 100644 --- a/src/textual/_clock.py +++ b/src/textual/_clock.py @@ -2,7 +2,6 @@ import asyncio from ._time import time - """ A module that serves as the single source of truth for everything time-related in a Textual app. Having this logic centralised makes it easier to simulate time in integration tests, diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index a74910d78..5489c8687 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -25,14 +25,14 @@ from rich.style import Style from . import errors from ._cells import cell_len from ._loop import loop_last -from .strip import Strip from .geometry import NULL_OFFSET, Offset, Region, Size - +from .strip import Strip if TYPE_CHECKING: - from .widget import Widget from typing_extensions import TypeAlias + from .widget import Widget + class ReflowResult(NamedTuple): """The result of a reflow operation. Describes the chances to widgets.""" diff --git a/src/textual/_context.py b/src/textual/_context.py index 625152a95..6a5562476 100644 --- a/src/textual/_context.py +++ b/src/textual/_context.py @@ -1,6 +1,5 @@ -from typing import TYPE_CHECKING - from contextvars import ContextVar +from typing import TYPE_CHECKING if TYPE_CHECKING: from .app import App diff --git a/src/textual/_doc.py b/src/textual/_doc.py index 91639d6e5..b4921ed70 100644 --- a/src/textual/_doc.py +++ b/src/textual/_doc.py @@ -2,14 +2,13 @@ from __future__ import annotations import hashlib import os -from pathlib import Path import shlex +from pathlib import Path from typing import Iterable +from textual._import_app import import_app from textual.app import App from textual.pilot import Pilot -from textual._import_app import import_app - SCREENSHOT_CACHE = ".screenshot_cache" diff --git a/src/textual/_easing.py b/src/textual/_easing.py index 007b643b2..13b274ddd 100644 --- a/src/textual/_easing.py +++ b/src/textual/_easing.py @@ -3,7 +3,7 @@ Define a series of easing functions for more natural-looking animations. Taken from https://easings.net/ and translated from JavaScript. """ -from math import pi, cos, sin, sqrt +from math import cos, pi, sin, sqrt def _in_out_expo(x: float) -> float: diff --git a/src/textual/_immutable_sequence_view.py b/src/textual/_immutable_sequence_view.py index fafb274e8..b9c34f0f0 100644 --- a/src/textual/_immutable_sequence_view.py +++ b/src/textual/_immutable_sequence_view.py @@ -1,8 +1,9 @@ """Provides an immutable sequence view class.""" from __future__ import annotations + from sys import maxsize -from typing import Generic, TypeVar, Iterator, overload, Sequence +from typing import Generic, Iterator, Sequence, TypeVar, overload T = TypeVar("T") diff --git a/src/textual/_import_app.py b/src/textual/_import_app.py index 4fedc4376..8176caf72 100644 --- a/src/textual/_import_app.py +++ b/src/textual/_import_app.py @@ -1,12 +1,11 @@ from __future__ import annotations import os -import sys import runpy import shlex +import sys from pathlib import Path -from typing import cast, TYPE_CHECKING - +from typing import TYPE_CHECKING, cast if TYPE_CHECKING: from textual.app import App @@ -46,10 +45,10 @@ def import_app(import_name: str) -> App: A Textual application """ - import inspect import importlib + import inspect - from textual.app import App, WINDOWS + from textual.app import WINDOWS, App import_name, *argv = shlex.split(import_name, posix=not WINDOWS) drive, import_name = os.path.splitdrive(import_name) diff --git a/src/textual/_layout.py b/src/textual/_layout.py index 22c7129cd..5556a705e 100644 --- a/src/textual/_layout.py +++ b/src/textual/_layout.py @@ -1,12 +1,13 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import ClassVar, NamedTuple, TYPE_CHECKING +from typing import TYPE_CHECKING, ClassVar, NamedTuple from .geometry import Region, Size, Spacing if TYPE_CHECKING: from typing_extensions import TypeAlias + from .widget import Widget ArrangeResult: TypeAlias = "tuple[list[WidgetPlacement], set[Widget]]" diff --git a/src/textual/_node_list.py b/src/textual/_node_list.py index b8a714bc1..d5e4051cb 100644 --- a/src/textual/_node_list.py +++ b/src/textual/_node_list.py @@ -1,6 +1,6 @@ from __future__ import annotations -import sys +import sys from typing import TYPE_CHECKING, Any, Iterator, Sequence, overload import rich.repr diff --git a/src/textual/_parser.py b/src/textual/_parser.py index 5163a6014..54b0f49c6 100644 --- a/src/textual/_parser.py +++ b/src/textual/_parser.py @@ -1,16 +1,8 @@ from __future__ import annotations -from collections import deque import io -from typing import ( - Callable, - Deque, - Generator, - TypeVar, - Generic, - Union, - Iterable, -) +from collections import deque +from typing import Callable, Deque, Generator, Generic, Iterable, TypeVar, Union class ParseError(Exception): diff --git a/src/textual/_partition.py b/src/textual/_partition.py index be431af0c..858846f54 100644 --- a/src/textual/_partition.py +++ b/src/textual/_partition.py @@ -2,7 +2,6 @@ from __future__ import annotations from typing import Callable, Iterable, TypeVar - T = TypeVar("T") diff --git a/src/textual/_profile.py b/src/textual/_profile.py index a64f6402f..4a0199a6f 100644 --- a/src/textual/_profile.py +++ b/src/textual/_profile.py @@ -4,8 +4,8 @@ Timer context manager, only used in debug. """ import contextlib -from typing import Generator from time import perf_counter +from typing import Generator from . import log diff --git a/src/textual/_resolve.py b/src/textual/_resolve.py index 5a6961381..0a6671377 100644 --- a/src/textual/_resolve.py +++ b/src/textual/_resolve.py @@ -2,7 +2,7 @@ from __future__ import annotations from fractions import Fraction from itertools import accumulate -from typing import Sequence, cast, TYPE_CHECKING +from typing import TYPE_CHECKING, Sequence, cast from typing_extensions import Literal diff --git a/src/textual/_sleep.py b/src/textual/_sleep.py index 4b6176435..bdc7010dc 100644 --- a/src/textual/_sleep.py +++ b/src/textual/_sleep.py @@ -1,9 +1,8 @@ from __future__ import annotations - -from time import sleep, perf_counter -from asyncio import get_running_loop, Future -from threading import Thread, Event +from asyncio import Future, get_running_loop +from threading import Event, Thread +from time import perf_counter, sleep class Sleeper(Thread): diff --git a/src/textual/_wait.py b/src/textual/_wait.py index f7ed7d3f3..92fe8f761 100644 --- a/src/textual/_wait.py +++ b/src/textual/_wait.py @@ -1,5 +1,5 @@ from asyncio import sleep -from time import process_time, monotonic +from time import monotonic, process_time SLEEP_GRANULARITY: float = 1 / 50 SLEEP_IDLE: float = SLEEP_GRANULARITY / 2.0 diff --git a/src/textual/_win_sleep.py b/src/textual/_win_sleep.py index 16e91285d..c8dd4517a 100644 --- a/src/textual/_win_sleep.py +++ b/src/textual/_win_sleep.py @@ -7,7 +7,6 @@ This should only be imported on Windows. from time import sleep as time_sleep - __all__ = ["sleep"] diff --git a/src/textual/_xterm_parser.py b/src/textual/_xterm_parser.py index 7111fca50..336da9af0 100644 --- a/src/textual/_xterm_parser.py +++ b/src/textual/_xterm_parser.py @@ -1,17 +1,15 @@ from __future__ import annotations -import unicodedata import re +import unicodedata from typing import Any, Callable, Generator, Iterable -from . import events -from . import messages +from . import events, messages from ._ansi_sequences import ANSI_SEQUENCES_KEYS from ._parser import Awaitable, Parser, TokenCallback from ._types import MessageTarget from .keys import KEY_NAME_REPLACEMENTS - # When trying to determine whether the current sequence is a supported/valid # escape sequence, at which length should we give up and consider our search # to be unsuccessful? diff --git a/src/textual/app.py b/src/textual/app.py index d6a0d766d..4398bca2b 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -50,7 +50,6 @@ from ._context import active_app from ._event_broker import NoHandler, extract_handler_actions from ._filter import LineFilter, Monochrome from ._path import _make_path_object_relative - from ._wait import wait_for_idle from .actions import SkipAction from .await_remove import AwaitRemove diff --git a/src/textual/case.py b/src/textual/case.py index 6c3414c46..e92dfa3fb 100644 --- a/src/textual/case.py +++ b/src/textual/case.py @@ -1,5 +1,4 @@ import re - from typing import Match, Pattern diff --git a/src/textual/cli/cli.py b/src/textual/cli/cli.py index b7048f807..a4897bf62 100644 --- a/src/textual/cli/cli.py +++ b/src/textual/cli/cli.py @@ -10,8 +10,8 @@ except ImportError: from importlib_metadata import version +from textual._import_app import AppFail, import_app from textual.pilot import Pilot -from textual._import_app import import_app, AppFail @click.group() @@ -26,6 +26,7 @@ def run(): def console(verbose: bool, exclude: list[str]) -> None: """Launch the textual console.""" from rich.console import Console + from textual.devtools.server import _run_devtools console = Console() diff --git a/src/textual/cli/previews/borders.py b/src/textual/cli/previews/borders.py index 5eb8d26e7..a33320a0a 100644 --- a/src/textual/cli/previews/borders.py +++ b/src/textual/cli/previews/borders.py @@ -1,8 +1,7 @@ from textual.app import App, ComposeResult from textual.constants import BORDERS -from textual.widgets import Button, Label from textual.containers import Vertical - +from textual.widgets import Button, Label TEXT = """I must not fear. Fear is the mind-killer. diff --git a/src/textual/cli/previews/colors.py b/src/textual/cli/previews/colors.py index 3ae0eb669..1cbc04f9c 100644 --- a/src/textual/cli/previews/colors.py +++ b/src/textual/cli/previews/colors.py @@ -2,7 +2,7 @@ from textual.app import App, ComposeResult from textual.containers import Horizontal, Vertical from textual.design import ColorSystem from textual.widget import Widget -from textual.widgets import Button, Footer, Static, Label +from textual.widgets import Button, Footer, Label, Static class ColorButtons(Vertical): diff --git a/src/textual/cli/previews/easing.py b/src/textual/cli/previews/easing.py index 53b7c4475..38a0a9710 100644 --- a/src/textual/cli/previews/easing.py +++ b/src/textual/cli/previews/easing.py @@ -1,6 +1,7 @@ from __future__ import annotations from rich.console import RenderableType + from textual._easing import EASING from textual.app import App, ComposeResult from textual.cli.previews.borders import TEXT @@ -8,7 +9,7 @@ from textual.containers import Container, Horizontal, Vertical from textual.reactive import reactive, var from textual.scrollbar import ScrollBarRender from textual.widget import Widget -from textual.widgets import Button, Footer, Label, Input +from textual.widgets import Button, Footer, Input, Label VIRTUAL_SIZE = 100 WINDOW_SIZE = 10 diff --git a/src/textual/cli/previews/keys.py b/src/textual/cli/previews/keys.py index 933fac807..4be99e022 100644 --- a/src/textual/cli/previews/keys.py +++ b/src/textual/cli/previews/keys.py @@ -1,16 +1,14 @@ from __future__ import annotations from rich.panel import Panel - from rich.text import Text -from textual.app import App, ComposeResult -from textual.reactive import var, Reactive from textual import events +from textual.app import App, ComposeResult from textual.containers import Horizontal +from textual.reactive import Reactive, var from textual.widgets import Button, Header, TextLog - INSTRUCTIONS = """\ [u]Press some keys![/] diff --git a/src/textual/cli/tools/diagnose.py b/src/textual/cli/tools/diagnose.py index d1c622ad1..d6ccf0cd6 100644 --- a/src/textual/cli/tools/diagnose.py +++ b/src/textual/cli/tools/diagnose.py @@ -1,11 +1,13 @@ """Textual CLI command code to print diagnostic information.""" from __future__ import annotations + import os -import sys import platform -from typing import Any +import sys from functools import singledispatch +from typing import Any + from importlib_metadata import version from rich.console import Console, ConsoleDimensions diff --git a/src/textual/css/_help_text.py b/src/textual/css/_help_text.py index e0f3b60ed..e873bd8a0 100644 --- a/src/textual/css/_help_text.py +++ b/src/textual/css/_help_text.py @@ -5,20 +5,20 @@ from typing import Iterable, Sequence from typing_extensions import Literal +from textual.css._error_tools import friendly_list +from textual.css.scalar import SYMBOL_UNIT + from ..color import ColorParseError -from ._help_renderables import Example, Bullet, HelpText +from ._help_renderables import Bullet, Example, HelpText from .constants import ( - VALID_BORDER, - VALID_LAYOUT, VALID_ALIGN_HORIZONTAL, VALID_ALIGN_VERTICAL, + VALID_BORDER, + VALID_LAYOUT, VALID_STYLE_FLAGS, VALID_TEXT_ALIGN, ) -from textual.css._error_tools import friendly_list -from textual.css.scalar import SYMBOL_UNIT - StylingContext = Literal["inline", "css"] """The type of styling the user was using when the error was encountered. Used to give help text specific to the context i.e. we give CSS help if the diff --git a/src/textual/css/_style_properties.py b/src/textual/css/_style_properties.py index f3e5908a6..f69d10f16 100644 --- a/src/textual/css/_style_properties.py +++ b/src/textual/css/_style_properties.py @@ -10,14 +10,7 @@ when setting and getting. from __future__ import annotations from operator import attrgetter -from typing import ( - TYPE_CHECKING, - Generic, - Iterable, - NamedTuple, - TypeVar, - cast, -) +from typing import TYPE_CHECKING, Generic, Iterable, NamedTuple, TypeVar, cast import rich.errors import rich.repr @@ -611,11 +604,8 @@ class LayoutProperty: or a ``Layout`` object. """ - from ..layouts.factory import ( - Layout, # Prevents circular import - MissingLayout, - get_layout, - ) + from ..layouts.factory import Layout # Prevents circular import + from ..layouts.factory import MissingLayout, get_layout _rich_traceback_omit = True if layout is None: diff --git a/src/textual/css/constants.py b/src/textual/css/constants.py index c3c073940..e6a7ab019 100644 --- a/src/textual/css/constants.py +++ b/src/textual/css/constants.py @@ -1,4 +1,5 @@ from __future__ import annotations + import typing from ..geometry import Spacing diff --git a/src/textual/css/errors.py b/src/textual/css/errors.py index 6908d964e..2daa7e3b3 100644 --- a/src/textual/css/errors.py +++ b/src/textual/css/errors.py @@ -1,6 +1,6 @@ from __future__ import annotations -from rich.console import ConsoleOptions, Console, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult from rich.traceback import Traceback from ._help_renderables import HelpText diff --git a/src/textual/css/match.py b/src/textual/css/match.py index cc58c90b2..2f964945d 100644 --- a/src/textual/css/match.py +++ b/src/textual/css/match.py @@ -1,8 +1,8 @@ from __future__ import annotations -from typing import Iterable, TYPE_CHECKING -from .model import CombinatorType, Selector, SelectorSet +from typing import TYPE_CHECKING, Iterable +from .model import CombinatorType, Selector, SelectorSet if TYPE_CHECKING: from ..dom import DOMNode diff --git a/src/textual/css/model.py b/src/textual/css/model.py index f8087ad27..cc68ee0af 100644 --- a/src/textual/css/model.py +++ b/src/textual/css/model.py @@ -1,11 +1,10 @@ from __future__ import annotations - -import rich.repr - from dataclasses import dataclass, field from enum import Enum -from typing import Iterable, TYPE_CHECKING +from typing import TYPE_CHECKING, Iterable + +import rich.repr from .styles import Styles from .tokenize import Token diff --git a/src/textual/css/parse.py b/src/textual/css/parse.py index 265458fa9..fe23c084d 100644 --- a/src/textual/css/parse.py +++ b/src/textual/css/parse.py @@ -2,23 +2,23 @@ from __future__ import annotations from functools import lru_cache from pathlib import PurePath -from typing import Iterator, Iterable, NoReturn +from typing import Iterable, Iterator, NoReturn +from ..suggestions import get_suggestion +from ._styles_builder import DeclarationError, StylesBuilder from .errors import UnresolvedVariableError -from .types import Specificity3 -from ._styles_builder import StylesBuilder, DeclarationError from .model import ( + CombinatorType, Declaration, RuleSet, Selector, - CombinatorType, SelectorSet, SelectorType, ) from .styles import Styles -from ..suggestions import get_suggestion -from .tokenize import tokenize, tokenize_declarations, Token, tokenize_values +from .tokenize import Token, tokenize, tokenize_declarations, tokenize_values from .tokenizer import EOFError, ReferencedBy +from .types import Specificity3 SELECTOR_MAP: dict[str, tuple[SelectorType, Specificity3]] = { "selector": (SelectorType.TYPE, (0, 0, 1)), diff --git a/src/textual/css/scalar.py b/src/textual/css/scalar.py index 68bb5158f..d0bc4e3bc 100644 --- a/src/textual/css/scalar.py +++ b/src/textual/css/scalar.py @@ -1,9 +1,9 @@ from __future__ import annotations +import re from enum import Enum, unique from fractions import Fraction from functools import lru_cache -import re from typing import Iterable, NamedTuple import rich.repr diff --git a/src/textual/css/scalar_animation.py b/src/textual/css/scalar_animation.py index 21afd51f8..935be134a 100644 --- a/src/textual/css/scalar_animation.py +++ b/src/textual/css/scalar_animation.py @@ -2,15 +2,12 @@ from __future__ import annotations from typing import TYPE_CHECKING -from .scalar import ScalarOffset, Scalar -from .._animator import Animation -from .._animator import EasingFunction +from .._animator import Animation, EasingFunction from .._types import CallbackType - +from .scalar import Scalar, ScalarOffset if TYPE_CHECKING: from ..dom import DOMNode - from .styles import StylesBase diff --git a/src/textual/css/styles.py b/src/textual/css/styles.py index 423f1889f..ba2efa93c 100644 --- a/src/textual/css/styles.py +++ b/src/textual/css/styles.py @@ -4,8 +4,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field from functools import lru_cache from operator import attrgetter -from typing import Iterable, cast -from typing import TYPE_CHECKING, Any, NamedTuple +from typing import TYPE_CHECKING, Any, Iterable, NamedTuple, cast import rich.repr from rich.style import Style diff --git a/src/textual/css/tokenize.py b/src/textual/css/tokenize.py index 1afd78379..2a8677f68 100644 --- a/src/textual/css/tokenize.py +++ b/src/textual/css/tokenize.py @@ -4,7 +4,7 @@ import re from pathlib import PurePath from typing import Iterable -from textual.css.tokenizer import Expect, Tokenizer, Token +from textual.css.tokenizer import Expect, Token, Tokenizer PERCENT = r"-?\d+\.?\d*%" DECIMAL = r"-?\d+\.?\d*" diff --git a/src/textual/css/tokenizer.py b/src/textual/css/tokenizer.py index f518d623a..3128b0a76 100644 --- a/src/textual/css/tokenizer.py +++ b/src/textual/css/tokenizer.py @@ -4,11 +4,11 @@ import re from pathlib import PurePath from typing import NamedTuple +import rich.repr from rich.console import Group, RenderableType from rich.highlighter import ReprHighlighter from rich.padding import Padding from rich.panel import Panel -import rich.repr from rich.syntax import Syntax from rich.text import Text diff --git a/src/textual/css/types.py b/src/textual/css/types.py index 60a1d2f5f..58dfd42bb 100644 --- a/src/textual/css/types.py +++ b/src/textual/css/types.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import Tuple + from typing_extensions import Literal from ..color import Color diff --git a/src/textual/demo.py b/src/textual/demo.py index 58eb6aea0..6d79e6292 100644 --- a/src/textual/demo.py +++ b/src/textual/demo.py @@ -1,8 +1,8 @@ from __future__ import annotations -from importlib_metadata import version from pathlib import Path +from importlib_metadata import version from rich import box from rich.console import RenderableType from rich.json import JSON diff --git a/src/textual/design.py b/src/textual/design.py index 447f86c62..4830ac20c 100644 --- a/src/textual/design.py +++ b/src/textual/design.py @@ -7,8 +7,7 @@ from rich.padding import Padding from rich.table import Table from rich.text import Text -from .color import Color, WHITE - +from .color import WHITE, Color NUMBER_OF_SHADES = 3 diff --git a/src/textual/devtools/client.py b/src/textual/devtools/client.py index b9933feae..0ba570552 100644 --- a/src/textual/devtools/client.py +++ b/src/textual/devtools/client.py @@ -9,21 +9,14 @@ from io import StringIO from time import time from typing import Any, NamedTuple, Type +import aiohttp +import msgpack +from aiohttp import ClientConnectorError, ClientResponseError, ClientWebSocketResponse from rich.console import Console from rich.segment import Segment from .._log import LogGroup, LogVerbosity - -import aiohttp -import msgpack -from aiohttp import ( - ClientConnectorError, - ClientResponseError, - ClientWebSocketResponse, -) - - DEVTOOLS_PORT = 8081 WEBSOCKET_CONNECT_TIMEOUT = 3 LOG_QUEUE_MAXSIZE = 512 diff --git a/src/textual/devtools/redirect_output.py b/src/textual/devtools/redirect_output.py index 696b0b8ba..b79f93580 100644 --- a/src/textual/devtools/redirect_output.py +++ b/src/textual/devtools/redirect_output.py @@ -1,10 +1,10 @@ from __future__ import annotations import inspect - from typing import TYPE_CHECKING, cast -from .client import DevtoolsLog + from .._log import LogGroup, LogVerbosity +from .client import DevtoolsLog if TYPE_CHECKING: from .client import DevtoolsClient diff --git a/src/textual/devtools/server.py b/src/textual/devtools/server.py index e9926aee5..4228ca6f5 100644 --- a/src/textual/devtools/server.py +++ b/src/textual/devtools/server.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio + from aiohttp.web import run_app from aiohttp.web_app import Application from aiohttp.web_request import Request diff --git a/src/textual/devtools/service.py b/src/textual/devtools/service.py index 1d35c4e90..5e85d2f89 100644 --- a/src/textual/devtools/service.py +++ b/src/textual/devtools/service.py @@ -7,19 +7,19 @@ import pickle from json import JSONDecodeError from typing import Any, cast +import msgpack from aiohttp import WSMessage, WSMsgType from aiohttp.abc import Request from aiohttp.web_ws import WebSocketResponse from rich.console import Console from rich.markup import escape -import msgpack from textual._log import LogGroup from textual._time import time from textual.devtools.renderables import ( + DevConsoleHeader, DevConsoleLog, DevConsoleNotice, - DevConsoleHeader, ) QUEUEABLE_TYPES = {"client_log", "client_spillover"} diff --git a/src/textual/drivers/headless_driver.py b/src/textual/drivers/headless_driver.py index 87a0940e7..75172b9b6 100644 --- a/src/textual/drivers/headless_driver.py +++ b/src/textual/drivers/headless_driver.py @@ -1,9 +1,10 @@ from __future__ import annotations import asyncio + +from .. import events from ..driver import Driver from ..geometry import Size -from .. import events class HeadlessDriver(Driver): diff --git a/src/textual/drivers/linux_driver.py b/src/textual/drivers/linux_driver.py index 09260be6f..d2c00f61b 100644 --- a/src/textual/drivers/linux_driver.py +++ b/src/textual/drivers/linux_driver.py @@ -2,27 +2,26 @@ from __future__ import annotations import asyncio import os -from codecs import getincrementaldecoder import selectors import signal import sys import termios import tty -from typing import Any, TYPE_CHECKING +from codecs import getincrementaldecoder from threading import Event, Thread +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from rich.console import Console import rich.repr -from .. import log -from ..driver import Driver -from ..geometry import Size +from .. import events, log +from .._profile import timer from .._types import MessageTarget from .._xterm_parser import XTermParser -from .._profile import timer -from .. import events +from ..driver import Driver +from ..geometry import Size @rich.repr.auto diff --git a/src/textual/geometry.py b/src/textual/geometry.py index f2f8ef3d8..e6efbbe5d 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -9,6 +9,7 @@ from __future__ import annotations from functools import lru_cache from operator import attrgetter, itemgetter from typing import ( + TYPE_CHECKING, Any, Collection, NamedTuple, @@ -16,7 +17,6 @@ from typing import ( TypeVar, Union, cast, - TYPE_CHECKING, ) if TYPE_CHECKING: diff --git a/src/textual/layouts/factory.py b/src/textual/layouts/factory.py index 8fa724b07..7ea59dcc5 100644 --- a/src/textual/layouts/factory.py +++ b/src/textual/layouts/factory.py @@ -1,8 +1,8 @@ from __future__ import annotations from .._layout import Layout -from .horizontal import HorizontalLayout from .grid import GridLayout +from .horizontal import HorizontalLayout from .vertical import VerticalLayout LAYOUT_MAP: dict[str, type[Layout]] = { diff --git a/src/textual/layouts/horizontal.py b/src/textual/layouts/horizontal.py index 2d6736b08..7ed1820ef 100644 --- a/src/textual/layouts/horizontal.py +++ b/src/textual/layouts/horizontal.py @@ -2,9 +2,9 @@ from __future__ import annotations from fractions import Fraction -from .._resolve import resolve_box_models -from ..geometry import Size, Region from .._layout import ArrangeResult, Layout, WidgetPlacement +from .._resolve import resolve_box_models +from ..geometry import Region, Size from ..widget import Widget diff --git a/src/textual/layouts/vertical.py b/src/textual/layouts/vertical.py index f26e531c0..d0235092c 100644 --- a/src/textual/layouts/vertical.py +++ b/src/textual/layouts/vertical.py @@ -3,9 +3,9 @@ from __future__ import annotations from fractions import Fraction from typing import TYPE_CHECKING +from .._layout import ArrangeResult, Layout, WidgetPlacement from .._resolve import resolve_box_models from ..geometry import Region, Size -from .._layout import ArrangeResult, Layout, WidgetPlacement if TYPE_CHECKING: from ..widget import Widget diff --git a/src/textual/message.py b/src/textual/message.py index da0c093a7..5f46cc97a 100644 --- a/src/textual/message.py +++ b/src/textual/message.py @@ -1,16 +1,16 @@ from __future__ import annotations -from typing import ClassVar, TYPE_CHECKING +from typing import TYPE_CHECKING, ClassVar import rich.repr from . import _clock -from .case import camel_to_snake from ._types import MessageTarget as MessageTarget +from .case import camel_to_snake if TYPE_CHECKING: - from .widget import Widget from .message_pump import MessagePump + from .widget import Widget @rich.repr.auto diff --git a/src/textual/messages.py b/src/textual/messages.py index f23a1a8a8..fcfe2ad2c 100644 --- a/src/textual/messages.py +++ b/src/textual/messages.py @@ -1,13 +1,13 @@ from __future__ import annotations + from typing import TYPE_CHECKING import rich.repr -from .geometry import Region from ._types import CallbackType +from .geometry import Region from .message import Message - if TYPE_CHECKING: from .message_pump import MessagePump from .widget import Widget diff --git a/src/textual/pilot.py b/src/textual/pilot.py index b68f9409c..5f4ca11b1 100644 --- a/src/textual/pilot.py +++ b/src/textual/pilot.py @@ -1,12 +1,12 @@ from __future__ import annotations -import rich.repr - import asyncio from typing import Generic -from .app import App, ReturnType +import rich.repr + from ._wait import wait_for_idle +from .app import App, ReturnType @rich.repr.auto(angular=True) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 58f9a0837..4c7bd1d98 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -17,7 +17,7 @@ import rich.repr from . import events from ._callback import count_parameters -from ._types import MessageTarget, CallbackType +from ._types import CallbackType, MessageTarget if TYPE_CHECKING: from .dom import DOMNode diff --git a/src/textual/renderables/blank.py b/src/textual/renderables/blank.py index 05552ac2f..80daaf5be 100644 --- a/src/textual/renderables/blank.py +++ b/src/textual/renderables/blank.py @@ -1,6 +1,6 @@ from __future__ import annotations -from rich.console import ConsoleOptions, Console, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult from rich.segment import Segment from rich.style import Style diff --git a/src/textual/renderables/gradient.py b/src/textual/renderables/gradient.py index a0c5379fb..2774f6b60 100644 --- a/src/textual/renderables/gradient.py +++ b/src/textual/renderables/gradient.py @@ -1,7 +1,6 @@ from __future__ import annotations -from rich.console import ConsoleOptions, Console, RenderResult - +from rich.console import Console, ConsoleOptions, RenderResult from rich.segment import Segment from rich.style import Style diff --git a/src/textual/renderables/sparkline.py b/src/textual/renderables/sparkline.py index f2e01f409..1289029b0 100644 --- a/src/textual/renderables/sparkline.py +++ b/src/textual/renderables/sparkline.py @@ -1,10 +1,10 @@ from __future__ import annotations import statistics -from typing import Generic, Sequence, Iterable, Callable, TypeVar +from typing import Callable, Generic, Iterable, Sequence, TypeVar from rich.color import Color -from rich.console import ConsoleOptions, Console, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult from rich.segment import Segment from rich.style import Style diff --git a/src/textual/renderables/text_opacity.py b/src/textual/renderables/text_opacity.py index b0c72b2a0..1ec567020 100644 --- a/src/textual/renderables/text_opacity.py +++ b/src/textual/renderables/text_opacity.py @@ -3,7 +3,7 @@ from typing import Iterable, Tuple, cast from rich.cells import cell_len from rich.color import Color -from rich.console import ConsoleOptions, Console, RenderResult, RenderableType +from rich.console import Console, ConsoleOptions, RenderableType, RenderResult from rich.segment import Segment from rich.style import Style diff --git a/src/textual/renderables/tint.py b/src/textual/renderables/tint.py index a81471fa9..d06dfed4f 100644 --- a/src/textual/renderables/tint.py +++ b/src/textual/renderables/tint.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import Iterable -from rich.console import ConsoleOptions, Console, RenderResult, RenderableType +from rich.console import Console, ConsoleOptions, RenderableType, RenderResult from rich.segment import Segment from rich.style import Style diff --git a/src/textual/renderables/underline_bar.py b/src/textual/renderables/underline_bar.py index 599c7b4c5..4a7f2ea35 100644 --- a/src/textual/renderables/underline_bar.py +++ b/src/textual/renderables/underline_bar.py @@ -1,6 +1,6 @@ from __future__ import annotations -from rich.console import ConsoleOptions, Console, RenderResult +from rich.console import Console, ConsoleOptions, RenderResult from rich.style import StyleType from rich.text import Text @@ -99,6 +99,7 @@ class UnderlineBar: if __name__ == "__main__": import random from time import sleep + from rich.color import ANSI_COLOR_NAMES console = Console() diff --git a/src/textual/screen.py b/src/textual/screen.py index 3bed42f18..86ea1c4b9 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Iterable, Iterator, TYPE_CHECKING +from typing import TYPE_CHECKING, Iterable, Iterator import rich.repr from rich.console import RenderableType @@ -9,14 +9,14 @@ from rich.style import Style from . import errors, events, messages from ._callback import invoke from ._compositor import Compositor, MapGeometry +from ._types import CallbackType from .css.match import match from .css.parse import parse_selectors from .dom import DOMNode -from .timer import Timer -from ._types import CallbackType from .geometry import Offset, Region, Size from .reactive import Reactive from .renderables.blank import Blank +from .timer import Timer from .widget import Widget if TYPE_CHECKING: diff --git a/src/textual/walk.py b/src/textual/walk.py index 654fccb67..0dc672471 100644 --- a/src/textual/walk.py +++ b/src/textual/walk.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections import deque -from typing import Iterable, Iterator, TypeVar, overload, TYPE_CHECKING +from typing import TYPE_CHECKING, Iterable, Iterator, TypeVar, overload if TYPE_CHECKING: from textual.dom import DOMNode diff --git a/src/textual/widget.py b/src/textual/widget.py index 5bd204c9e..4cb9fbbc5 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -35,9 +35,9 @@ from rich.text import Text from rich.traceback import Traceback from . import errors, events, messages -from ._asyncio import create_task from ._animator import DEFAULT_EASING, Animatable, BoundAnimator, EasingFunction from ._arrange import DockArrangeResult, arrange +from ._asyncio import create_task from ._context import active_app from ._easing import DEFAULT_SCROLL_EASING from ._layout import Layout diff --git a/src/textual/widgets/__init__.py b/src/textual/widgets/__init__.py index 98dd81f18..13b046c03 100644 --- a/src/textual/widgets/__init__.py +++ b/src/textual/widgets/__init__.py @@ -1,6 +1,7 @@ from __future__ import annotations -from importlib import import_module + import typing +from importlib import import_module from ..case import camel_to_snake @@ -8,6 +9,7 @@ from ..case import camel_to_snake # but also to the `__init__.pyi` file in this same folder - otherwise text editors and type checkers won't # be able to "see" them. if typing.TYPE_CHECKING: + from ..widget import Widget from ._button import Button from ._checkbox import Checkbox from ._data_table import DataTable @@ -24,7 +26,6 @@ if typing.TYPE_CHECKING: from ._text_log import TextLog from ._tree import Tree from ._welcome import Welcome - from ..widget import Widget __all__ = [ diff --git a/src/textual/widgets/__init__.pyi b/src/textual/widgets/__init__.pyi index 8fc4a8458..323a93d10 100644 --- a/src/textual/widgets/__init__.pyi +++ b/src/textual/widgets/__init__.pyi @@ -1,17 +1,17 @@ # This stub file must re-export every classes exposed in the __init__.py's `__all__` list: from ._button import Button as Button -from ._data_table import DataTable as DataTable from ._checkbox import Checkbox as Checkbox +from ._data_table import DataTable as DataTable from ._directory_tree import DirectoryTree as DirectoryTree from ._footer import Footer as Footer from ._header import Header as Header +from ._input import Input as Input from ._label import Label as Label -from ._list_view import ListView as ListView from ._list_item import ListItem as ListItem +from ._list_view import ListView as ListView from ._placeholder import Placeholder as Placeholder from ._pretty import Pretty as Pretty from ._static import Static as Static -from ._input import Input as Input from ._text_log import TextLog as TextLog from ._tree import Tree as Tree from ._welcome import Welcome as Welcome diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py index eaa0b874b..fbeb60645 100644 --- a/src/textual/widgets/_button.py +++ b/src/textual/widgets/_button.py @@ -2,11 +2,11 @@ from __future__ import annotations from functools import partial from typing import cast -from typing_extensions import Literal import rich.repr from rich.console import RenderableType from rich.text import Text, TextType +from typing_extensions import Literal from .. import events from ..css._error_tools import friendly_list @@ -14,7 +14,6 @@ from ..message import Message from ..reactive import reactive from ..widgets import Static - ButtonVariant = Literal["default", "primary", "success", "warning", "error"] _VALID_BUTTON_VARIANTS = {"default", "primary", "success", "warning", "error"} diff --git a/src/textual/widgets/_checkbox.py b/src/textual/widgets/_checkbox.py index 9b5b1b454..c6f3ad9ec 100644 --- a/src/textual/widgets/_checkbox.py +++ b/src/textual/widgets/_checkbox.py @@ -8,8 +8,8 @@ from ..binding import Binding, BindingType from ..geometry import Size from ..message import Message from ..reactive import reactive -from ..widget import Widget from ..scrollbar import ScrollBarRender +from ..widget import Widget class Checkbox(Widget, can_focus=True): diff --git a/src/textual/widgets/_data_table.py b/src/textual/widgets/_data_table.py index 0a641d870..4cc540c94 100644 --- a/src/textual/widgets/_data_table.py +++ b/src/textual/widgets/_data_table.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import dataclass, field from itertools import chain, zip_longest from typing import Generic, Iterable, cast -from typing_extensions import ClassVar, TypeVar, Literal import rich.repr from rich.console import RenderableType @@ -12,6 +11,7 @@ from rich.protocol import is_renderable from rich.segment import Segment from rich.style import Style from rich.text import Text, TextType +from typing_extensions import ClassVar, Literal, TypeVar from .. import events, messages from .._cache import LRUCache diff --git a/src/textual/widgets/_directory_tree.py b/src/textual/widgets/_directory_tree.py index 5b4845c05..9b3d33fc5 100644 --- a/src/textual/widgets/_directory_tree.py +++ b/src/textual/widgets/_directory_tree.py @@ -7,9 +7,9 @@ from typing import ClassVar from rich.style import Style from rich.text import Text, TextType -from ..message import Message -from ._tree import Tree, TreeNode, TOGGLE_STYLE from .._types import MessageTarget +from ..message import Message +from ._tree import TOGGLE_STYLE, Tree, TreeNode @dataclass diff --git a/src/textual/widgets/_header.py b/src/textual/widgets/_header.py index d09c4dad8..12e07e4c1 100644 --- a/src/textual/widgets/_header.py +++ b/src/textual/widgets/_header.py @@ -4,8 +4,8 @@ from datetime import datetime from rich.text import Text -from ..widget import Widget from ..reactive import Reactive +from ..widget import Widget class HeaderIcon(Widget): diff --git a/src/textual/widgets/_input.py b/src/textual/widgets/_input.py index d449efee0..8528e225a 100644 --- a/src/textual/widgets/_input.py +++ b/src/textual/widgets/_input.py @@ -1,7 +1,7 @@ from __future__ import annotations -from typing import ClassVar import re +from typing import ClassVar from rich.cells import cell_len, get_character_cell_size from rich.console import Console, ConsoleOptions, RenderableType, RenderResult diff --git a/src/textual/widgets/_list_view.py b/src/textual/widgets/_list_view.py index 6e391d862..3d9db5892 100644 --- a/src/textual/widgets/_list_view.py +++ b/src/textual/widgets/_list_view.py @@ -1,4 +1,5 @@ from __future__ import annotations + from typing import ClassVar from textual.await_remove import AwaitRemove diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index d111d906b..d4bf01333 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -7,8 +7,7 @@ from typing_extensions import Literal from .. import events from ..css._error_tools import friendly_list from ..reactive import Reactive, reactive -from ..widget import Widget, RenderResult - +from ..widget import RenderResult, Widget PlaceholderVariant = Literal["default", "size", "text"] _VALID_PLACEHOLDER_VARIANTS_ORDERED: list[PlaceholderVariant] = [ diff --git a/src/textual/widgets/_pretty.py b/src/textual/widgets/_pretty.py index ff43350f5..0597886c4 100644 --- a/src/textual/widgets/_pretty.py +++ b/src/textual/widgets/_pretty.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import Any + from rich.pretty import Pretty as PrettyRenderable from ..widget import Widget diff --git a/src/textual/widgets/_welcome.py b/src/textual/widgets/_welcome.py index 0ad5032dc..631437b5a 100644 --- a/src/textual/widgets/_welcome.py +++ b/src/textual/widgets/_welcome.py @@ -1,10 +1,10 @@ -from ..app import ComposeResult -from ._static import Static -from ._button import Button -from ..containers import Container - from rich.markdown import Markdown +from ..app import ComposeResult +from ..containers import Container +from ._button import Button +from ._static import Static + WELCOME_MD = """\ # Welcome! diff --git a/src/textual/widgets/tabs.py b/src/textual/widgets/tabs.py index 8dcfac98e..193cb5d45 100644 --- a/src/textual/widgets/tabs.py +++ b/src/textual/widgets/tabs.py @@ -7,11 +7,11 @@ from typing import Iterable from rich.cells import cell_len from rich.console import Console, ConsoleOptions, RenderableType, RenderResult from rich.segment import Segment -from rich.style import StyleType, Style +from rich.style import Style, StyleType from rich.text import Text from textual import events -from textual._layout_resolve import layout_resolve, Edge +from textual._layout_resolve import Edge, layout_resolve from textual.keys import Keys from textual.reactive import Reactive from textual.renderables.text_opacity import TextOpacity diff --git a/tests/css/test_help_text.py b/tests/css/test_help_text.py index 928ca2d62..e2945b057 100644 --- a/tests/css/test_help_text.py +++ b/tests/css/test_help_text.py @@ -2,17 +2,17 @@ import pytest from tests.utilities.render import render from textual.css._help_text import ( - spacing_wrong_number_of_values_help_text, - spacing_invalid_value_help_text, - scalar_help_text, - string_enum_help_text, - color_property_help_text, - border_property_help_text, - layout_property_help_text, - fractional_property_help_text, - offset_property_help_text, align_help_text, + border_property_help_text, + color_property_help_text, + fractional_property_help_text, + layout_property_help_text, + offset_property_help_text, offset_single_axis_help_text, + scalar_help_text, + spacing_invalid_value_help_text, + spacing_wrong_number_of_values_help_text, + string_enum_help_text, style_flags_property_help_text, ) diff --git a/tests/css/test_parse.py b/tests/css/test_parse.py index fed5db430..727d45af4 100644 --- a/tests/css/test_parse.py +++ b/tests/css/test_parse.py @@ -8,7 +8,7 @@ from textual.css.parse import substitute_references from textual.css.scalar import Scalar, Unit from textual.css.stylesheet import Stylesheet, StylesheetParseError from textual.css.tokenize import tokenize -from textual.css.tokenizer import Token, ReferencedBy +from textual.css.tokenizer import ReferencedBy, Token from textual.css.transition import Transition from textual.geometry import Spacing from textual.layouts.vertical import VerticalLayout diff --git a/tests/css/test_styles.py b/tests/css/test_styles.py index 8a257c0ad..e21572478 100644 --- a/tests/css/test_styles.py +++ b/tests/css/test_styles.py @@ -1,13 +1,12 @@ from decimal import Decimal import pytest - from rich.style import Style from textual.color import Color from textual.css.errors import StyleValueError from textual.css.scalar import Scalar, Unit -from textual.css.styles import Styles, RenderStyles +from textual.css.styles import RenderStyles, Styles from textual.dom import DOMNode from textual.widget import Widget diff --git a/tests/devtools/__init__.py b/tests/devtools/__init__.py index c668d5fd7..9e35d1a25 100644 --- a/tests/devtools/__init__.py +++ b/tests/devtools/__init__.py @@ -11,6 +11,4 @@ _WINDOWS = sys.platform == "win32" # and the error messages suggest the event loop is being shutdown before async fixture # teardown code has finished running. These are very rare, but are much more of an issue on # CI since they can delay builds that have passed locally. -pytestmark = pytest.mark.skipif( - _MACOS_CI or _WINDOWS, reason="Issue #411" -) +pytestmark = pytest.mark.skipif(_MACOS_CI or _WINDOWS, reason="Issue #411") diff --git a/tests/devtools/test_devtools_client.py b/tests/devtools/test_devtools_client.py index 1d7e8e8f7..88088bff0 100644 --- a/tests/devtools/test_devtools_client.py +++ b/tests/devtools/test_devtools_client.py @@ -30,7 +30,6 @@ async def test_devtools_client_is_connected(devtools): @time_machine.travel(datetime.utcfromtimestamp(TIMESTAMP)) async def test_devtools_log_places_encodes_and_queues_message(devtools): - await devtools._stop_log_queue_processing() devtools.log(DevtoolsLog("Hello, world!", CALLER)) queued_log = await devtools.log_queue.get() diff --git a/tests/input/test_input_key_modification_actions.py b/tests/input/test_input_key_modification_actions.py index 68f7e50c8..a7fc76800 100644 --- a/tests/input/test_input_key_modification_actions.py +++ b/tests/input/test_input_key_modification_actions.py @@ -5,7 +5,6 @@ from __future__ import annotations from textual.app import App, ComposeResult from textual.widgets import Input - TEST_INPUTS: dict[str | None, str] = { "empty": "", "multi-no-punctuation": "Curse your sudden but inevitable betrayal", diff --git a/tests/input/test_input_value_visibility.py b/tests/input/test_input_value_visibility.py index 9a6a25e89..e2de63502 100644 --- a/tests/input/test_input_value_visibility.py +++ b/tests/input/test_input_value_visibility.py @@ -1,4 +1,5 @@ from rich.console import Console + from textual.app import App from textual.widgets import Input diff --git a/tests/layouts/test_content_dimensions.py b/tests/layouts/test_content_dimensions.py index 1db259b4a..0811d029b 100644 --- a/tests/layouts/test_content_dimensions.py +++ b/tests/layouts/test_content_dimensions.py @@ -1,12 +1,11 @@ import pytest +from textual.geometry import Size from textual.layouts.grid import GridLayout from textual.layouts.horizontal import HorizontalLayout from textual.layouts.vertical import VerticalLayout -from textual.geometry import Size from textual.widget import Widget - LAYOUTS = [GridLayout, HorizontalLayout, VerticalLayout] diff --git a/tests/layouts/test_factory.py b/tests/layouts/test_factory.py index bece5ab6a..ab3a6667d 100644 --- a/tests/layouts/test_factory.py +++ b/tests/layouts/test_factory.py @@ -1,6 +1,6 @@ import pytest -from textual.layouts.factory import get_layout, MissingLayout +from textual.layouts.factory import MissingLayout, get_layout from textual.layouts.vertical import VerticalLayout diff --git a/tests/listview/test_inherit_listview.py b/tests/listview/test_inherit_listview.py index 2f147a28a..520b4b21c 100644 --- a/tests/listview/test_inherit_listview.py +++ b/tests/listview/test_inherit_listview.py @@ -1,5 +1,5 @@ from textual.app import App, ComposeResult -from textual.widgets import ListView, ListItem, Label +from textual.widgets import Label, ListItem, ListView class MyListView(ListView): diff --git a/tests/renderables/test_sparkline.py b/tests/renderables/test_sparkline.py index 74f1f2f6b..5285ccc6c 100644 --- a/tests/renderables/test_sparkline.py +++ b/tests/renderables/test_sparkline.py @@ -20,22 +20,35 @@ def test_sparkline_two_values_min_max(): def test_sparkline_expand_data_to_width(): - assert render(Sparkline([2, 4], - width=4)) == f"{GREEN}▁{STOP}{GREEN}▁{STOP}{RED}█{STOP}{RED}█{STOP}" + assert ( + render(Sparkline([2, 4], width=4)) + == f"{GREEN}▁{STOP}{GREEN}▁{STOP}{RED}█{STOP}{RED}█{STOP}" + ) def test_sparkline_expand_data_to_width_non_divisible(): - assert render(Sparkline([2, 4], width=3)) == f"{GREEN}▁{STOP}{GREEN}▁{STOP}{RED}█{STOP}" + assert ( + render(Sparkline([2, 4], width=3)) + == f"{GREEN}▁{STOP}{GREEN}▁{STOP}{RED}█{STOP}" + ) def test_sparkline_shrink_data_to_width(): - assert render(Sparkline([2, 2, 4, 4, 6, 6], width=3)) == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + assert ( + render(Sparkline([2, 2, 4, 4, 6, 6], width=3)) + == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + ) def test_sparkline_shrink_data_to_width_non_divisible(): - assert render( - Sparkline([1, 2, 3, 4, 5], width=3, summary_function=min)) == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + assert ( + render(Sparkline([1, 2, 3, 4, 5], width=3, summary_function=min)) + == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + ) def test_sparkline_color_blend(): - assert render(Sparkline([1, 2, 3], width=3)) == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + assert ( + render(Sparkline([1, 2, 3], width=3)) + == f"{GREEN}▁{STOP}{BLENDED}▄{STOP}{RED}█{STOP}" + ) diff --git a/tests/renderables/test_text_opacity.py b/tests/renderables/test_text_opacity.py index b543667ba..877f5b459 100644 --- a/tests/renderables/test_text_opacity.py +++ b/tests/renderables/test_text_opacity.py @@ -14,7 +14,7 @@ def text(): def test_simple_text_opacity(text): blended_red_on_green = "\x1b[38;2;127;127;0;48;2;0;255;0m" - assert render(TextOpacity(text, opacity=.5)) == ( + assert render(TextOpacity(text, opacity=0.5)) == ( f"{blended_red_on_green}Hello, world!{STOP}" ) @@ -31,19 +31,21 @@ def test_text_opacity_value_of_one_noop(text): def test_ansi_colors_noop(): ansi_colored_text = Text("Hello, world!", style="red on green", end="") - assert render(TextOpacity(ansi_colored_text, opacity=.5)) == render(ansi_colored_text) + assert render(TextOpacity(ansi_colored_text, opacity=0.5)) == render( + ansi_colored_text + ) def test_text_opacity_no_style_noop(): text_no_style = Text("Hello, world!", end="") - assert render(TextOpacity(text_no_style, opacity=.2)) == render(text_no_style) + assert render(TextOpacity(text_no_style, opacity=0.2)) == render(text_no_style) def test_text_opacity_only_fg_noop(): text_only_fg = Text("Hello, world!", style="#ff0000", end="") - assert render(TextOpacity(text_only_fg, opacity=.5)) == render(text_only_fg) + assert render(TextOpacity(text_only_fg, opacity=0.5)) == render(text_only_fg) def test_text_opacity_only_bg_noop(): text_only_bg = Text("Hello, world!", style="on #ff0000", end="") - assert render(TextOpacity(text_only_bg, opacity=.5)) == render(text_only_bg) + assert render(TextOpacity(text_only_bg, opacity=0.5)) == render(text_only_bg) diff --git a/tests/renderables/test_underline_bar.py b/tests/renderables/test_underline_bar.py index 549b331e3..b195d6f64 100644 --- a/tests/renderables/test_underline_bar.py +++ b/tests/renderables/test_underline_bar.py @@ -1,7 +1,6 @@ from unittest.mock import create_autospec -from rich.console import Console -from rich.console import ConsoleOptions +from rich.console import Console, ConsoleOptions from rich.text import Text from tests.utilities.render import render @@ -21,16 +20,12 @@ def test_no_highlight(): def test_highlight_from_zero(): bar = UnderlineBar(highlight_range=(0, 2.5), width=6) - assert render(bar) == ( - f"{MAGENTA}━━{STOP}{MAGENTA}╸{STOP}{GREY}━━━{STOP}" - ) + assert render(bar) == (f"{MAGENTA}━━{STOP}{MAGENTA}╸{STOP}{GREY}━━━{STOP}") def test_highlight_from_zero_point_five(): bar = UnderlineBar(highlight_range=(0.5, 2), width=6) - assert render(bar) == ( - f"{MAGENTA}╺━{STOP}{GREY}╺{STOP}{GREY}━━━{STOP}" - ) + assert render(bar) == (f"{MAGENTA}╺━{STOP}{GREY}╺{STOP}{GREY}━━━{STOP}") def test_highlight_middle(): @@ -47,10 +42,7 @@ def test_highlight_middle(): def test_highlight_half_start(): bar = UnderlineBar(highlight_range=(2.5, 4), width=6) assert render(bar) == ( - f"{GREY}━━{STOP}" - f"{MAGENTA}╺━{STOP}" - f"{GREY}╺{STOP}" - f"{GREY}━{STOP}" + f"{GREY}━━{STOP}" f"{MAGENTA}╺━{STOP}" f"{GREY}╺{STOP}" f"{GREY}━{STOP}" ) @@ -68,42 +60,30 @@ def test_highlight_half_end(): def test_highlight_half_start_and_half_end(): bar = UnderlineBar(highlight_range=(2.5, 4.5), width=6) assert render(bar) == ( - f"{GREY}━━{STOP}" - f"{MAGENTA}╺━{STOP}" - f"{MAGENTA}╸{STOP}" - f"{GREY}━{STOP}" + f"{GREY}━━{STOP}" f"{MAGENTA}╺━{STOP}" f"{MAGENTA}╸{STOP}" f"{GREY}━{STOP}" ) def test_highlight_to_near_end(): bar = UnderlineBar(highlight_range=(3, 5.5), width=6) assert render(bar) == ( - f"{GREY}━━{STOP}" - f"{GREY}╸{STOP}" - f"{MAGENTA}━━{STOP}" - f"{MAGENTA}╸{STOP}" + f"{GREY}━━{STOP}" f"{GREY}╸{STOP}" f"{MAGENTA}━━{STOP}" f"{MAGENTA}╸{STOP}" ) def test_highlight_to_end(): bar = UnderlineBar(highlight_range=(3, 6), width=6) - assert render(bar) == ( - f"{GREY}━━{STOP}{GREY}╸{STOP}{MAGENTA}━━━{STOP}" - ) + assert render(bar) == (f"{GREY}━━{STOP}{GREY}╸{STOP}{MAGENTA}━━━{STOP}") def test_highlight_out_of_bounds_start(): bar = UnderlineBar(highlight_range=(-2, 3), width=6) - assert render(bar) == ( - f"{MAGENTA}━━━{STOP}{GREY}╺{STOP}{GREY}━━{STOP}" - ) + assert render(bar) == (f"{MAGENTA}━━━{STOP}{GREY}╺{STOP}{GREY}━━{STOP}") def test_highlight_out_of_bounds_end(): bar = UnderlineBar(highlight_range=(3, 9), width=6) - assert render(bar) == ( - f"{GREY}━━{STOP}{GREY}╸{STOP}{MAGENTA}━━━{STOP}" - ) + assert render(bar) == (f"{GREY}━━{STOP}{GREY}╸{STOP}{MAGENTA}━━━{STOP}") def test_highlight_full_range_out_of_bounds_end(): @@ -117,7 +97,9 @@ def test_highlight_full_range_out_of_bounds_start(): def test_custom_styles(): - bar = UnderlineBar(highlight_range=(2, 4), highlight_style="red", background_style="green", width=6) + bar = UnderlineBar( + highlight_range=(2, 4), highlight_style="red", background_style="green", width=6 + ) assert render(bar) == ( f"{GREEN}━{STOP}" f"{GREEN}╸{STOP}" @@ -128,7 +110,9 @@ def test_custom_styles(): def test_clickable_ranges(): - bar = UnderlineBar(highlight_range=(0, 1), width=6, clickable_ranges={"foo": (0, 2), "bar": (4, 5)}) + bar = UnderlineBar( + highlight_range=(0, 1), width=6, clickable_ranges={"foo": (0, 2), "bar": (4, 5)} + ) console = create_autospec(Console) options = create_autospec(ConsoleOptions) @@ -136,8 +120,8 @@ def test_clickable_ranges(): start, end, style = text.spans[-2] assert (start, end) == (0, 2) - assert style.meta == {'@click': "range_clicked('foo')"} + assert style.meta == {"@click": "range_clicked('foo')"} start, end, style = text.spans[-1] assert (start, end) == (4, 5) - assert style.meta == {'@click': "range_clicked('bar')"} + assert style.meta == {"@click": "range_clicked('bar')"} diff --git a/tests/test_animator.py b/tests/test_animator.py index a92f38c96..e5be30ab6 100644 --- a/tests/test_animator.py +++ b/tests/test_animator.py @@ -6,7 +6,7 @@ from unittest.mock import Mock import pytest from textual._animator import Animator, SimpleAnimation -from textual._easing import EASING, DEFAULT_EASING +from textual._easing import DEFAULT_EASING, EASING class Animatable: diff --git a/tests/test_arrange.py b/tests/test_arrange.py index ad70e5cbc..31e030b1b 100644 --- a/tests/test_arrange.py +++ b/tests/test_arrange.py @@ -1,6 +1,6 @@ import pytest -from textual._arrange import arrange, TOP_Z +from textual._arrange import TOP_Z, arrange from textual._layout import WidgetPlacement from textual.geometry import Region, Size, Spacing from textual.widget import Widget diff --git a/tests/test_auto_pilot.py b/tests/test_auto_pilot.py index 5e2834c83..a6d4c2d1a 100644 --- a/tests/test_auto_pilot.py +++ b/tests/test_auto_pilot.py @@ -1,10 +1,9 @@ +from textual import events from textual.app import App from textual.pilot import Pilot -from textual import events def test_auto_pilot() -> None: - keys_pressed: list[str] = [] class TestApp(App): @@ -12,7 +11,6 @@ def test_auto_pilot() -> None: keys_pressed.append(event.key) async def auto_pilot(pilot: Pilot) -> None: - await pilot.press("tab", *"foo") await pilot.exit("bar") diff --git a/tests/test_binding.py b/tests/test_binding.py index 9a24b3e2d..65a8c0285 100644 --- a/tests/test_binding.py +++ b/tests/test_binding.py @@ -3,7 +3,7 @@ from string import ascii_lowercase import pytest from textual.app import App -from textual.binding import Bindings, Binding, BindingError, NoBinding, InvalidBinding +from textual.binding import Binding, BindingError, Bindings, InvalidBinding, NoBinding BINDING1 = Binding("a,b", action="action1", description="description1") BINDING2 = Binding("c", action="action2", description="description2") diff --git a/tests/test_border.py b/tests/test_border.py index 852e713ba..37133125b 100644 --- a/tests/test_border.py +++ b/tests/test_border.py @@ -5,7 +5,6 @@ from textual._border import render_row def test_border_render_row(): - style = Style.parse("red") row = (Segment("┏", style), Segment("━", style), Segment("┓", style)) diff --git a/tests/test_cache.py b/tests/test_cache.py index 1bf589755..384eccb23 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,5 +1,4 @@ -from __future__ import annotations -from __future__ import unicode_literals +from __future__ import annotations, unicode_literals import pytest diff --git a/tests/test_call_later.py b/tests/test_call_later.py index 025eb8c12..506db93a5 100644 --- a/tests/test_call_later.py +++ b/tests/test_call_later.py @@ -1,4 +1,5 @@ import asyncio + from textual.app import App diff --git a/tests/test_color.py b/tests/test_color.py index 10340d3dc..c4ef8311c 100644 --- a/tests/test_color.py +++ b/tests/test_color.py @@ -43,7 +43,6 @@ def test_rgb(): def test_hls(): - red = Color(200, 20, 32) print(red.hsl) assert red.hsl == pytest.approx( diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index c73418f2f..4dab38dc2 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -1,6 +1,7 @@ +from threading import Thread + import pytest -from threading import Thread from textual.app import App, ComposeResult from textual.widgets import TextLog diff --git a/tests/test_dom.py b/tests/test_dom.py index ded834300..f366d0706 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -1,7 +1,7 @@ import pytest from textual.css.errors import StyleValueError -from textual.dom import DOMNode, BadIdentifier +from textual.dom import BadIdentifier, DOMNode def test_display_default(): diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 6b9cd07b1..c8c663df5 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -1,6 +1,6 @@ import pytest -from textual.geometry import clamp, Offset, Size, Region, Spacing +from textual.geometry import Offset, Region, Size, Spacing, clamp def test_dimensions_region(): @@ -299,6 +299,7 @@ def test_size_line_range(): assert Size(20, 0).line_range == range(0) assert Size(0, 20).line_range == range(20) + def test_region_x_extents(): assert Region(5, 10, 20, 30).column_span == (5, 25) diff --git a/tests/test_immutable_sequence_view.py b/tests/test_immutable_sequence_view.py index fd691798c..5e3dffde8 100644 --- a/tests/test_immutable_sequence_view.py +++ b/tests/test_immutable_sequence_view.py @@ -1,6 +1,7 @@ +from typing import Sequence + import pytest -from typing import Sequence from textual._immutable_sequence_view import ImmutableSequenceView diff --git a/tests/test_loop.py b/tests/test_loop.py index c235f23a5..87ef97da7 100644 --- a/tests/test_loop.py +++ b/tests/test_loop.py @@ -1,4 +1,4 @@ -from textual._loop import loop_first, loop_last, loop_first_last +from textual._loop import loop_first, loop_first_last, loop_last def test_loop_first(): diff --git a/tests/test_node_list.py b/tests/test_node_list.py index 71001559f..37d6bfd28 100644 --- a/tests/test_node_list.py +++ b/tests/test_node_list.py @@ -1,7 +1,7 @@ import pytest -from textual.widget import Widget from textual._node_list import NodeList +from textual.widget import Widget def test_empty_list(): diff --git a/tests/test_overflow_change.py b/tests/test_overflow_change.py index 1ebd39765..236a15f8c 100644 --- a/tests/test_overflow_change.py +++ b/tests/test_overflow_change.py @@ -1,7 +1,6 @@ """Regression test for #1616 https://github.com/Textualize/textual/issues/1616""" import pytest - from textual.app import App from textual.containers import Vertical diff --git a/tests/test_paste.py b/tests/test_paste.py index 58c5da41d..e8d7be34e 100644 --- a/tests/test_paste.py +++ b/tests/test_paste.py @@ -1,5 +1,5 @@ -from textual.app import App from textual import events +from textual.app import App async def test_paste_app(): diff --git a/tests/test_path.py b/tests/test_path.py index 3b9b268ea..501ab0523 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1,5 +1,7 @@ from __future__ import annotations + from pathlib import Path + import pytest from textual.app import App diff --git a/tests/test_query.py b/tests/test_query.py index c2368ba47..c58ffd575 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -2,8 +2,8 @@ import pytest from textual.app import App, ComposeResult from textual.containers import Container +from textual.css.query import InvalidQueryFormat, NoMatches, TooManyMatches, WrongType from textual.widget import Widget -from textual.css.query import InvalidQueryFormat, WrongType, NoMatches, TooManyMatches def test_query(): diff --git a/tests/test_reactive.py b/tests/test_reactive.py index 8a889c61a..da8be66ae 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -259,7 +259,6 @@ async def test_reactive_method_call_order(): async def test_premature_reactive_call(): - watcher_called = False class BrokenWidget(Widget): @@ -335,7 +334,6 @@ async def test_watch_compute(): watch_called: list[bool] = [] class Calculator(App): - numbers = var("0") show_ac = var(True) value = var("") diff --git a/tests/test_screens.py b/tests/test_screens.py index 707bad5df..e877c1ade 100644 --- a/tests/test_screens.py +++ b/tests/test_screens.py @@ -16,15 +16,17 @@ async def test_installed_screens(): SCREENS = { "home": Screen, # Screen type "one": Screen(), # Screen instance - "two": lambda: Screen() # Callable[[], Screen] + "two": lambda: Screen(), # Callable[[], Screen] } app = ScreensApp() async with app.run_test() as pilot: pilot.app.push_screen("home") # Instantiates and pushes the "home" screen - pilot.app.push_screen("one") # Pushes the pre-instantiated "one" screen + pilot.app.push_screen("one") # Pushes the pre-instantiated "one" screen pilot.app.push_screen("home") # Pushes the single instance of "home" screen - pilot.app.push_screen("two") # Calls the callable, pushes returned Screen instance + pilot.app.push_screen( + "two" + ) # Calls the callable, pushes returned Screen instance assert len(app.screen_stack) == 5 assert app.screen_stack[1] is app.screen_stack[3] @@ -40,10 +42,8 @@ async def test_installed_screens(): pilot.app.pop_screen() - @skip_py310 async def test_screens(): - app = App() app._set_active() diff --git a/tests/test_segment_tools.py b/tests/test_segment_tools.py index 630114ed9..befe4baae 100644 --- a/tests/test_segment_tools.py +++ b/tests/test_segment_tools.py @@ -1,7 +1,7 @@ from rich.segment import Segment from rich.style import Style -from textual._segment_tools import line_crop, line_trim, line_pad +from textual._segment_tools import line_crop, line_pad, line_trim def test_line_crop(): diff --git a/tests/test_strip.py b/tests/test_strip.py index 40f3975fe..82d7ec680 100644 --- a/tests/test_strip.py +++ b/tests/test_strip.py @@ -2,9 +2,9 @@ import pytest from rich.segment import Segment from rich.style import Style +from textual._filter import Monochrome from textual._segment_tools import NoCellPositionForIndex from textual.strip import Strip -from textual._filter import Monochrome def test_cell_length() -> None: diff --git a/tests/test_table.py b/tests/test_table.py index 827242e85..1290933d4 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -46,8 +46,8 @@ async def test_table_clear_with_columns() -> None: assert table.data == {} assert table.row_count == 0 -async def test_table_add_row() -> None: +async def test_table_add_row() -> None: app = TableApp() async with app.run_test(): table = app.query_one(DataTable) diff --git a/tests/test_test_runner.py b/tests/test_test_runner.py index 0435d31d9..b47bed98d 100644 --- a/tests/test_test_runner.py +++ b/tests/test_test_runner.py @@ -1,5 +1,5 @@ -from textual.app import App from textual import events +from textual.app import App async def test_run_test() -> None: diff --git a/tests/test_text_backend.py b/tests/test_text_backend.py index bf9296720..135931e3f 100644 --- a/tests/test_text_backend.py +++ b/tests/test_text_backend.py @@ -113,21 +113,25 @@ def test_query_cursor_right_cursor_at_end_returns_false(): editor = TextEditorBackend(CONTENT, len(CONTENT)) assert not editor.query_cursor_right() + def test_cursor_text_start_cursor_already_at_start(): editor = TextEditorBackend(CONTENT) assert not editor.cursor_text_start() assert editor.cursor_index == 0 + def test_cursor_text_start_cursor_in_middle(): editor = TextEditorBackend(CONTENT, 6) assert editor.cursor_text_start() assert editor.cursor_index == 0 + def test_cursor_text_end_cursor_already_at_end(): editor = TextEditorBackend(CONTENT, len(CONTENT)) assert not editor.cursor_text_end() assert editor.cursor_index == len(CONTENT) + def test_cursor_text_end_cursor_in_middle(): editor = TextEditorBackend(CONTENT, len(CONTENT)) assert not editor.cursor_text_end() @@ -140,6 +144,7 @@ def test_insert_at_cursor_cursor_at_start(): assert editor.content == "ABC" + CONTENT assert editor.cursor_index == len("ABC") + def test_insert_at_cursor_cursor_in_middle(): start_cursor_index = 6 editor = TextEditorBackend(CONTENT, start_cursor_index) @@ -154,6 +159,7 @@ def test_insert_at_cursor_cursor_at_end(): assert editor.content == CONTENT + "ABC" assert editor.cursor_index == len(editor.content) + def test_get_range(): editor = TextEditorBackend(CONTENT) assert editor.get_range(0, 5) == "Hello" diff --git a/tests/test_unmount.py b/tests/test_unmount.py index 13e2e79b3..6ef23f247 100644 --- a/tests/test_unmount.py +++ b/tests/test_unmount.py @@ -1,7 +1,7 @@ from __future__ import annotations -from textual.app import App, ComposeResult from textual import events +from textual.app import App, ComposeResult from textual.containers import Container from textual.screen import Screen diff --git a/tests/test_widget.py b/tests/test_widget.py index a06cf7857..79c4f466c 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -5,7 +5,7 @@ from textual.app import App, ComposeResult from textual.css.errors import StyleValueError from textual.css.query import NoMatches from textual.geometry import Size -from textual.widget import Widget, MountError +from textual.widget import MountError, Widget from textual.widgets import Label diff --git a/tests/test_widget_mount_point.py b/tests/test_widget_mount_point.py index 67a6269c3..eebfdec5a 100644 --- a/tests/test_widget_mount_point.py +++ b/tests/test_widget_mount_point.py @@ -1,6 +1,6 @@ import pytest -from textual.widget import Widget, MountError +from textual.widget import MountError, Widget class Content(Widget): @@ -12,7 +12,6 @@ class Body(Widget): def test_find_dom_spot(): - # Build up a "fake" DOM for an application. screen = Widget(name="Screen") header = Widget(name="Header", id="header") diff --git a/tests/test_widget_mounting.py b/tests/test_widget_mounting.py index 189c77c14..666dca537 100644 --- a/tests/test_widget_mounting.py +++ b/tests/test_widget_mounting.py @@ -1,9 +1,9 @@ import pytest from textual.app import App -from textual.widget import Widget, WidgetError, MountError -from textual.widgets import Static from textual.css.query import TooManyMatches +from textual.widget import MountError, Widget, WidgetError +from textual.widgets import Static class SelfOwn(Widget): diff --git a/tests/test_widget_removing.py b/tests/test_widget_removing.py index a33860c83..49b92e191 100644 --- a/tests/test_widget_removing.py +++ b/tests/test_widget_removing.py @@ -1,8 +1,9 @@ import asyncio + from textual.app import App -from textual.widget import Widget -from textual.widgets import Static, Button from textual.containers import Container +from textual.widget import Widget +from textual.widgets import Button, Static async def test_remove_single_widget(): diff --git a/tests/test_xterm_parser.py b/tests/test_xterm_parser.py index 1b426267b..92ff1f31c 100644 --- a/tests/test_xterm_parser.py +++ b/tests/test_xterm_parser.py @@ -5,13 +5,13 @@ import pytest from textual._xterm_parser import XTermParser from textual.events import ( - Paste, Key, MouseDown, - MouseUp, MouseMove, MouseScrollDown, MouseScrollUp, + MouseUp, + Paste, ) from textual.messages import TerminalSupportsSynchronizedOutput diff --git a/tests/tree/test_tree_get_node_by_id.py b/tests/tree/test_tree_get_node_by_id.py index ffee36996..62f481aa9 100644 --- a/tests/tree/test_tree_get_node_by_id.py +++ b/tests/tree/test_tree_get_node_by_id.py @@ -1,5 +1,7 @@ -import pytest from typing import cast + +import pytest + from textual.widgets import Tree from textual.widgets._tree import NodeID diff --git a/tests/tree/test_tree_messages.py b/tests/tree/test_tree_messages.py index df7442d31..6296126e8 100644 --- a/tests/tree/test_tree_messages.py +++ b/tests/tree/test_tree_messages.py @@ -1,9 +1,10 @@ from __future__ import annotations from typing import Any + from textual.app import App, ComposeResult -from textual.widgets import Tree from textual.message import Message +from textual.widgets import Tree class MyTree(Tree[None]): diff --git a/tests/tree/test_tree_node_children.py b/tests/tree/test_tree_node_children.py index d6c5c7e4e..e68656036 100644 --- a/tests/tree/test_tree_node_children.py +++ b/tests/tree/test_tree_node_children.py @@ -1,4 +1,5 @@ import pytest + from textual.widgets import Tree from textual.widgets.tree import TreeNode diff --git a/tests/tree/test_tree_node_label.py b/tests/tree/test_tree_node_label.py index 7d7a04329..8c67f316a 100644 --- a/tests/tree/test_tree_node_label.py +++ b/tests/tree/test_tree_node_label.py @@ -1,6 +1,7 @@ +from rich.text import Text + from textual.widgets import Tree from textual.widgets.tree import TreeNode -from rich.text import Text def test_tree_node_label() -> None: From 451fa3e50a06fce87c789535c36d4a2589918d62 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Thu, 9 Feb 2023 15:52:14 +0000 Subject: [PATCH 25/25] Fix a typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ba65722f6..954588fbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ include = [ { path = "tests", format = "sdist" }, # The reason for the slightly convoluted path specification here is that # poetry populates the exclude list with the content of .gitignore, and - # it also seems like exclude tumps include. So here we specify that we + # it also seems like exclude trumps include. So here we specify that we # want to package up the content of the docs-offline directory in a way # that works around that. { path = "docs-offline/**/*", format = "sdist" }