Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyring hook does not work #4569

Closed
toyg opened this issue Dec 8, 2019 · 7 comments · Fixed by #5245
Closed

Keyring hook does not work #4569

toyg opened this issue Dec 8, 2019 · 7 comments · Fixed by #5245

Comments

@toyg
Copy link

toyg commented Dec 8, 2019

Environment:

  • MacOS 10.14.6
  • Python 3.7.4 (from homebrew)
  • PyInstaller==4.0.dev0+9dd34bdfba
  • keyring==20.0.0

Configure the virtualenv with keyring and pyinstaller

python3 -m venv venv
source ./venv/bin/activate
pip install keyring 
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

Have a simple file called test.py:

import keyring
print(keyring.get_password('test','test'))

This prints "None" when executed.

Package it and run:

pyinstaller --clean --log-level DEBUG -d all --noupx -y test.py

Build log: https://pastebin.com/raw/VeEtsZge
Content of build and dist: https://www.dropbox.com/s/79s7fe8dpkij717/pyinstbug.tgz?dl=1

Result:

$> ./dist/test/test

Traceback (most recent call last):
  File "test.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/Users/toyg/Dev/tmp/venv/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "keyring/__init__.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/Users/toyg/Dev/tmp/venv/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "keyring/core.py", line 192, in <module>
  File "keyring/core.py", line 96, in init_backend
  File "keyring/util/__init__.py", line 22, in wrapper
  File "keyring/backend.py", line 216, in get_all_keyring
  File "keyring/backend.py", line 199, in _load_plugins
KeyError: 'keyring.backends'
[55646] Failed to execute script test

From the various logs it looks like keyring is somewhat detected, but then it's not actually fully imported at runtime. I have tried explicitly setting all keyring submodules as hiddenimports, it does not make any difference.

@anasofiapaixao
Copy link

For reference for anyone who like me landed here out of the blue, @msk849 has submitted a PR for this issue, and until it makes its way to master to keyring release to pyinstaller to pyinstaller release to pypi, ...... there's a horrible workaround to get it to work right now that in theory you should not do, which is altering the library yourself with the contents of their PR directly in your own site-packages python package cache.

Open site-packages/keyring-x.x.x-pyx.x.egg/keyring/backend.py and replace

    entry_points = metadata.entry_points()['keyring.backends']

with

    try: entry_points = metadata.entry_points()['keyring.backends']
    except Exception:
        entry_points = (
            metadata.EntryPoint(name='KWallet',value='keyring.backends.kwallet',group='keyring.backends'),
            metadata.EntryPoint(name='SecretService',value='keyring.backends.SecretService',group='keyring.backends'),
            metadata.EntryPoint(name='Windows',value='keyring.backends.Windows',group='keyring.backends'),
            metadata.EntryPoint(name='chainer',value='keyring.backends.chainer',group='keyring.backends'),
            metadata.EntryPoint(name='macOS',value='keyring.backends.OS_X',group='keyring.backends'))

which should be around line 199.

Clear pyinstaler build and dist cache, rerun pyinstaller, and the error should be gone.

@arossert
Copy link
Contributor

arossert commented Dec 17, 2019

@anasofiapaixao thanks for the update, I'm facing the same issue.
Is there anything that can be done in a PyInstaller hook to overcome this issue?
My issue is that I'm currently using Python2 and even if this fix will find its way to master it will only be for Python3 (18.0.1 is the last release that supports Python2).

My current workaround without changing the keyring code is to add this code after import keyring:

if hasattr(sys, "frozen"):
    if sys.platform.startswith("win"):
        import keyring.backends.Windows
        keyring.set_keyring(keyring.backends.Windows.WinVaultKeyring())
    elif sys.platform.startswith("darwin"):
        import keyring.backends.OS_X
        keyring.set_keyring(keyring.backends.OS_X.Keyring())

@rxvt
Copy link

rxvt commented Jan 15, 2020

Doesn't look like that Keyring PR is going to be merged, maintainers have mentioned that PyInstaller should supply the metadata so that other packages should be able to follow these instructions to discover the metadata.

@MAKOMO
Copy link

MAKOMO commented Feb 10, 2020

Newer Keyrings also fail to work in apps bundled with py2app. Can't find any workaround despite modifying the keyring lib. Monkey patching seems not to be possible.  So I downgrade to keyring==19.2.0 again. Bad.

slokhorst added a commit to slokhorst/gajim that referenced this issue Apr 11, 2020
@DK26
Copy link

DK26 commented Jun 29, 2020

BTW, stumbling upon this error myself while I'm also learning the Rust programming language (A systems language like C\C++), I've made an attempt to port Rust's own most popular keyring library to Python and it seems to be working fine with PyInstaller.
It's cross-platform as well but I've mainly tested it on windows.

pip install rskeyring

rokm added a commit to rokm/pyinstaller that referenced this issue Oct 12, 2020
Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata. Fixes pyinstaller#4569.
rokm added a commit to rokm/pyinstaller that referenced this issue Oct 13, 2020
Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata. Fixes pyinstaller#4569.
rokm added a commit to rokm/pyinstaller that referenced this issue Oct 20, 2020
Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata, which is needed for backend discovery at run-time.

Fixes pyinstaller#4569.
@anatolio-deb
Copy link

BTW, stumbling upon this error myself while I'm also learning the Rust programming language (A systems language like C\C++), I've made an attempt to port Rust's own most popular keyring library to Python and it seems to be working fine with PyInstaller.
It's cross-platform as well but I've mainly tested it on windows.

pip install rskeyring

Thank you for your workaround. Does it support Linux platforms? Secret Service or KWallet?

@DK26
Copy link

DK26 commented Dec 5, 2020

BTW, stumbling upon this error myself while I'm also learning the Rust programming language (A systems language like C\C++), I've made an attempt to port Rust's own most popular keyring library to Python and it seems to be working fine with PyInstaller.
It's cross-platform as well but I've mainly tested it on windows.

pip install rskeyring

Thank you for your workaround. Does it support Linux platforms? Secret Service or KWallet?

Since it was created mainly as a workaround for PyInstaller to create windows EXE, it was not well tested on Linux. It does compile on Linux and the underlying keyring does support Linux. I think it uses Secret Service. You may try

Edit: I have created this with a very fundemental understanding of the Rust language. As I'm getting to learn the langauge deeper, I will eventually create a complete bind supporting all features. For now, I'm open to PRs

rokm added a commit to rokm/pyinstaller that referenced this issue Dec 10, 2020
Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata, which is needed for backend discovery at run-time.

Fixes pyinstaller#4569.
Legorooj pushed a commit that referenced this issue Dec 21, 2020
* expand test_keyring

Instead instead of just importing the keyring module, try to get a
password from it. Doing so will raise a keyring.errors.NoKeyringError
if backends are not properly collected.

This is skipped on Linux, due to the SecretStorage backend requiring an active D-BUS session
and initialized keyring, and may need to unlock the keyring via
UI prompt. These conditions are difficult to satisfy in automated
test environments, so just skip the test on linux.

* update keyring hook

Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata, which is needed for backend discovery at run-time.

Fixes #4569.
3wnbr1 pushed a commit to 3wnbr1/pyinstaller that referenced this issue Jan 4, 2021
* expand test_keyring

Instead instead of just importing the keyring module, try to get a
password from it. Doing so will raise a keyring.errors.NoKeyringError
if backends are not properly collected.

This is skipped on Linux, due to the SecretStorage backend requiring an active D-BUS session
and initialized keyring, and may need to unlock the keyring via
UI prompt. These conditions are difficult to satisfy in automated
test environments, so just skip the test on linux.

* update keyring hook

Turn the existing hook into a top-level hook, i.e., rename it
from  hook-keyring.backends.py to hook-keyring.py.

In addition to collecting the backends, also copy the package's
metadata, which is needed for backend discovery at run-time.

Fixes pyinstaller#4569.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants