utilities to get a password andor the current user name getpassprompt stream prompt for a password with echo turned off getuser get the user name from the environment or password database getpasswarning this userwarning is issued when getpass cannot prevent echoing of the password contents while reading on windows the msvcrt module will be used s piers lauder original guido van rossum windows support and cleanup gregory p smith tty support getpasswarning prompt for a password with echo turned off args prompt written on stream to ask for the input default password stream a writable file object to display the prompt defaults to the tty if no tty is available defaults to sys stderr returns the sekr3t input raises eoferror if our input tty or stdin was closed getpasswarning when we were unable to turn echo off on the input always restores terminal settings before returning always try reading and writing directly on the tty first if that fails see if stdin can be controlled rawinput succeeded the final tcsetattr failed reraise instead of leaving the terminal in an unknown state we can t control the tty or stdin give up and use normal io fallbackgetpass raises an appropriate warning clean up unused file objects before blocking prompt for password with echo off using windows getwch if sys stdin is not sys stdin return fallbackgetpassprompt stream for c in prompt msvcrt putwchc pw while 1 c msvcrt getwch if c r or c n break if c 003 raise keyboardinterrupt if c b pw pw 1 else pw pw c msvcrt putwch r msvcrt putwch n return pw def fallbackgetpassprompt password streamnone import warnings warnings warncan not control echo on the terminal getpasswarning stacklevel2 if not stream stream sys stderr printwarning password input may be echoed filestream return rawinputprompt stream def rawinputprompt streamnone inputnone this doesn t save the string in the gnu readline history if not stream stream sys stderr if not input input sys stdin prompt strprompt if prompt try stream writeprompt except unicodeencodeerror use replace error handler to get as much as possible printed prompt prompt encodestream encoding replace prompt prompt decodestream encoding stream writeprompt stream flush note the python c api calls flockfile and unlock during readline line input readline if not line raise eoferror if line1 n line line 1 return line def getuser for name in logname user lname username user os environ getname if user return user try import pwd return pwd getpwuidos getuid0 except importerror keyerror as e raise oserror no username set in the environment from e bind the name getpass to the appropriate function try import termios it s possible there is an incompatible termios from the mcmillan installer make sure we have a unixcompatible termios termios tcgetattr termios tcsetattr except importerror attributeerror try import msvcrt except importerror getpass fallbackgetpass else getpass wingetpass else getpass unixgetpass s piers lauder original guido van rossum windows support and cleanup gregory p smith tty support getpasswarning prompt for a password with echo turned off args prompt written on stream to ask for the input default password stream a writable file object to display the prompt defaults to the tty if no tty is available defaults to sys stderr returns the sekr3t input raises eoferror if our input tty or stdin was closed getpasswarning when we were unable to turn echo off on the input always restores terminal settings before returning always try reading and writing directly on the tty first if that fails see if stdin can be controlled a copy to save 3 lflags issue7208 _raw_input succeeded the final tcsetattr failed reraise instead of leaving the terminal in an unknown state we can t control the tty or stdin give up and use normal io fallback_getpass raises an appropriate warning clean up unused file objects before blocking prompt for password with echo off using windows getwch this doesn t save the string in the gnu readline history use replace error handler to get as much as possible printed note the python c api calls flockfile and unlock during readline get the username from the environment or password database first try various environment variables then the password database this works on windows as long as username is set any failure to find a username raises oserror versionchanged 3 13 previously various exceptions beyond just exc oserror were raised bind the name getpass to the appropriate function it s possible there is an incompatible termios from the mcmillan installer make sure we have a unix compatible termios
import contextlib
import io
import os
import sys

__all__ = ["getpass","getuser","GetPassWarning"]


class GetPassWarning(UserWarning): pass


def unix_getpass(prompt='Password: ', stream=None):
    
    passwd = None
    with contextlib.ExitStack() as stack:
        try:
            
            fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
            tty = io.FileIO(fd, 'w+')
            stack.enter_context(tty)
            input = io.TextIOWrapper(tty)
            stack.enter_context(input)
            if not stream:
                stream = input
        except OSError:
            
            stack.close()
            try:
                fd = sys.stdin.fileno()
            except (AttributeError, ValueError):
                fd = None
                passwd = fallback_getpass(prompt, stream)
            input = sys.stdin
            if not stream:
                stream = sys.stderr

        if fd is not None:
            try:
                old = termios.tcgetattr(fd)     
                new = old[:]
                new[3] &= ~termios.ECHO  
                tcsetattr_flags = termios.TCSAFLUSH
                if hasattr(termios, 'TCSASOFT'):
                    tcsetattr_flags |= termios.TCSASOFT
                try:
                    termios.tcsetattr(fd, tcsetattr_flags, new)
                    passwd = _raw_input(prompt, stream, input=input)
                finally:
                    termios.tcsetattr(fd, tcsetattr_flags, old)
                    stream.flush()  
            except termios.error:
                if passwd is not None:
                    raise
                
                if stream is not input:
                    
                    stack.close()
                passwd = fallback_getpass(prompt, stream)

        stream.write('\n')
        return passwd


def win_getpass(prompt='Password: ', stream=None):
    
    if sys.stdin is not sys.__stdin__:
        return fallback_getpass(prompt, stream)

    for c in prompt:
        msvcrt.putwch(c)
    pw = ""
    while 1:
        c = msvcrt.getwch()
        if c == '\r' or c == '\n':
            break
        if c == '\003':
            raise KeyboardInterrupt
        if c == '\b':
            pw = pw[:-1]
        else:
            pw = pw + c
    msvcrt.putwch('\r')
    msvcrt.putwch('\n')
    return pw


def fallback_getpass(prompt='Password: ', stream=None):
    import warnings
    warnings.warn("Can not control echo on the terminal.", GetPassWarning,
                  stacklevel=2)
    if not stream:
        stream = sys.stderr
    print("Warning: Password input may be echoed.", file=stream)
    return _raw_input(prompt, stream)


def _raw_input(prompt="", stream=None, input=None):
    
    if not stream:
        stream = sys.stderr
    if not input:
        input = sys.stdin
    prompt = str(prompt)
    if prompt:
        try:
            stream.write(prompt)
        except UnicodeEncodeError:
            
            prompt = prompt.encode(stream.encoding, 'replace')
            prompt = prompt.decode(stream.encoding)
            stream.write(prompt)
        stream.flush()
    
    line = input.readline()
    if not line:
        raise EOFError
    if line[-1] == '\n':
        line = line[:-1]
    return line


def getuser():
    

    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
        user = os.environ.get(name)
        if user:
            return user

    try:
        import pwd
        return pwd.getpwuid(os.getuid())[0]
    except (ImportError, KeyError) as e:
        raise OSError('No username set in the environment') from e



try:
    import termios
    
    
    termios.tcgetattr, termios.tcsetattr
except (ImportError, AttributeError):
    try:
        import msvcrt
    except ImportError:
        getpass = fallback_getpass
    else:
        getpass = win_getpass
else:
    getpass = unix_getpass