Issue #96 resolved

default backend sort order is not deterministic

Anonymous created an issue

the default backend is chosen using the following code:

    # if the user doesn't specify a keyring, we apply a default one
    if keyring is None:

        keyrings = backend.get_all_keyring()
        # rank according to the supported result
        keyrings.sort(key = lambda x: -x.supported())
        # get the most recommended one
        keyring = keyrings[0]

this isn't deterministic enough because subsequent runs may return a different value if <backend>.supported() is the same value for multiple backends.

for example, on ubuntu, if i run the following a bunch of times:

import keyring
print keyring.get_keyring()

sometimes i'll get keyring.backends.Gnome.Keyring and sometimes i'll get keyring.backends.file.PlaintextKeyring.

Comments (3)

  1. Johannes Erdfelt

    I ran into this problem recently as well.

    keyring uses a set() internally to track the classes. hash() will then use the memory location creating a non-deterministic order when it is later converted to a list(). Since Python's sort() method is stable and the sort key could be equal among backends, this leads to the behavior being seen.

    This is a really frustrating problem since seemingly unrelated changes to my program were causing the backend to change and result in different passwords being returned (mostly the password I was looking for, or None).

    I spent days being bewildered by this behavior.

  2. Johannes Erdfelt

    As a followup, a simple workaround is to create an appropriate keyringrc.cfg file with the desired backend:

    [backend]
    default-keyring = keyring.backend.UncryptedFileKeyring
    
  3. Jason R. Coombs

    Keyring 2.0 addresses this issue by requiring each keyring to determine its priority in a given environment, so the order of keyrings should now be deterministic. Please comment or re-open if you find that's not the case.

  4. Log in to comment