Note: If you just want to help out with testing the program without reading about it, click here.

What is getpassfix.py?

getpassfix.py is a
Python module which addresses an issue using the getpass module on certain Windows platforms. Here's an example illustrating the problem:

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.

Where can I download it?

You can get it from
here. Make sure you download the latest version.

Do I need to use getpassfix.py?

You only need to consider this module if you want to use the getpass module on a Windows platform.

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.

  • repeat: This provides a replacement version of raw_input which repeats the prompt if nothing is received in the initial prompt.
    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.

  • repeat-detect: As above, but it will only repeat a raw_input prompt once. When raw_input is invoked after getpass, it sees whether the user has given any information. If not, it installs the 'hacked' version of getpass, and repeats the prompt.
    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.

  • timed-repeat: Similar to the repeat-detect approach, except it also times how long the user input takes. If no data was given, and the response was given under a certain time, it is assumed that the platform is affected. This allows the user to provide a blank response on an unaffected platform, without it being assumed that the platform suffers from the bug.
    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.

  • msvcrt: This approach replaces raw_input with a version which uses the msvcrt library (which is the same library that the Windows implementation of getpass uses). The main advantage of this approach is that all Windows machines will work correctly and will not show signs of the bug, the disadvantage is that you may experience broken behaviour for anything which tries to use sys.stdin.

  • hack: A very straight forward approach. If you use this, it will install the hacked version of getpass, whether it is an affected system or not. The advantages and disadvantages should be clear on this one. :)

  • platform: This option is only available if you have Marc-André Lemburg's platform module installed. An internal list is kept of all platforms known to be affected (and unaffected). If you use this approach, it determines what version of Windows you are running, and if it's known to be affected. If the platform is affected, it installs the hacked version of getpass.
    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.

    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.

    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.
    SourceForge.net Logo