@@ -43,9 +43,8 @@ def unix_getpass(prompt='Password: ', stream=None, *, echochar=None):
4343
4444    Always restores terminal settings before returning. 
4545    """ 
46-     if  echochar  and  not  echochar .isascii ():
47-         return  ValueError (f"Invalid echochar: { echochar }  
48-                           "ASCII character expected." )
46+     if  _is_ascii (echochar ):
47+         return  ValueError (f"'echochar' must be ASCII, got: { echochar !r}  )
4948
5049    passwd  =  None 
5150    with  contextlib .ExitStack () as  stack :
@@ -82,13 +81,11 @@ def unix_getpass(prompt='Password: ', stream=None, *, echochar=None):
8281                    tcsetattr_flags  |=  termios .TCSASOFT 
8382                try :
8483                    termios .tcsetattr (fd , tcsetattr_flags , new )
85-                     if  not  echochar :
84+                     if  echochar :
85+                         passwd  =  _input_with_echochar (prompt , stream , input ,
86+                                                       echochar )
87+                     else :
8688                        passwd  =  _raw_input (prompt , stream , input = input )
87-                         stream .write ('\n ' )
88-                         return  passwd 
89- 
90-                     passwd  =  _input_with_echochar (prompt , stream , input ,
91-                                                   echochar )
9289                finally :
9390                    termios .tcsetattr (fd , tcsetattr_flags , old )
9491                    stream .flush ()  # issue7208 
@@ -112,9 +109,8 @@ def win_getpass(prompt='Password: ', stream=None, *, echochar=None):
112109    """Prompt for password with echo off, using Windows getwch().""" 
113110    if  sys .stdin  is  not sys .__stdin__ :
114111        return  fallback_getpass (prompt , stream )
115-     if  echochar  and  not  echochar .isascii ():
116-         return  ValueError (f"Invalid echochar: { echochar }  
117-                           "ASCII character expected." )
112+     if  _is_ascii (echochar ):
113+         return  ValueError (f"'echochar' must be ASCII, got: { echochar !r}  )
118114
119115    for  c  in  prompt :
120116        msvcrt .putwch (c )
@@ -127,9 +123,9 @@ def win_getpass(prompt='Password: ', stream=None, *, echochar=None):
127123            raise  KeyboardInterrupt 
128124        if  c  ==  '\b ' :
129125            if  echochar  and  pw :
130-                 msvcrt .putwch ('\b ' )
131-                 msvcrt .putwch (' ' )
132-                 msvcrt .putwch ('\b ' )
126+                 msvcrt .putch ('\b ' )
127+                 msvcrt .putch (' ' )
128+                 msvcrt .putch ('\b ' )
133129            pw  =  pw [:- 1 ]
134130        else :
135131            pw  =  pw  +  c 
@@ -150,6 +146,13 @@ def fallback_getpass(prompt='Password: ', stream=None):
150146    return  _raw_input (prompt , stream )
151147
152148
149+ def  _is_ascii (echochar ):
150+     # ASCII excluding control characters 
151+     if  echochar  and  not  (32  <=  ord (echochar ) <=  127 ):
152+         return  False 
153+     return  True 
154+ 
155+ 
153156def  _raw_input (prompt = "" , stream = None , input = None ):
154157    # This doesn't save the string in the GNU readline history. 
155158    if  not  stream :
0 commit comments