Skip to content

Commit 7d412d9

Browse files
committed
Accept only single character with getpass.getpass(echo_char) (see: gh-138514)
1 parent c919d02 commit 7d412d9

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

Doc/library/getpass.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ The :mod:`getpass` module provides two functions:
2727

2828
The *echo_char* argument controls how user input is displayed while typing.
2929
If *echo_char* is ``None`` (default), input remains hidden. Otherwise,
30-
*echo_char* must be a printable ASCII string and each typed character
31-
is replaced by it. For example, ``echo_char='*'`` will display
32-
asterisks instead of the actual input.
30+
*echo_char* must be a single-character, printable ASCII string and each
31+
typed character is replaced by it. For example, ``echo_char='*'`` will
32+
display asterisks instead of the actual input.
3333

3434
If echo free input is unavailable getpass() falls back to printing
3535
a warning message to *stream* and reading from ``sys.stdin`` and

Lib/getpass.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
1212
"""
1313

14+
# fmt: off
15+
# isort: skip_file
16+
1417
# Authors: Piers Lauder (original)
1518
# Guido van Rossum (Windows support and cleanup)
1619
# Gregory P. Smith (tty support & GetPassWarning)
@@ -33,8 +36,8 @@ def unix_getpass(prompt='Password: ', stream=None, *, echo_char=None):
3336
prompt: Written on stream to ask for the input. Default: 'Password: '
3437
stream: A writable file object to display the prompt. Defaults to
3538
the tty. If no tty is available defaults to sys.stderr.
36-
echo_char: A string used to mask input (e.g., '*'). If None, input is
37-
hidden.
39+
echo_char: A single-character string used to mask input (e.g., '*').
40+
If None, input is hidden.
3841
Returns:
3942
The seKr3t input.
4043
Raises:
@@ -144,10 +147,14 @@ def fallback_getpass(prompt='Password: ', stream=None, *, echo_char=None):
144147

145148

146149
def _check_echo_char(echo_char):
147-
# ASCII excluding control characters
148-
if echo_char and not (echo_char.isprintable() and echo_char.isascii()):
149-
raise ValueError("'echo_char' must be a printable ASCII string, "
150-
f"got: {echo_char!r}")
150+
# Single-character ASCII excluding control characters
151+
if echo_char and not (
152+
len(echo_char) == 1
153+
and echo_char.isprintable()
154+
and echo_char.isascii()
155+
):
156+
raise ValueError("'echo_char' must be a single-character, printable "
157+
f"ASCII string, got: {echo_char!r}")
151158

152159

153160
def _raw_input(prompt="", stream=None, input=None, echo_char=None):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ Jim Jewett
906906
Pedro Diaz Jimenez
907907
Orjan Johansen
908908
Fredrik Johansson
909+
Benjamin K. Johnson
909910
Gregory K. Johnson
910911
Kent Johnson
911912
Michael Johnson
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Modify :func:`getpass.getpass` to accept only a single character. Patch by
2+
Benjamin Johnson.

0 commit comments

Comments
 (0)