Skip to content

getpass's echo_char should be restricted to a single ASCII character #138514

Description

@bkjoh

Bug report

Bug description:

Running getpass.getpass(echo_char="***") works until a character is entered, at which point a traceback error occurs.

import getpass
getpass.getpass(echo_char="***")
Password: Traceback (most recent call last):
  File "<python-input-10>", line 1, in <module>
    getpass.getpass(echo_char="***")
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "...\pythoncore-3.14-64\Lib\getpass.py", line 129, in win_getpass
    msvcrt.putwch(echo_char)
    ~~~~~~~~~~~~~^^^^^^^^^^^
TypeError: putwch(): argument must be a unicode character, not a string of length 3

Validation should occur upon input for this argument, and getpass should raise a ValueError stating: "'echo_char' must be a single-character ASCII string, not a string of length 3" (with ASCII only being bolded in this write-up for emphasis that a Unicode character cannot be used).

Additionally, the error message language should be revised when a non-ASCII string is entered:

import getpass
getpass.getpass(echo_char="Æ")
Traceback (most recent call last):
  File "<python-input-11>", line 1, in <module>
    getpass.getpass(echo_char="Æ")
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "...\pythoncore-3.14-64\Lib\getpass.py", line 109, in win_getpass
    _check_echo_char(echo_char)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "...\pythoncore-3.14-64\Lib\getpass.py", line 149, in _check_echo_char
    raise ValueError("'echo_char' must be a printable ASCII string, "
                     f"got: {echo_char!r}")
ValueError: 'echo_char' must be a printable ASCII string, got: 'Æ'

Better language would be: "'echo_char' must be a single-character ASCII string, got: 'Æ'".

With agreement, I can submit a pull request.

CPython versions tested on:

3.14

Operating systems tested on:

Windows

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Sep 4, 2025
  2. changed the title [-]`getpass` `echo_char` Validation Failure & Unclear Language[/-] [+]`getpass` `echo_char` Input Validation Failure & Imprecise Language[/+] on Sep 4, 2025
  3. brianschubert commented on Sep 4, 2025

    @brianschubert
    Contributor

    Note that the error when using a multi-character echo_char only occurs on Windows; the unix implementation is able to handle multi-character values (whether intended or not).

  4. bkjoh commented on Sep 4, 2025

    @bkjoh
    ContributorAuthor

    If multi-character values are allowed on Unix-based systems, should this issue instead be resolved by adjusting the code to work with multi-character echo_char strings on Windows?

  5. uranusjr commented on Sep 5, 2025

    @uranusjr
    Contributor

    the unix implementation is able to handle multi-character values

    Does it? It does the same check right at the top

    _check_echo_char(echo_char)

    Reading the implementation, I’m inclined to say the feature should only accept ASCII, and it’s a bug if it behaves otherwise.

  6. donbarbos commented on Sep 5, 2025

    @donbarbos
    Contributor

    Thank you for noticing this inconsistency!
    I would prefer to keep the ability to pass in strings longer than a single character, allowing for a more permissive behavior.
    I don’t currently have access to a Windows machine to test this, but it seems the issue could be solved fairly easily by adding the output one at a time:

    if echo_char:
        for c in echo_char: # new loop
            msvcrt.putwch(c)

    And I’d like to point out that it would be great if tests for Windows could be implemented (for a separate issue #130524), since they are still missing. That way, we could ensure consistent behavior across all implementations.

  7. bkjoh commented on Sep 5, 2025

    @bkjoh
    ContributorAuthor

    I can implement multi-character acceptance on Windows! I could also complete the test cases, because I have a Windows machine to test on.

  8. brianschubert commented on Sep 5, 2025

    @brianschubert
    Contributor

    I think it would be preferable to limit this to single characters strings for the reasons @picnixz gave in #130496 (comment). Support for longer strings and/or non-ASCII characters can always be added later.

    It also seems that the unix implementation doesn't work with multi-character strings either, just in a different way. It can accept and print longer strings, but the output becomes garbled if you try to delete characters

  9. brianschubert commented on Sep 5, 2025

    @brianschubert
    Contributor

    Another possibly unintended behavior: passing echo_char disables line editing on the Unix implementation. For example, the result of entering foo CTRL+U bar varies depending on if echo_char is passed:

    >>> getpass.getpass()
    Password: 
    'bar'
    >>> getpass.getpass(echo_char="*")
    Password: *******
    'foo\x15bar'
  10. bkjoh commented on Sep 5, 2025

    @bkjoh
    ContributorAuthor

    I agree. While I like the idea of handling multi-character strings in theory, it does not seem necessary for most users, and if it adds complexity with additional edge cases, perhaps it is worth modifying this feature to accept only a single ASCII character.

    If so, does the proposed language in the bug report sound good?

    I have both Windows and Unix machines, and I am happy to implement these changes for both the Windows and Unix implementations.

  11. bkjoh commented on Sep 5, 2025

    @bkjoh
    ContributorAuthor

    As for line editing -- I think it should be allowed in all cases on Unix systems.

  12. added
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Sep 6, 2025
  13. picnixz commented on Sep 6, 2025

    @picnixz
    Member

    I agree that we should restrict the input to a single ASCII char with a better message. I don't remmeber why I didn't pressed for this behavior despite my comment (or did I?) I think I may have forgotten...

    For example, the result of entering foo CTRL+U bar varies depending on if echo_char is passed

    See #138577.

  14. changed the title [-]`getpass` `echo_char` Input Validation Failure & Imprecise Language[/-] [+]`getpass`'s `echo_char` should be restricted to a single ASCII character[/+] on Sep 6, 2025
  15. picnixz commented on Sep 6, 2025

    @picnixz
    Member

    @benjaminjohnson01 You can take care of the 1-char ASCII validation.

  16. added a commit that references this issue on Sep 16, 2025
  17. added a commit that references this issue on Sep 16, 2025
  18. added a commit that references this issue on Sep 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.14bugs and security fixes3.15bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions