Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 16 additions & 22 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: test
on:
push: # any branch
pull_request:
branches: [master]
branches: [main]

env:
FORCE_COLOR: 1
Expand All @@ -14,41 +14,35 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version:
["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]

steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- uses: actions/checkout@v6.0.2
- uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
- name: Code formatting
if: ${{ matrix.python-version == '3.13' }}
if: ${{ matrix.python-version == '3.14' }}
run: |
uvx ruff check .
uvx ruff format --check .
uv run ruff check .
uv run ruff format --check .
- name: Typos
if: ${{ matrix.python-version == '3.13' }}
if: ${{ matrix.python-version == '3.14' }}
run: |
uvx typos .
uv run typos .
- name: Unit test
run: |
uvx --with . --with pytest coverage run -m pytest tests/
uv run coverage run -m pytest tests/
- name: Type Checking
if: ${{ matrix.python-version != '3.8' }}
run: |
uvx --with . --with asyncssh mypy --strict src/ --platform win32
uvx --with . --with asyncssh mypy --strict src/ --platform linux
uvx --with . --with asyncssh mypy --strict src/ --platform darwin
- name: Validate README.md
if: ${{ matrix.python-version == '3.13' }}
# Ensure that the README renders correctly (required for uploading to PyPI).
run: |
uv pip install readme_renderer
python -m readme_renderer README.rst > /dev/null
uv run mypy --strict src/ --platform win32
uv run mypy --strict src/ --platform linux
uv run mypy --strict src/ --platform darwin
- name: Run codecov
run: |
uvx codecov
uv run codecov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pip-log.txt
.tox
nosetests.xml
.pytest_cache
coverage.xml

# Translations
*.mo
Expand All @@ -45,6 +46,9 @@ docs/_build
# pycharm metadata
.idea

# uv
uv.lock

# vscode metadata
.vscode

Expand Down
31 changes: 31 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v6.0.0"
hooks:
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-toml
Comment thread
jonathanslenders marked this conversation as resolved.
- id: check-yaml
Comment thread
jonathanslenders marked this conversation as resolved.
Outdated
- id: detect-private-key
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.15.6"
hooks:
- id: ruff-format
args: [--config=pyproject.toml]
- id: ruff-check
args: [--config=pyproject.toml, --fix, --exit-non-zero-on-fix]

- repo: https://github.com/crate-ci/typos
rev: v1.44.0
hooks:
- id: typos
exclude: |
(?x)^(
tests/.*
)$
100 changes: 100 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Simple Makefile for use with a uv-based development environment
# The at (@) prefix tells make to suppress output from the command
# The hyphen (-) prefix tells make to ignore errors (e.g., if a directory doesn't exist)

.PHONY: install
install: ## Install the virtual environment with dependencies
@echo "🚀 Creating uv Python virtual environment"
@uv python install 3.14
@uv sync --python=3.14
@echo "🚀 Installing Git prek hooks locally"
@uv run prek install -f

.PHONY: check
check: ## Run code quality tools.
@echo "🚀 Checking lock file consistency with 'pyproject.toml'"
@uv lock --locked
@echo "🚀 Auto-formatting/Linting code and documentation: Running prek"
@uv run prek run -a
@echo "🚀 Static type checking: Running mypy"
@uv run mypy

.PHONY: format
format: ## Perform ruff formatting
@uv run ruff format

.PHONY: lint
lint: ## Perform ruff linting
@uv run ruff check --fix

.PHONY: typecheck
typecheck: ## Perform type checking
@uv run mypy

.PHONY: test
test: ## Test the code with pytest.
@echo "🚀 Testing code: Running pytest"
@uv run python -Xutf8 -m pytest --cov --cov-config=pyproject.toml --cov-report=xml tests

# TODO Add stuff for building Sphinx docs

.PHONY: build
build: clean-build ## Build wheel file
@echo "🚀 Creating wheel file"
@uv build

.PHONY: tag
Comment thread
tleonhardt marked this conversation as resolved.
Outdated
tag: ## Add a Git tag and push it to origin with syntax: make tag TAG=tag_name
@echo "🚀 Creating git tag: ${TAG}"
@git tag -a ${TAG} -m ""
@echo "🚀 Pushing tag to origin: ${TAG}"
@git push origin ${TAG}

# Define variables for files/directories to clean
BUILD_DIRS = build dist *.egg-info
DOC_DIRS = build
MYPY_DIRS = .mypy_cache dmypy.json dmypy.sock
TEST_DIRS = .cache .pytest_cache htmlcov
TEST_FILES = .coverage coverage.xml

.PHONY: clean-build
clean-build: ## Clean build artifacts
@echo "🚀 Removing build artifacts"
@uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(BUILD_DIRS)'.split() if os.path.isdir(d)]"

.PHONY: clean-docs
clean-docs: ## Clean documentation artifacts
@echo "🚀 Removing documentation artifacts"
@uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(DOC_DIRS)'.split() if os.path.isdir(d)]"

.PHONY: clean-mypy
clean-mypy: ## Clean mypy artifacts
@echo "🚀 Removing mypy artifacts"
@uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(MYPY_DIRS)'.split() if os.path.isdir(d)]"

.PHONY: clean-pycache
clean-pycache: ## Clean pycache artifacts
@echo "🚀 Removing pycache artifacts"
@-find . -type d -name "__pycache__" -exec rm -r {} +

.PHONY: clean-ruff
clean-ruff: ## Clean ruff artifacts
@echo "🚀 Removing ruff artifacts"
@uv run ruff clean

.PHONY: clean-test
clean-test: ## Clean test artifacts
@echo "🚀 Removing test artifacts"
@uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(TEST_DIRS)'.split() if os.path.isdir(d)]"
@uv run python -c "from pathlib import Path; [Path(f).unlink(missing_ok=True) for f in '$(TEST_FILES)'.split()]"

.PHONY: clean
clean: clean-build clean-docs clean-mypy clean-pycache clean-ruff clean-test ## Clean all artifacts
@echo "🚀 Cleaned all artifacts"

.PHONY: help
help:
@uv run python -c "import re; \
[[print(f'\033[36m{m[0]:<20}\033[0m {m[1]}') for m in re.findall(r'^([a-zA-Z_-]+):.*?## (.*)$$', open(makefile).read(), re.M)] for makefile in ('$(MAKEFILE_LIST)').strip().split()]"

.DEFAULT_GOAL := help
2 changes: 1 addition & 1 deletion PROJECTS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Shells:
- `athenacli <https://github.com/dbcli/athenacli>`_: A CLI for AWS Athena.
- `vulcano <https://github.com/dgarana/vulcano>`_: A framework for creating command-line applications that also runs in REPL mode.
- `kafka-shell <https://github.com/devshawn/kafka-shell>`_: A supercharged shell for Apache Kafka.
- `starterTree <https://github.com/thomas10-10/starterTree>`_: A command launcher organized in a tree structure with fuzzy autocompletion
- `starterTree <https://github.com/thomas10-10/starterTree>`_: A command launcher organized in a tree structure with fuzzy autocompletion
- `git-delete-merged-branches <https://github.com/hartwork/git-delete-merged-branches>`_: Command-line tool to delete merged Git branches
- `radian <https://github.com/randy3k/radian>`_: A 21 century R console

Expand Down
1 change: 0 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,3 @@ Special thanks to

.. |Codecov| image:: https://codecov.io/gh/prompt-toolkit/python-prompt-toolkit/branch/master/graphs/badge.svg?style=flat
:target: https://codecov.io/gh/prompt-toolkit/python-prompt-toolkit/

2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Have a look at :ref:`the gallery <gallery>` to get an idea of what is possible.
Getting started
---------------

Go to :ref:`getting started <getting_started>` and build your first prompt.
Go to :ref:`getting started <getting_started>` and build your first prompt.
Issues are tracked `on the Github project
<https://github.com/prompt-toolkit/python-prompt-toolkit>`_.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/advanced_topics/styling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ The style is determined as follows:

- Then we go through this style from left to right, starting from the default
style. Inline styling is applied directly.

If we come across a class name, then we generate all combinations of the
class names that we collected so far (this one and all class names to the
left), and for each combination which includes the new class name, we look
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/advanced_topics/unit_testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ these.
structures (like text buffers) change over time.

So we programmatically feed some input to the input pipe, have the key
bindings process the input and then test what comes out of it.
bindings process the input and then test what comes out of it.

In the following example we use a
:class:`~prompt_toolkit.shortcuts.PromptSession`, but the same works for any
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/asking_for_input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Suppose we'd like to use a Pygments style, for instance
tango_style = style_from_pygments_cls(TangoStyle)

text = prompt(
"Enter HTML: ",
"Enter HTML: ",
lexer=PygmentsLexer(HtmlLexer),
style=tango_style
)
Expand Down
24 changes: 12 additions & 12 deletions docs/pages/dialogs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ each providing the return value (first element) and the displayed value (second

from prompt_toolkit.shortcuts import radiolist_dialog

result = radiolist_dialog(
title="RadioList dialog",
text="Which breakfast would you like ?",
values=[
("breakfast1", "Eggs and beacon"),
("breakfast2", "French breakfast"),
("breakfast3", "Equestrian breakfast")
]
result = radiolist_dialog(
title="RadioList dialog",
text="Which breakfast would you like ?",
values=[
("breakfast1", "Eggs and beacon"),
("breakfast2", "French breakfast"),
("breakfast3", "Equestrian breakfast")
]
).run()


Expand All @@ -118,15 +118,15 @@ The :func:`~prompt_toolkit.shortcuts.checkboxlist_dialog` has the same usage and

from prompt_toolkit.shortcuts import checkboxlist_dialog

results_array = checkboxlist_dialog(
title="CheckboxList dialog",
results_array = checkboxlist_dialog(
title="CheckboxList dialog",
text="What would you like in your breakfast ?",
values=[
values=[
("eggs", "Eggs"),
("bacon", "Bacon"),
("croissants", "20 Croissants"),
("daily", "The breakfast of the day")
]
]
).run()


Expand Down
4 changes: 2 additions & 2 deletions docs/pages/full_screen_apps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ a key press), it will send that to the the appropriate handler, like for
instance, a key binding.

When :func:`~prompt_toolkit.application.Application.run()` is called, the event
loop will run until the application is done. An application will quit when
loop will run until the application is done. An application will quit when
:func:`~prompt_toolkit.application.Application.exit()` is called.


Expand Down Expand Up @@ -311,7 +311,7 @@ the key handler:
Pressing Ctrl-Q will exit the user interface.

Setting a return value means: quit the event loop that drives the user
interface and return this value from the `Application.run()` call.
interface and return this value from the `Application.run()` call.
"""
event.app.exit()

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/progress_bars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Progress bars
=============

Prompt_toolkit ships with a high level API for displaying progress bars,
inspired by `tqdm <https://github.com/tqdm/tqdm>`_
inspired by `tqdm <https://github.com/tqdm/tqdm>`_

.. warning::

Expand Down
1 change: 0 additions & 1 deletion docs/pages/upgrading/2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,3 @@ rather then inheriting from `Filter`. For instance:
@Condition
def my_filter();
return True # Or False

2 changes: 1 addition & 1 deletion examples/tutorial/README.md
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1 +1 @@
See http://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html
See http://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html
Loading
Loading