jaraco / keyring

MIT License
1.25k stars 159 forks source link

Importing keyring takes long time on WSL2 #531

Closed oldclock closed 3 years ago

oldclock commented 3 years ago

Describe the bug When import keyring on WSL2, it hangs for long time (about 6-8 minutes on my PC) Note that this symptom only happens when DISPLAY variable is set in WSL2 but no X-server is running on Windows. If ctrl+c then log shows that the issue is related to dbus:

^CTraceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/keyring/__init__.py", line 3, in <module>
    from .core import (
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 189, in <module>
    init_backend()
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 93, in init_backend
    keyrings = filter(limit, backend.get_all_keyring())
  File "/usr/lib/python3/dist-packages/keyring/util/__init__.py", line 21, in wrapper
    func.always_returns = func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/keyring/backend.py", line 210, in get_all_keyring
    return list(rings)
  File "/usr/lib/python3/dist-packages/keyring/util/__init__.py", line 31, in suppress_exceptions
    for callable in callables:
  File "/usr/lib/python3/dist-packages/keyring/util/properties.py", line 26, in __get__
    return self.fget.__get__(None, owner)()
  File "/usr/lib/python3/dist-packages/keyring/backend.py", line 67, in viable
    cls.priority
  File "/usr/lib/python3/dist-packages/keyring/util/properties.py", line 26, in __get__
    return self.fget.__get__(None, owner)()
  File "/usr/lib/python3/dist-packages/keyring/backends/SecretService.py", line 34, in priority
    bus = secretstorage.dbus_init()
  File "/usr/lib/python3/dist-packages/secretstorage/__init__.py", line 47, in dbus_init
    return dbus.SessionBus()
  File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 212, in __new__
    return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
  File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 102, in __new__
    bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
  File "/usr/lib/python3/dist-packages/dbus/bus.py", line 124, in __new__
    bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
  File "/usr/lib/python3/dist-packages/dbus/exceptions.py", line 47, in __init__
    def __init__(self, *args, **kwargs):
KeyboardInterrupt

There are two work-arounds I have found:

  1. unset DISPLAY or
  2. Launch VcXsrv on Windows

Any of them can work-around this symptom.

To Reproduce Steps to reproduce the behavior: Enter the following commands on WSL2

$ date; python3 -c 'import keyring'; date
Mon Sep 27 15:30:55 CST 2021
Mon Sep 27 15:37:35 CST 2021

Expected behavior It should not take long time.

Environment

Additional context Please refer to yt-dlp/yt-dlp#551 for more discussion history.

mitya57 commented 3 years ago

Please try keyring ≥ 21.6.0 where #480 was merged.

oldclock commented 3 years ago

After python -m pip install --upgrade keyring to latest version, the issue is fixed. Thanks so much !!

mbway commented 3 years ago

doesn't that just hide/delay the symptoms though? I'm not sure about the specific implementation but wouldn't a keyring service like GNOME keyring be available in Ubuntu in WSL? In which case attempting to read from it would cause either hanging or crashes as observed in https://github.com/yt-dlp/yt-dlp/issues/551

oldclock commented 3 years ago

Yes, the symptom is delayed. import keyring do not hang now, but keyring --list-backends command still hang for long time because it cannot find SecretService. Should I re-open this issue ? I have already got the answer I need, so it's up to repository owner's decision.

mitya57 commented 3 years ago

What backend are you going to use on WSL2? If it's SecretService backend, then you need to set up the server, for example as described in README: https://github.com/jaraco/keyring/blob/main/README.rst#using-keyring-on-headless-linux-systems

If it is a different backend, I suggest you to specify it explicitly in the configuration file: https://github.com/jaraco/keyring/blob/main/README.rst#configuring

mbway commented 3 years ago

so it sounds like for a user who doesn't know about keyring (and therefore has not configured it) and wants to use a tool which uses keyring (like yt-dlp) then either:

So as a mitigation, yt-dlp can import keyring on demand and hopefully not too many users will require keyring access in WSL, but for those that do, would it be possible to have better detection of this problem on the keyring side so that users are more informed about the problem rather than assuming that the tool they are using has a problem?

For example, perhaps if WSL is detected (using this), then set a short dbus timeout if possible to something like 5 seconds and catch dbus.exceptions.DBusException and re-raise as something more informative like BackendConfigurationError('no keyring backend found at ... Please refer to https://github.com/jaraco/keyring/blob/main/README.rst#using-keyring-on-headless-linux-systems for configuring keyring in WSL') I'm not sure if that's a good solution but just an idea.