poetry: ValueError, whl in cache does not exist when running poetry install again
- 
I am on the latest Poetry version.
 - 
I have searched the issues of this repo and believe that this is not a duplicate.
 - 
If an exception occurs when executing a command, I executed it again in debug mode (
-vvvoption). - 
Windows 10 1909
 - 
poetry version: 1.2.0a1
 - 
Link of a Gist with the contents of your pyproject.toml file: https://gist.github.com/Transmitt0r/ed8414abd90efaef9d4453ec05c48e1c
 
Issue
Hey everyone, I’m having issues when trying to run poetry install via jenkins. poetry config virtualenvs.in-project is true. The install fails on the second installation attempt (always). It seems that there is an issue with the way caching works. Here is the trace: Thanks in advance!
de\user@PC C:\workspace>poetry install -vvv 
Loading configuration file C:\Users\user\AppData\Roaming\pypoetry\config.toml
Adding repository private (https://artifactory-url.de)
Creating virtualenv envname in C:\workspace\.venv
Using virtualenv: C:\workspace\.venv
Installing dependencies from lock file
Finding the necessary packages for the current system
Package operations: 20 installs, 0 updates, 0 removals, 3 skipped
  • Removing importlib-metadata (4.5.0): Skipped for the following reason: Not currently installed
  • Removing typing-extensions (3.10.0.0): Skipped for the following reason: Not currently installed
  • Removing zipp (3.4.1): Skipped for the following reason: Not currently installed
  • Installing pyparsing (2.4.7)
  Stack trace:
  6  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:244 in _execute_operation
      242| 
      243|             try:
    > 244|                 result = self._do_execute_operation(operation)
      245|             except EnvCommandError as e:
      246|                 if e.e.returncode == -2:
  5  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:321 in _do_execute_operation
      319|             return 0
      320| 
    > 321|         result = getattr(self, f"_execute_{method}")(operation)
      322| 
      323|         if result != 0:
  4  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:462 in _execute_install
      460| 
      461|     def _execute_install(self, operation: Union[Install, Update]) -> int:
    > 462|         status_code = self._install(operation)
      463| 
      464|         self._save_url_reference(operation)
  3  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:498 in _install
      496|             archive = self._download_link(operation, Link(package.source_url))
      497|         else:
    > 498|             archive = self._download(operation)
      499| 
      500|         operation_message = self.get_operation_message(operation)
  2  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:648 in _download
      646|         link = self._chooser.choose_for(operation.package)
      647| 
    > 648|         return self._download_link(operation, link)
      649| 
      650|     def _download_link(self, operation: Union[Install, Update], link: Link) -> Link:
  1  c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\installation\executor.py:676 in _download_link
      674|             archive_hash = (
      675|                 "sha256:"
    > 676|                 + FileDependency(
      677|                     package.name,
      678|                     Path(archive.path) if isinstance(archive, Link) else archive,
  ValueError
  File \C:\Users\user\AppData\Local\pypoetry\Cache\artifacts\92\0f\cf\effdcd5d76a6186df0969f85b3b030284ff8058936d5016540b5258ea3\pyparsing-2.4.7-py2.py3-none-any.whl does not exist
  at c:\users\user\appdata\roaming\pypoetry\venv\lib\site-packages\poetry\core\packages\file_dependency.py:41 in __init__
       37|             except FileNotFoundError:
       38|                 raise ValueError("Directory {} does not exist".format(self._path))
       39| 
       40|         if not self._full_path.exists():
    >  41|             raise ValueError("File {} does not exist".format(self._path))
       42| 
       43|         if self._full_path.is_dir():
       44|             raise ValueError("{} is a directory, expected a file".format(self._path))
       45| 
About this issue
- Original URL
 - State: closed
 - Created 3 years ago
 - Reactions: 24
 - Comments: 18
 
Commits related to this issue
- [1.1] fix: Broken cache on Windows (#4549) Backport of #4531, fixes #4163 and #4535. — committed to python-poetry/poetry by serverwentdown 3 years ago
 
Also have this issue with 1.1.8 on Windows 10. My workaround is to go to the path specified, delete the cache and run
poetry installagain.e.g.
Go to
C:\Users\julie\AppData\Local\pypoetry\Cache, delete everything.Run
poetry installagain and:Hope it helps other people in the meantime!
I found some much better PRs that already had some eyes, not sure what the path to get the PRs merged is.
1.1: #4549 1.2+: #4531
I found the culprit!
https://github.com/python-poetry/poetry/blob/e180aab14bdc1d0c9e76b2717fd0de189d26fddd/poetry/installation/executor.py#L673-L680
At this point,
archiveis always going to be a file URL because it’s been downloaded and cached. ButLink.pathis broken for file URLs on Windows, so the patch is as follows:https://github.com/python-poetry/poetry-core/blob/ad33bc2f92be03dc5b31a666664903c439fb1173/poetry/core/packages/utils/link.py#L9 becomes:
and
https://github.com/python-poetry/poetry-core/blob/ad33bc2f92be03dc5b31a666664903c439fb1173/poetry/core/packages/utils/link.py#L103-L105 becomes
Unfortunately this impacts a number of places where improper path handling happens, mainly in the executor module. It’s a rabbit hole for sure and I need to look at my local edits and compare with a fresh clone to get ALL of the spots I changed code.
In hindsight, it may be better to leave Link.path alone and instead fix all of the misuses of it.
After patching Link.path to properly handle Windows file URIs, poetry still fails to install the cached package:
This is because Executor.pip_install is being called with a string
reqcontaining - yet again - a Windows file URI. When this URI string gets passed to pip_install, it’s used to construct a Path, which, like the original Link.path, also doesn’t quite understand URIs:We can get around this by using the fixed Link.path to “sanitize” string inputs to Executor.pip_install, stripping away the URI prefix before passing it to the utility pip_install function.
With these two changes, I can successfully install from the cache.
I ran into this same issue today.
Calling
urllib.parse.urlspliton a Windowsfilescheme URI (file:///C:/Users/...) leaves the extra leading/in the result’spathattribute.We can strip this character by passing the malformed
pathintourllib.request.url2pathname()to get a valid Windows-style path string.Note that
url2pathnameis only recommended for use onfilescheme URIs, and it basically just wrapsurllib.parse.unquoteon non-Windows systems.[0] On Windows, it ends up usingnturl2path.url2pathname.[1]In fact,
pipalso usesurl2pathname, along with some extra logic to handle the special case of a Windows UNC path (e.g. for shared network folders).[2][0] https://github.com/python/cpython/blob/3.9/Lib/urllib/request.py#L1675 [1] https://github.com/python/cpython/blob/v3.6.1/Lib/nturl2path.py#L3 [2] https://github.com/pypa/pip/blob/9.0.1/pip/download.py#L442
I made two PRs:
https://github.com/python-poetry/poetry/pull/4651 and https://github.com/python-poetry/poetry-core/pull/222
I made them with the suggestions from this issue. I can not repro @vsutardja’s issue that required a fixed executor (when I applied the fixes to Link.path my repro went away). I don’t know if the fixes @jgentil is mentioning in executor.py still need to be put into the PRs.
using version 1.1.10 here, same issue downgraded to 1.0.8 works fine