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 prevent some package uninstall #8443

Closed
pierreluctg opened this issue Jun 15, 2020 · 19 comments
Closed

Keyring prevent some package uninstall #8443

pierreluctg opened this issue Jun 15, 2020 · 19 comments
Assignees
Labels
C: keyring Related to pip's keyring integration resolution: deferred till PR Further discussion will happen when a PR is made type: feature request Request for a new feature

Comments

@pierreluctg
Copy link

Environment

  • pip version: 20.1.1
  • Python version: 3.7
  • OS: Windows

Description

Optional pip keyring support is cause some resource lock while uninstalling cffi

Expected behavior

pip should not lock any resources and allow clean uninstall of cffi

How to Reproduce

# Install keyring to enable keyring feature in pip
pip install keyring -q
# install cffi
pip install cffi -q
# uninstall cffi
pip uninstall cffi -y

Output

Found existing installation: cffi 1.14.0
Uninstalling cffi-1.14.0:
  Successfully uninstalled cffi-1.14.0
ERROR: Exception:
Traceback (most recent call last):
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\cli\base_command.py", line 188, in _main
    status = self.run(options, args)
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\commands\uninstall.py", line 89, in run
    uninstall_pathset.commit()
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\req\req_uninstall.py", line 450, in commit
    self._moved_paths.commit()
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\req\req_uninstall.py", line 290, in commit
    save_dir.cleanup()
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\utils\temp_dir.py", line 196, in cleanup
    rmtree(self._path)
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_vendor\retrying.py", line 49, in wrapped_f
    return Retrying(*dargs, **dkw).call(f, *args, **kw)
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_vendor\retrying.py", line 212, in call
    raise attempt.get()
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_vendor\retrying.py", line 247, in get
    six.reraise(self.value[0], self.value[1], self.value[2])
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_vendor\six.py", line 703, in reraise
    raise value
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_vendor\retrying.py", line 200, in call
    attempt = Attempt(fn(*args, **kwargs), attempt_number, False)
  File "c:\projects\.venv_pip_keyring\lib\site-packages\pip\_internal\utils\misc.py", line 136, in rmtree
    onerror=rmtree_errorhandler)
  File "c:\python37-32\lib\shutil.py", line 516, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "c:\python37-32\lib\shutil.py", line 400, in _rmtree_unsafe
    onerror(os.unlink, fullname, sys.exc_info())
  File "c:\python37-32\lib\shutil.py", line 398, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\*****\\AppData\\Local\\Temp\\pip-uninstall-l1br_4h0\\_cffi_backend.cp37-win32.pyd'

To show that pip keyring feature is in cause here, setting the keyring backend to null (set PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring) is preventing this issue.

@triage-new-issues triage-new-issues bot added the S: needs triage Issues/PRs that need to be triaged label Jun 15, 2020
@pierreluctg
Copy link
Author

@pradyunsg what do I need to do to get this triaged?

@deveshks
Copy link
Contributor

deveshks commented Jun 28, 2020

May I also suggest filing an issue with keyring on this?

I also found some closed issues related to cffi and Access is denied which weren't related to keyring.

Also I couldn't reproduce this issue in OSX Catalina 10.15.4

$ pip --version
pip 20.1.1 from ...... (python 3.8)

$ python --version
Python 3.8.2

$ pip install keyring
Collecting keyring
  Using cached keyring-21.2.1-py3-none-any.whl (31 kB)
Installing collected packages: keyring
Successfully installed keyring-21.2.1

$ pip install cffi
Collecting cffi
  Using cached cffi-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl (175 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: pycparser, cffi
Successfully installed cffi-1.14.0 pycparser-2.20

$ pip uninstall cffi -y
Found existing installation: cffi 1.14.0
Uninstalling cffi-1.14.0:
  Successfully uninstalled cffi-1.14.0

@pfmoore pfmoore added the type: bug A confirmed bug or unintended behavior label Jun 28, 2020
@triage-new-issues triage-new-issues bot removed the S: needs triage Issues/PRs that need to be triaged label Jun 28, 2020
@pfmoore
Copy link
Member

pfmoore commented Jun 28, 2020

Installers like pip have very strict constraints on what they can do. One of the reasons we vendor all of our dependencies is so that we don't typically hit issues like this. Keyring is an exception, being an "optional" dependency, but in this case the issue is that it doesn't conform to the restrictions that "being part of pip" impose (specifically, it depends on an external C extension.

I don't think we can expect keyring to work under the limitations needed to make it safe for pip to use, unfortunately.

One thing that might improve this issue is for pip to lazily import keyring only when needed. This would at least avoid the problem when keyring isn't actually used by pip (although there will still be potential issues - users who need keyring to access an index won't be able to upgrade cfffi without disabling keyring, for example).

The issue is Windows-only because Windows won't allow you to delete a shared library that's loaded in a running process. Unix will allow you to do this, and so uninstalling cffi while using it is OK on Unix but not on Windows.

@pierreluctg
Copy link
Author

pierreluctg commented Jun 29, 2020

@deveshks, the issue is not in keyring it's in pip and was introduced by #5952.
The issue may be on windows only, you will only hit the issue when the keyring backend uses cffi.

Uninstalling a package using pip should not make use of any external (not in pip vendor). This is causing the issue that we have here.

@pierreluctg
Copy link
Author

Thank you @pfmoore, yes, lazily importing keyring only when needed will fix the uninstall issue. But potentially still cause an issue on updates.

However, for the update case, it will be probably be easier to diagnose (for a user that uses keyring to store pip related credentials) versus a user that have no idea keyring is installed (potentially via a dependency) and hits this issues...

@pfmoore
Copy link
Member

pfmoore commented Jun 29, 2020

it's in pip and was introduced by #5952

It's possible that some additional thought is needed around how keyring support is activated. I didn't get involved in the discussions at the time so I can't say whether a manual opt-in (beyond simply "having keyring installed") was considered and/or found unacceptable.

@pierreluctg
Copy link
Author

Can any of the Member look at this issue and provide a fix?

@pfmoore
Copy link
Member

pfmoore commented Jul 20, 2020

Please understand that keyring support is optional and the reason it's not built in is precisely because it can cause issues like this. There's no "fix" needed here. If you want to uninstall a package that keyring relies on, you may have to disable or remove keyring while you do so.

Repeatedly insisting that someone else fix this issue isn't going to alter that fact.

I've offered some suggestions as to how someone could try to reduce the number of times this is an issue, but I'm certainly not offering to do that work. And on reflection, I no longer consider the current behaviour a pip bug.

As has been already suggested, another approach you could take is to raise an issue with keyring, saying that its use of C extensions causes this problem when it gets used in pip. But I doubt the keyring maintainers are likely to remove all C dependencies just for this very niche problem.

I'm going to mark this issue as a feature request, and "Deferred till PR", to reflect the fact that there doesn't appear to be much more to say here until someone (quite likely not one of the pip committers, but a user who is sufficiently interested in improving the behaviour in this situation to work on it) submits a PR that can act as a starting point for further discussion.

I'm happy if any of the other @pypa/pip-committers want to pick this up and handle it differently, but I will leave the discussion at this point.

@pfmoore pfmoore added resolution: deferred till PR Further discussion will happen when a PR is made type: feature request Request for a new feature and removed type: bug A confirmed bug or unintended behavior labels Jul 20, 2020
@pierreluctg
Copy link
Author

@pfmoore I fully agree that keyring support should be optional. Even more when you try to use pip uninstall, since you do not need any secret to be retrieved.

However, currently because keyring and it's dependencies are not vendored like most pip dependencies. This is preventing users to uninstalling cffi, upgrading cffi or installing any package that need a different version of cffi.

I am sure there are good reasons why keyring is not vendored (some are mentioned in #5952).

The issue is not in keyring, the issue was clearly introduce by #5952.

This is not how a optional feature should work.

@jaraco
Copy link
Member

jaraco commented Dec 22, 2020

The latest release of keyring 21.6.0 is less aggressive about initializing the keyring backend on import. It's possible this change will fix this reported issue. Please test and let me know.

@jaraco
Copy link
Member

jaraco commented Dec 23, 2020

Looking at the code in pywin32-ctypes, it seems that it may be possible for pip to force the fallback to ctypes with something like:

with contextlib.suppress(Exception):
    importlib.import_module('win32ctypes.core')._backend = 'ctypes'

@nmz787
Copy link

nmz787 commented Feb 23, 2021

However, for the update case, it will be probably be easier to diagnose (for a user that uses keyring to store pip related credentials) versus a user that have no idea keyring is installed (potentially via a dependency) and hits this issues...

I've been diagnosing this for hours and just found this post... pip.ini doesn't seem to be working for me on Windows to store my password for a local pypi repo... so I'm sort of confused on how to move forward.

@ovianao
Copy link

ovianao commented Feb 24, 2021

Just an update that tried 21.6.0, and 22.0.1 versions of keyring. Issue still there, and reproducible.

@jaraco
Copy link
Member

jaraco commented Feb 24, 2021

The latest release of keyring 21.6.0 is less aggressive about initializing the keyring backend on import. It's possible this change will fix this reported issue. Please test and let me know.

Just an update that tried 21.6.0, and 22.0.1 versions of keyring. Issue still there, and reproducible.

I was hoping that by late-binding the lookup of backends that pip's use of keyring would not come into play for these use-cases, but it seems that's not the case.

I tried to find out where keyring behavior is being triggered, but wasn't able to trigger it with an install/uninstall operation:

pip bugfix/8443-block-cffi $ git diff
diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py
index bd54a5cba..d6565e38d 100644
--- a/src/pip/_internal/network/auth.py
+++ b/src/pip/_internal/network/auth.py
@@ -37,6 +37,7 @@ except Exception as exc:
 
 
 def get_keyring_auth(url, username):
+    breakpoint()
     # type: (Optional[str], Optional[str]) -> Optional[AuthInfo]
     """Return the tuple auth for a given url from keyring."""
     global keyring
pip bugfix/8443-block-cffi $ pip-run -q . keyring -- -m pip-run cffi -- -m pip uninstall cffi
Collecting cffi
  Using cached cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl (177 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: pycparser, cffi
Successfully installed cffi-1.14.5 pycparser-2.20
Found existing installation: cffi 1.14.5
Uninstalling cffi-1.14.5:
  Would remove:
    /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-qd068zwt/_cffi_backend.cpython-39-darwin.so
    /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-qd068zwt/cffi-1.14.5.dist-info/*
    /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-qd068zwt/cffi/*
Proceed (y/n)? y
  Successfully uninstalled cffi-1.14.5

As you can see, I added a breakpoint at auth.py:40 and then with that copy of pip and with keyring installed, installed CFFI and then uninstalled it, all without triggering the keyring behavior. I need to do more testing on Windows.

@jaraco jaraco self-assigned this Feb 24, 2021
@jaraco
Copy link
Member

jaraco commented Feb 24, 2021

So, using that technique on Windows, I'm able to replicate the issue with keyring<21.6:

PS C:\> pip-run -q "keyring<21.6" -- -m pip-run cffi -- -m pip uninstall -y cffi
Collecting cffi
  Using cached cffi-1.14.5-cp39-cp39-win_amd64.whl (179 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: pycparser, cffi
Successfully installed cffi-1.14.5 pycparser-2.20
Found existing installation: cffi 1.14.5
Uninstalling cffi-1.14.5:
  Successfully uninstalled cffi-1.14.5
ERROR: Exception:
Traceback (most recent call last):
  File "c:\python39\lib\site-packages\pip\_internal\cli\base_command.py", line 189, in _main
    status = self.run(options, args)
  File "c:\python39\lib\site-packages\pip\_internal\commands\uninstall.py", line 91, in run
    uninstall_pathset.commit()
  File "c:\python39\lib\site-packages\pip\_internal\req\req_uninstall.py", line 456, in commit
    self._moved_paths.commit()
  File "c:\python39\lib\site-packages\pip\_internal\req\req_uninstall.py", line 296, in commit
    save_dir.cleanup()
  File "c:\python39\lib\site-packages\pip\_internal\utils\temp_dir.py", line 205, in cleanup
    rmtree(ensure_text(self._path))
  File "c:\python39\lib\site-packages\pip\_vendor\retrying.py", line 49, in wrapped_f
    return Retrying(*dargs, **dkw).call(f, *args, **kw)
  File "c:\python39\lib\site-packages\pip\_vendor\retrying.py", line 212, in call
    raise attempt.get()
  File "c:\python39\lib\site-packages\pip\_vendor\retrying.py", line 247, in get
    six.reraise(self.value[0], self.value[1], self.value[2])
  File "c:\python39\lib\site-packages\pip\_vendor\six.py", line 703, in reraise
    raise value
  File "c:\python39\lib\site-packages\pip\_vendor\retrying.py", line 200, in call
    attempt = Attempt(fn(*args, **kwargs), attempt_number, False)
  File "c:\python39\lib\site-packages\pip\_internal\utils\misc.py", line 129, in rmtree
    shutil.rmtree(dir, ignore_errors=ignore_errors,
  File "c:\python39\lib\shutil.py", line 740, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "c:\python39\lib\shutil.py", line 618, in _rmtree_unsafe
    onerror(os.unlink, fullname, sys.exc_info())
  File "c:\python39\lib\shutil.py", line 616, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp\\pip-uninstall-o23rww4x\\_cffi_backend.cp39-win_amd64.pyd'

And the issue goes away with keyring 21.6:

PS C:\> pip-run -q "keyring==21.6" -- -m pip-run cffi -- -m pip uninstall -y cffi
Collecting cffi
  Using cached cffi-1.14.5-cp39-cp39-win_amd64.whl (179 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: pycparser, cffi
Successfully installed cffi-1.14.5 pycparser-2.20
Found existing installation: cffi 1.14.5
Uninstalling cffi-1.14.5:
  Successfully uninstalled cffi-1.14.5

So there seems to be another factor at play if you're still encountering the issue after keyring 21.6. Is there something about your environment that's causing the 'auth' behavior of pip to be invoked?

@ovianao
Copy link

ovianao commented Feb 24, 2021

pip 20.3.1, keyring 21.6.0, cffi 1.13.2
If it helps, here's my stack of when cffi is being initialized by pip; which based on observation is effectively when _cffi_backend.cp37-win32.pyd gets locked:

  c:\python36\lib\runpy.py(193)_run_module_as_main()
-> "__main__", mod_spec)
  c:\python36\lib\runpy.py(85)_run_code()
-> exec(code, run_globals)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\__main__.py(26)<module>()
-> sys.exit(_main())
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\cli\main.py(75)main()
-> return command.main(cmd_args)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\cli\base_command.py(117)main()
-> return self._main(args)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\cli\base_command.py(224)_main()
-> status = self.run(options, args)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\cli\req_command.py(180)wrapper()
-> return func(self, options, args)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\commands\install.py(321)run()
-> reqs, check_supported_wheels=not options.target_dir
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\resolution\resolvelib\resolver.py(122)resolve()
-> requirements, max_rounds=try_to_avoid_resolution_too_deep,
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\resolvelib\resolvers.py(445)resolve()
-> state = resolution.resolve(requirements, max_rounds=max_rounds)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\resolvelib\resolvers.py(310)resolve()
-> name, crit = self._merge_into_criterion(r, parent=None)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\resolvelib\resolvers.py(173)_merge_into_criterion()
-> crit = Criterion.from_requirement(self._p, requirement, parent)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\resolvelib\resolvers.py(82)from_requirement()
-> if not cands:
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\resolvelib\structs.py(124)__bool__()
-> return bool(self._sequence)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py(96)__bool__()
-> return any(self)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py(20)_deduplicated_by_version()
-> for candidate in candidates:
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\resolution\resolvelib\factory.py(194)iter_index_candidates()
-> hashes=hashes,
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\package_finder.py(882)find_best_candidate()
-> candidates = self.find_all_candidates(project_name)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\package_finder.py(826)find_all_candidates()
-> project_url, link_evaluator=link_evaluator,
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\package_finder.py(789)process_project_url()
-> html_page = self._link_collector.fetch_page(project_url)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\collector.py(618)fetch_page()
-> return _get_html_page(location, session=self.session)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\collector.py(430)_get_html_page()
-> resp = _get_html_response(url, session=session)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\index\collector.py(144)_get_html_response()
-> "Cache-Control": "max-age=0",
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\requests\sessions.py(555)get()
-> return self.request('GET', url, **kwargs)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\network\session.py(428)request()
-> return super(PipSession, self).request(method, url, *args, **kwargs)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\requests\sessions.py(528)request()
-> prep = self.prepare_request(req)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\requests\sessions.py(466)prepare_request()
-> hooks=merge_hooks(request.hooks, self.hooks),
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\requests\models.py(320)prepare()
-> self.prepare_auth(auth, url)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_vendor\requests\models.py(551)prepare_auth()
-> r = auth(self)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\network\auth.py(209)__call__()
-> url, username, password = self._get_url_and_credentials(req.url)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\network\auth.py(184)_get_url_and_credentials()
-> username, password = self._get_new_credentials(original_url)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\network\auth.py(156)_get_new_credentials()
-> get_keyring_auth(index_url, username) or
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\pip\_internal\network\auth.py(58)get_keyring_auth()
-> cred = get_credential(url, username)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\core.py(70)get_credential()
-> return get_keyring().get_credential(service_name, username)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\core.py(32)get_keyring()
-> init_backend()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\core.py(81)init_backend()
-> set_keyring(_detect_backend(limit))
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\core.py(99)_detect_backend()
-> filter(limit, backend.get_all_keyring()),
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\util\__init__.py(22)wrapper()
-> func.always_returns = func(*args, **kwargs)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\backend.py(215)get_all_keyring()
-> _load_plugins()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\backend.py(202)_load_plugins()
-> init_func = ep.load()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\importlib_metadata\__init__.py(100)load()
-> module = import_module(match.group('module'))
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\importlib\__init__.py(126)import_module()
-> return _bootstrap._gcd_import(name[level:], package, level)
  <frozen importlib._bootstrap>(994)_gcd_import()
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(665)_load_unlocked()
  <frozen importlib._bootstrap_external>(678)exec_module()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\keyring\backends\windows.py(12)<module>()
-> from win32ctypes.pywin32 import pywintypes
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(665)_load_unlocked()
  <frozen importlib._bootstrap_external>(678)exec_module()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\win32ctypes\pywin32\__init__.py(11)<module>()
-> from win32ctypes.pywin32 import win32api
  <frozen importlib._bootstrap>(1023)_handle_fromlist()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(665)_load_unlocked()
  <frozen importlib._bootstrap_external>(678)exec_module()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\win32ctypes\pywin32\win32api.py(12)<module>()
-> from win32ctypes.core import (
  <frozen importlib._bootstrap>(1023)_handle_fromlist()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(656)_load_unlocked()
  <frozen importlib._bootstrap>(626)_load_backward_compatible()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\win32ctypes\core\__init__.py(36)load_module()
-> module = importlib.import_module(self.redirect_module)
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\importlib\__init__.py(126)import_module()
-> return _bootstrap._gcd_import(name[level:], package, level)
  <frozen importlib._bootstrap>(994)_gcd_import()
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(665)_load_unlocked()
  <frozen importlib._bootstrap_external>(678)exec_module()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\win32ctypes\core\cffi\_common.py(12)<module>()
-> from ._util import ffi
  <frozen importlib._bootstrap>(971)_find_and_load()
  <frozen importlib._bootstrap>(955)_find_and_load_unlocked()
  <frozen importlib._bootstrap>(665)_load_unlocked()
  <frozen importlib._bootstrap_external>(678)exec_module()
  <frozen importlib._bootstrap>(219)_call_with_frames_removed()
  c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\win32ctypes\core\cffi\_util.py(16)<module>()
-> ffi = FFI()
> c:\jenkins\shiningpanda\jobs\13bb4b33\virtualenvs\d41d8cd9\lib\site-packages\cffi\api.py(47)__init__()
-> if backend is None:

@ovianao
Copy link

ovianao commented Feb 24, 2021

@jaraco, try this:
pip-run -q "keyring==21.6.0" "cffi==1.13.2" -- -m pip-run cffi -- -m pip install "cffi>1.13.2"

@jaraco
Copy link
Member

jaraco commented Feb 24, 2021

I couldn't install cffi 1.13.2 due to compiler configuration, but I was able to replicate the issue thus:

PS C:\> pip-run -q keyring "cffi<1.14.5" -- -m pip install -U cffi
Requirement already satisfied: cffi in c:\users\containeradministrator\appdata\local\temp\pip-run-pi6rtixx (1.14.4)
Collecting cffi
  Using cached cffi-1.14.5-cp39-cp39-win_amd64.whl (179 kB)
Requirement already satisfied: pycparser in c:\users\containeradministrator\appdata\local\temp\pip-run-pi6rtixx (from cffi) (2.20)       
Installing collected packages: cffi
  Attempting uninstall: cffi
    Found existing installation: cffi 1.14.4
    Uninstalling cffi-1.14.4:
      Successfully uninstalled cffi-1.14.4
ERROR: Could not install packages due to an OSError: [WinError 5] Access is denied: 'C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp\\pip-uninstall-jok6i4x_\\_cffi_backend.cp39-win_amd64.pyd'
Consider using the `--user` option or check the permissions.

@jaraco
Copy link
Member

jaraco commented Feb 24, 2021

Looks like the issue was fixed in #8687.

PS C:\> pip-run -q git+https://github.com/pypa/pip keyring "cffi<1.14.5" -- -m pip install -U cffi
Requirement already satisfied: cffi in c:\users\containeradministrator\appdata\local\temp\pip-run-dca5watx (1.14.4)
Collecting cffi
  Using cached cffi-1.14.5-cp39-cp39-win_amd64.whl (179 kB)
Requirement already satisfied: pycparser in c:\users\containeradministrator\appdata\local\temp\pip-run-dca5watx (from cffi) (2.20)       
Installing collected packages: cffi
  Attempting uninstall: cffi
    Found existing installation: cffi 1.14.4
    Uninstalling cffi-1.14.4:
      Successfully uninstalled cffi-1.14.4
Successfully installed cffi-1.14.5

@jaraco jaraco closed this as completed Feb 24, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: keyring Related to pip's keyring integration resolution: deferred till PR Further discussion will happen when a PR is made type: feature request Request for a new feature
Projects
None yet
Development

No branches or pull requests

7 participants