otus
otus

Reputation: 5732

Using getpass with python 2 and 3 compatibility

I know that getpass returns an unicode string in Python 3 and some kind of str in Python 2. However, I'm not sure about the encoding on Python 2.

How can I transform the value it returns to an UTF-8 encoded bytes object in a way that works in both Python 2 and 3?

(I don't use six and am trying to write code that just works on both, rather than iffing on the version number.)

Upvotes: 2

Views: 1057

Answers (2)

Anand S Kumar
Anand S Kumar

Reputation: 90979

I would follow the EAFP policy in this case. Try to decode() and encode() the string assuming its a python 2 environment, and expect TypeError , and if you get the TypeError , just do encode() . Example -

import sys
import getpass

s = getpass.getpass()

try:
    u = s.decode(sys.stdin.encoding).encode('UTF-8')
except TypeError:
    u = s.encode('UTF-8')

Upvotes: 2

PM 2Ring
PM 2Ring

Reputation: 55489

In Python 2, getpass() returns a normal Python 2 string, i.e. a byte string. It uses the terminal's encoding, so if the terminal is set to use UTF-8 you don't need to do anything - the string it returns will already be a UTF-8 encoded byte string. But to be robust, you can do this:

import sys
from getpass import getpass

p = getpass()
if isinstance(p, bytes):
    p = p.decode(sys.stdin.encoding)
p = p.encode('utf-8') # :D

We use if isinstance(p, bytes): to stop Python 3 from touching the string returned by getpass(), and then we encode the Unicode to UTF-8

Upvotes: 3

Related Questions