getpassの引数prompt
Python2.xだとgetpass()の引数promptに指定した文字列が化ける:
>>> import getpass >>> from getpass import getpass >>> pssword = getpass('パスワードを入力してください: ') pX[hðü͵ľ³¢:
ソースを見てみると、
def win_getpass(prompt='Password: ', stream=None): """Prompt for password with echo off, using Windows getch().""" if sys.stdin is not sys.__stdin__: return fallback_getpass(prompt, stream) import msvcrt for c in prompt: msvcrt.putch(c) # 以下略
1バイトづつputch()してやがる。どうりで化けるはずだ。Pythonは、時々こういうデリカシーに欠けるコードが標準ライブラリにも混ざっているからウンザリする。
msvcrt.putch()の実装を見ると、
static PyObject * msvcrt_putch(PyObject *self, PyObject *args) { char ch; if (!PyArg_ParseTuple(args, "c:putch", &ch)) return NULL; _putch(ch); Py_INCREF(Py_None); return Py_None; }
最終的にはVCランタイムの_putch()が呼ばれるようだ。
ここで簡単な実験をしてみる。テーマは「_putch()とputchar()はどこが違うのだろうか」だ。
#include <stdio.h> #include <conio.h> int main() { char *str = "日本語の文字列\n"; fputs("putchar: ", stdout); for (char *p = str; *p; p ++) { putchar(*p); } fputs("_putch: ", stdout); for (char *q = str; *q; q ++) { _putch(*q); } return 0; } // 結果 // putchar: 日本語の文字列 // _putch: “ú–{Œê‚Ì•¶Žš—ñ
1バイトづつ出力しているにもかかわらず、putchar()の方は化けていない! ランタイムのソースが見れないので原因はよくわからないが、おそらく_putch()の方は、
These functions write the character c directly,
http://msdn.microsoft.com/en-us/library/azb6c04e.aspx
なので化けてしまうんだと思う。
ちなみに、Python3.xではputwch()を使うようになっているので化けない。