Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
21 changes: 19 additions & 2 deletions src/prompt_toolkit/shortcuts/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from contextlib import contextmanager
from enum import Enum
from functools import partial
from typing import TYPE_CHECKING, Generic, TypeVar, Union, cast
from typing import TYPE_CHECKING, Any, Generic, TypeVar, Union, cast

from prompt_toolkit.application import Application
from prompt_toolkit.application.current import get_app
Expand All @@ -50,6 +50,7 @@
from prompt_toolkit.eventloop import InputHook
from prompt_toolkit.filters import (
Condition,
Filter,
FilterOrBool,
has_arg,
has_focus,
Expand Down Expand Up @@ -200,6 +201,21 @@ def __init__(self, text: AnyFormattedText) -> None:
)


class _PromptBuffer(Buffer):
"""
The default buffer of a `PromptSession`. Input that is accepted while
`is_password` is active is not appended to the history.
"""

def __init__(self, is_password: Filter, **kwargs: Any) -> None:
self._is_password = is_password
super().__init__(**kwargs)

def append_to_history(self) -> None:
if not self._is_password():
super().append_to_history()


class CompleteStyle(str, Enum):
"""
How to display autocompletions for the prompt.
Expand Down Expand Up @@ -515,7 +531,8 @@ def accept(buff: Buffer) -> bool:
)
return True # Keep text, we call 'reset' later on.

return Buffer(
return _PromptBuffer(
is_password=dyncond("is_password"),
name=DEFAULT_BUFFER,
# Make sure that complete_while_typing is disabled when
# enable_history_search is enabled. (First convert to Filter,
Expand Down
18 changes: 18 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,3 +940,21 @@ def test_accept_default():
# prompt reset between calls happened at the wrong time, breaking this.)
result = session.prompt(default="world", accept_default=True)
assert result == "world"


def test_password_input_not_added_to_history():
history = InMemoryHistory()

with create_pipe_input() as inp:
session = PromptSession(input=inp, output=DummyOutput(), history=history)

inp.send_text("alice\r")
assert session.prompt() == "alice"

inp.send_text("hunter2\r")
assert session.prompt(is_password=True) == "hunter2"

inp.send_text("ls\r")
assert session.prompt(is_password=False) == "ls"

assert list(history.get_strings()) == ["alice", "ls"]
Loading