We define this function:
>>> def ask(): ... import getpass ... a = getpass.getpass("Tell me a secret: ") ... b = raw_input("Tell me a non-secret: ") ... print 'Secret:', repr(a) ... print 'Non-secret:', repr(b) ...On most platforms, this happens:
>>> ask() Tell me a secret: # enters 'spam' Tell me a non-secret: eggs Secret: 'spam' Non-secret: 'eggs' >>>However, on some Windows platforms, this happens:
>>> ask() Tell me a secret: # enters 'spam' Tell me a non-secret: # didn't get a chance to enter anything Secret: 'spam' Non-secret: '' >>>This is down to a mixture of sys.stdin and the msvcrt module being used together (with Microsoft's implementation of console I/O being inconsistent between versions of Windows). Click here or here for more information.
How do I use it in my code?
Well, you need to decide what method you want to use first. But, for example, if you want to use the platform based method, you simply do this:
>>> import getpassfix >>> getpassfix.install_platform() >>>You simply run those lines of code before you use the getpass module.
gpftest.py is a short script which allows people to quickly find out if their platform is affected by the bug or not. It was mainly designed so that it would be quick and easy for people to provide feedback without having to do much at all.
If you want to use the getpassfix module in your code, you can just keep that module. You can optionally keep the platform module around, getpassfix will work whether it's there or not (though you have more options available to you if it is there). The gpftest module can be deleted, it's not used by the getpassfix module at all.
Why can't the fix be put in the getpass module? Why does it exist in a separate module?
Because the bug only occurs on certain versions of Windows. It's actually a Windows bug (of sorts), and this module provides a hack to make it work correctly on affected platforms.
So how does this module fix the problem?
It provides several mechanisms for getting round the bug. Unfortunately, there is no one *proper* way of getting around this bug, so this module provides different ways of handling the bug.
So what ways does this module fix the bug?
There are several different ways to tackle the problem.
The main advantage of this approach is that you will always get the data you want. The disadvantage is that it looks unpleasant on affected systems.
The main advantage of this approach is that a prompt will only ever be repeated once. The disadvantage is that if a user presses enter without entering data on purpose, it is assumed the platform is affected when it is not, and so further uses of the getpass module will result in odd and unexpected behaviour.
The main advantage is that is more likely to determine whether the platform is affected or not than the repeat-detect approach. The disadvantage is that user input can still be mistaken as an indication of the bug, and if a raw_input call on an affected platform takes longer than a specific amount of time (perhaps when there's high processor usage), a platform may be considered unaffected when it isn't.
The main advantage of this is that it's probably the cleanest way of handling with the bug. The disadvantage, however, is that there currently isn't a full list of platforms which are known to be (un)affected.
What version of Python do I need?
It should work on Python 1.5.2 and onwards.
What are these other modules bundled with getpassfix.py?
platform.py is required by the test module to determine which platform you're running. It's also there so that the install_platform function is available.Need any testers?
Yes please. :) If you are running any version of Windows, simply download the latest release, extract the files into a directory and run gpftest.py. It will only take a few seconds to do, and is fairly painless.
The more feedback I get, then the more useful the platform approach will be. My personal guess is that all Windows 95, 98 and ME versions are affected, but I need people to test it to determine what is affected.
The module has been tested, so I'm not expecting anything to fail, but please let me know if it does.
I'm also soliciting any feedback on whether people would prefer the install_platform function to be either undefined when the platform module is unavailable (as it currently is), or whether install_platform should be "NotImplemented". That way, you could write code like:
>>> if getpassfix.install_platform is NotImplemented:
... getpassfix.install_timed_repeat(0.1)
... else:
... getpassfix.install_platform()
What's with the documentation?
Think it's crap? Well it is. But it is slowly improving. You can now at least look at the API documentation (generated by PyDoc). I'm still learning my way around the various Python documentation utilities, so bear with me. :)
"This doesn't work!" or "This could be better!"
If there's a bug, or you have any improvements, please mail me.