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

fix: installing wheel from trailing slash url #4619

Closed

Conversation

pechersky
Copy link

@pechersky pechersky commented Oct 10, 2021

Pull Request Check List

Resolves: n/a

Provide a step-by-step description of the suggested enhancement in as many details as possible.

Currently, the poetry add ... code looks for wheels or sdists at a pypi at an index url. In some cases, the url the server sends back might be of the form https://my.pypi.server/path/to/my_package.whl/. Unfortunately, the code currently does an rsplit and keeps only the terminal result of that split. For such a url, this is the empty string. This causes the filename to where the wheel is to be written to is empty-string. That means poetry add tries to write a file to /tmp/tmpdircreated, which is a directory, which fails.

The expected behavior is proper installation/addition of a package. This is done via a slightly more complicated parsing of the url. If the terminal item after rsplitting is empty, then use the penultimate item instead.

Unfortunately, I cannot provide an explicit example of the url that causes the issue, because it is in a private pypi.

  • Added tests for changed code.
    There are no existing test cases for this particular code path. A single test might not make sense, it only could be an integration test.
  • Updated documentation for changed code.
    The current documentation says nothing about the urls the server sends back.

@pechersky
Copy link
Author

For discoverability, this is a possible solution for an error that looks like

 $ poetry update
 Updating dependencies
 Resolving dependencies... (1.4s)
 
   IsADirectoryError
 
   [Errno 21] Is a directory: '/tmp/tmpbs3xycu6'
 
   at ~/.pyenv/versions/3.8.8/envs/my-env/lib/python3.8/site-packages/poetry/utils/helpers.py:101 in download_file
        97│
        98│     with get(url, stream=True) as response:
        99│         response.raise_for_status()
       100│
     → 101│         with open(dest, "wb") as f:
       102│             for chunk in response.iter_content(chunk_size=chunk_size):
       103│                 if chunk:
       104│                     f.write(chunk)
       105│

@coleb
Copy link

coleb commented Nov 5, 2021

I'm running into this issue as well even when trying to get poetry to update itself:

$ poetry update self
Updating dependencies
Resolving dependencies... (1.4s)

  IsADirectoryError

  [Errno 21] Is a directory: '/var/folders/xf/dz91t9wj1znc5npw2yq8xzww0000gr/T/tmp5622k9o_'

  at ~/.poetry/lib/poetry/utils/helpers.py:101 in download_file
       97│ 
       98│     with get(url, stream=True) as response:
       99│         response.raise_for_status()
      100│ 
    → 101│         with open(dest, "wb") as f:
      102│             for chunk in response.iter_content(chunk_size=chunk_size):
      103│                 if chunk:
      104│                     f.write(chunk)
      105│ 

When I manually apply the changes from this pull request, it works around the problem.

poetry/repositories/pypi_repository.py Outdated Show resolved Hide resolved
poetry/repositories/pypi_repository.py Outdated Show resolved Hide resolved
poetry/repositories/pypi_repository.py Outdated Show resolved Hide resolved
Debug now outputs whole url instead of just the wheel's
filename. This is more detail that does not get in the way
because it only occurs at high
verbosity.
Copy link
Member

@neersighted neersighted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! That looks really good and helps clean this up a lot.

Last step: let's add a regression test that checks that we successfully handle paths with a trailing slash.

@pechersky
Copy link
Author

Awesome! That looks really good and helps clean this up a lot.

Last step: let's add a regression test that checks that we successfully handle paths with a trailing slash.

Thanks! Sounds good. I'm not very familiar with the poetry tests structure. Are there tests that mock download? Searching for download_file, mock_download, and download_mock only gives the fixture setup code. Would the test go into test_pypi_repository.py?

@neersighted
Copy link
Member

Awesome! That looks really good and helps clean this up a lot.
Last step: let's add a regression test that checks that we successfully handle paths with a trailing slash.

Thanks! Sounds good. I'm not very familiar with the poetry tests structure. Are there tests that mock download? Searching for download_file, mock_download, and download_mock only gives the fixture setup code. Would the test go into test_pypi_repository.py?

Indeed it would! You should find some mock examples there to get you started.

@neersighted neersighted mentioned this pull request Nov 18, 2021
@pechersky
Copy link
Author

Thanks for the guidance. Unfortunately, none of the tests actually deal with the url encoded in the package json info, so I am not sure how to test codepaths on that data. The url is also not kept by PackageInfo.

Making a change in the mocked _download function:

     def _download(self, url, dest):
-        filename = url.split("/")[-1]
+        filename = self._helper_filename(url)
 
         fixture = self.DIST_FIXTURES / filename

still has all the tests pass -- but I am not sure this codepath is actually being tested.

@neersighted
Copy link
Member

@pechersky Any chance you can rebase this onto current master? I'd be happy to provide some guidance on tests via Discord if you're still struggling (unit testing the helper and then mocking the install method and passing in a URL with a trailing slash out to be sufficient).

Copy link

github-actions bot commented Mar 3, 2024

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 3, 2024
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 this pull request may close these issues.

3 participants