Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
getpass.py257 linesDownload Raw Back to Lib
1"""Utilities to get a password and/or the current user name.2 3getpass(prompt[, stream[, echo_char]]) - Prompt for a password, with echo4turned off and optional keyboard feedback.5getuser() - Get the user name from the environment or password database.6 7GetPassWarning - This UserWarning is issued when getpass() cannot prevent8                 echoing of the password contents while reading.9 10On Windows, the msvcrt module will be used.11 12"""13 14# Authors: Piers Lauder (original)15#          Guido van Rossum (Windows support and cleanup)16#          Gregory P. Smith (tty support & GetPassWarning)17 18import contextlib19import io20import os21import sys22 23__all__ = ["getpass","getuser","GetPassWarning"]24 25 26class GetPassWarning(UserWarning): pass27 28 29def unix_getpass(prompt='Password: ', stream=None, *, echo_char=None):30    """Prompt for a password, with echo turned off.31 32    Args:33      prompt: Written on stream to ask for the input.  Default: 'Password: '34      stream: A writable file object to display the prompt.  Defaults to35              the tty.  If no tty is available defaults to sys.stderr.36      echo_char: A single ASCII character to mask input (e.g., '*').37              If None, input is hidden.38    Returns:39      The seKr3t input.40    Raises:41      EOFError: If our input tty or stdin was closed.42      GetPassWarning: When we were unable to turn echo off on the input.43 44    Always restores terminal settings before returning.45    """46    _check_echo_char(echo_char)47 48    passwd = None49    with contextlib.ExitStack() as stack:50        try:51            # Always try reading and writing directly on the tty first.52            fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)53            tty = io.FileIO(fd, 'w+')54            stack.enter_context(tty)55            input = io.TextIOWrapper(tty)56            stack.enter_context(input)57            if not stream:58                stream = input59        except OSError:60            # If that fails, see if stdin can be controlled.61            stack.close()62            try:63                fd = sys.stdin.fileno()64            except (AttributeError, ValueError):65                fd = None66                passwd = fallback_getpass(prompt, stream)67            input = sys.stdin68            if not stream:69                stream = sys.stderr70 71        if fd is not None:72            try:73                old = termios.tcgetattr(fd)     # a copy to save74                new = old[:]75                new[3] &= ~termios.ECHO  # 3 == 'lflags'76                if echo_char:77                    new[3] &= ~termios.ICANON78                tcsetattr_flags = termios.TCSAFLUSH79                if hasattr(termios, 'TCSASOFT'):80                    tcsetattr_flags |= termios.TCSASOFT81                try:82                    termios.tcsetattr(fd, tcsetattr_flags, new)83                    passwd = _raw_input(prompt, stream, input=input,84                                        echo_char=echo_char)85 86                finally:87                    termios.tcsetattr(fd, tcsetattr_flags, old)88                    stream.flush()  # issue720889            except termios.error:90                if passwd is not None:91                    # _raw_input succeeded.  The final tcsetattr failed.  Reraise92                    # instead of leaving the terminal in an unknown state.93                    raise94                # We can't control the tty or stdin.  Give up and use normal IO.95                # fallback_getpass() raises an appropriate warning.96                if stream is not input:97                    # clean up unused file objects before blocking98                    stack.close()99                passwd = fallback_getpass(prompt, stream)100 101        stream.write('\n')102        return passwd103 104 105def win_getpass(prompt='Password: ', stream=None, *, echo_char=None):106    """Prompt for password with echo off, using Windows getwch()."""107    if sys.stdin is not sys.__stdin__:108        return fallback_getpass(prompt, stream)109    _check_echo_char(echo_char)110 111    for c in prompt:112        msvcrt.putwch(c)113    pw = ""114    while 1:115        c = msvcrt.getwch()116        if c == '\r' or c == '\n':117            break118        if c == '\003':119            raise KeyboardInterrupt120        if c == '\b':121            if echo_char and pw:122                msvcrt.putwch('\b')123                msvcrt.putwch(' ')124                msvcrt.putwch('\b')125            pw = pw[:-1]126        else:127            pw = pw + c128            if echo_char:129                msvcrt.putwch(echo_char)130    msvcrt.putwch('\r')131    msvcrt.putwch('\n')132    return pw133 134 135def fallback_getpass(prompt='Password: ', stream=None, *, echo_char=None):136    _check_echo_char(echo_char)137    import warnings138    warnings.warn("Can not control echo on the terminal.", GetPassWarning,139                  stacklevel=2)140    if not stream:141        stream = sys.stderr142    print("Warning: Password input may be echoed.", file=stream)143    return _raw_input(prompt, stream, echo_char=echo_char)144 145 146def _check_echo_char(echo_char):147    # Single-character ASCII excluding control characters148    if echo_char is None:149        return150    if not isinstance(echo_char, str):151        raise TypeError("'echo_char' must be a str or None, not "152                        f"{type(echo_char).__name__}")153    if not (154        len(echo_char) == 1155        and echo_char.isprintable()156        and echo_char.isascii()157    ):158        raise ValueError("'echo_char' must be a single printable ASCII "159                         f"character, got: {echo_char!r}")160 161 162def _raw_input(prompt="", stream=None, input=None, echo_char=None):163    # This doesn't save the string in the GNU readline history.164    if not stream:165        stream = sys.stderr166    if not input:167        input = sys.stdin168    prompt = str(prompt)169    if prompt:170        try:171            stream.write(prompt)172        except UnicodeEncodeError:173            # Use replace error handler to get as much as possible printed.174            prompt = prompt.encode(stream.encoding, 'replace')175            prompt = prompt.decode(stream.encoding)176            stream.write(prompt)177        stream.flush()178    # NOTE: The Python C API calls flockfile() (and unlock) during readline.179    if echo_char:180        return _readline_with_echo_char(stream, input, echo_char)181    line = input.readline()182    if not line:183        raise EOFError184    if line[-1] == '\n':185        line = line[:-1]186    return line187 188 189def _readline_with_echo_char(stream, input, echo_char):190    passwd = ""191    eof_pressed = False192    while True:193        char = input.read(1)194        if char == '\n' or char == '\r':195            break196        elif char == '\x03':197            raise KeyboardInterrupt198        elif char == '\x7f' or char == '\b':199            if passwd:200                stream.write("\b \b")201                stream.flush()202            passwd = passwd[:-1]203        elif char == '\x04':204            if eof_pressed:205                break206            else:207                eof_pressed = True208        elif char == '\x00':209            continue210        else:211            passwd += char212            stream.write(echo_char)213            stream.flush()214            eof_pressed = False215    return passwd216 217 218def getuser():219    """Get the username from the environment or password database.220 221    First try various environment variables, then the password222    database.  This works on Windows as long as USERNAME is set.223    Any failure to find a username raises OSError.224 225    .. versionchanged:: 3.13226        Previously, various exceptions beyond just :exc:`OSError`227        were raised.228    """229 230    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):231        user = os.environ.get(name)232        if user:233            return user234 235    try:236        import pwd237        return pwd.getpwuid(os.getuid())[0]238    except (ImportError, KeyError) as e:239        raise OSError('No username set in the environment') from e240 241 242# Bind the name getpass to the appropriate function243try:244    import termios245    # it's possible there is an incompatible termios from the246    # McMillan Installer, make sure we have a UNIX-compatible termios247    termios.tcgetattr, termios.tcsetattr248except (ImportError, AttributeError):249    try:250        import msvcrt251    except ImportError:252        getpass = fallback_getpass253    else:254        getpass = win_getpass255else:256    getpass = unix_getpass257 
codekingpro/portable-devtools · Team Ai