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

uv fails to install jupyter_contrib_nbextensions==0.7.0 while pip succeeds #8884

Closed
leodevian opened this issue Nov 7, 2024 · 25 comments · Fixed by #8907
Closed

uv fails to install jupyter_contrib_nbextensions==0.7.0 while pip succeeds #8884

leodevian opened this issue Nov 7, 2024 · 25 comments · Fixed by #8907
Assignees
Labels
windows Specific to the Windows platform

Comments

@leodevian
Copy link

leodevian commented Nov 7, 2024

Hello,

I'm using uv 0.4.30 (61ed2a2 2024-11-04) on Windows and I'm trying to install jupyter_contrib_nbextensions==0.7.0. It seems that uv fails to install the package as it cannot be built with the latest versions of setuptools, due to some deprecations.

uv pip install jupyter_contrib_nbextensions==0.7.0

However, the latest version of pip (24.3.1) succeeds to build and install the package and I would like to understand this difference in behavior.

pip install jupyter_contrib_nbextensions==0.7.0

I read the documentation on build failures and I don't understand if I can force a version of setuptools and wheel for jupyter_contrib_nbextensions.

Also, can I manage this package with uv if it has been installed using pip?

Thank you for your awesome work!

@FishAlchemist
Copy link
Contributor

FishAlchemist commented Nov 7, 2024

I'm a Windows user and I couldn't reproduce the problem you mentioned.
Furthermore, according to your description, the package installed with uv is not the same as the one installed with pip. (Corrected)

@FishAlchemist
Copy link
Contributor

@leodevian
I suggest you provide more complete information. After all, if we can't reproduce the issue, we won't know what the error message is. As for the method, at least add --verbose to get complete information.

@leodevian
Copy link
Author

Thanks for your quick feedback! Indeed, I did mispell the package name in the description (now edited).

The following command should reproduce the issue:

mkdir issue
cd issue
uv venv -p 3.11 *> log.txt
uv pip install jupyter_contrib_nbextensions==0.7.0 -vvv *>> log.txt

I'm using cpython-3.11.10-windows-x86_64-none, which has been installed using uv.

Here are the logs with --verbose (I'm not used to redirection and struggled to get them).

log.txt

@FishAlchemist
Copy link
Contributor

FishAlchemist commented Nov 7, 2024

@leodevian Could you provide the pyproject.toml that can reproduce this issue? Because when I tried your problem, I used a default pyproject.toml.

Edit:
But it has a lot of warnings.

@leodevian
Copy link
Author

leodevian commented Nov 7, 2024

@FishAlchemist I don't have pyproject.toml in my directory.

I tried the following commands and it still failed with the same error:

mkdir issue
cd issue
uv init -p 3.11
uv add jupyter_contrib_nbextensions==0.7.0

It seems that pip succeeds to build a wheel while uv fails?

EDIT: I don't understand the difference in behavior. Does pip support deprecated methods that have not been implemented in uv?

@charliermarsh charliermarsh added the needs-mre Needs more information for reproduction label Nov 7, 2024
@charliermarsh
Copy link
Member

Are you perhaps hitting the filename length limit on Windows?

@leodevian
Copy link
Author

The directory is located in %USERPROFILE%, which is 18 characters long, so I doubt it.

I will try to reproduce the issue on my personal computer later, to investigate further.

@FishAlchemist
Copy link
Contributor

Are you perhaps hitting the filename length limit on Windows?

It seems possible, as my computer enable Long Paths.

To check if it's enabled, you can simply open PowerShell to query. Reading the registry doesn't require administrative privileges.

Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
∙ -Name "LongPathsEnabled"

@charliermarsh
Copy link
Member

Yes but the error you shared is for build\lib\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md which will already be nested inside the build cache directory.

@leodevian
Copy link
Author

leodevian commented Nov 7, 2024

I don't have it and I have no admin rights on this computer. I will give your more information once I tried to reproduce the issue on my personal computer (with admin rights).

Could it be that building universal wheels is not supported by uv? To me, it seems that this feature has been deprecated for quite some time...

From the logs:

With Python 2.7 end-of-life, support for building universal wheels
        (i.e., wheels that support both Python 2 and Python 3)
        is being obviated.

@FishAlchemist
Copy link
Contributor

FishAlchemist commented Nov 7, 2024

Yes but the error you shared is for build\lib\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md which will already be nested inside the build cache directory.

@charliermarsh Yes, I just closed the long path, and then the problem occurred

Edit:
Can UV detect long paths that are not enabled during the build phase?


@leodevian This is the configuration method provided by Microsoft.
https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#registry-setting-to-enable-long-paths

@charliermarsh charliermarsh added windows Specific to the Windows platform and removed needs-mre Needs more information for reproduction labels Nov 7, 2024
@leodevian
Copy link
Author

@FishAlchemist Thanks a lot! I guess that's good news.

It pains me because I'm promoting uv within my organization and no one will be able to disable the maximum file path limitation because of internal policies...

@leodevian
Copy link
Author

Is it possible to bypass the limitation using \\?\?

Here is how I would do it using Python.

import os

longpath = "..."

longpath = os.path.realpath(longpath)

unc = "\\\\?\\" if len(longpath) >= 260 else ""

os.mkdir(unc + longpath)

with open(unc + os.path.join(longpath, "hello.txt"), "w") as f:
    f.write("Hello world!")

@charliermarsh
Copy link
Member

I don't believe so. Using those UNC paths breaks a lot of things -- for example, any relative paths in the build will be interpreted relative to the drive: #1277

@leodevian
Copy link
Author

leodevian commented Nov 7, 2024

Well, I had mitigated hopes on this... I hope that I won't encounter this issue too many times. Meanwhile, I'll look for a workaround.

Is it possible to install a package using pip and still manage it using uv (so it won't be uninstalled with uv sync or uv add)?

@charliermarsh
Copy link
Member

I'll look into reducing the length of the cache path.

@charliermarsh
Copy link
Member

I actually don't really understand why this succeeds with pip but not uv. Their build cache prefix isn't any shorter, and even when I set --cache-dir to something short, uv still fails.

@FishAlchemist
Copy link
Contributor

@charliermarsh I've tracked program's behavior, and it should serve as a reference.
The nesting of the UV cache seems quite deep, but pip seems to have only the nesting of the source code.

UV (uv 0.4.30 (61ed2a2 2024-11-04))

( maximum 233 without user home path)

~\AppData\Local\Temp\.tmpyBcss8\sdists-v5\pypi\jupyter-contrib-nbextensions\0.7.0\Jk8_nRpxZF8Zdq-pjfEJr\jupyter_contrib_nbextensions-0.7.0.tar.gz\build\lib\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md

PIP (pip 24.3.1)

(maximum 209 without user home path)

~\AppData\Local\Temp\pip-install-7pgurthd\jupyter-contrib-nbextensions_0d7b5c639ab74a4fb664a5235eb7c74d\src\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md
~\AppData\Local\Temp\pip-install-7pgurthd\jupyter-contrib-nbextensions_0d7b5c639ab74a4fb664a5235eb7c74d\build\lib\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md
~\AppData\Local\Temp\pip-install-7pgurthd\jupyter-contrib-nbextensions_0d7b5c639ab74a4fb664a5235eb7c74d\build\bdist.win-amd64\wheel\jupyter_contrib_nbextensions\nbextensions\code_prettify\README_code_prettify.md

@konstin
Copy link
Member

konstin commented Nov 7, 2024

Collecting clues:

With pip install jupyter_contrib_nbextensions==0.7.0:

  copying build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding\main.js -> build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\codefolding
  copying build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding\readme.md -> build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\codefolding
  creating build\bdist.win-amd64\wheel\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions
  copying build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions\codemirror_mode_extensions.yaml -> build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions

With uv pip install jupyter_contrib_nbextensions==0.7.0, but also with uv pip install jupyter_contrib_nbextensions==0.7.0 --cache-dir C:\Users\Konsti\a:

copying src\jupyter_contrib_nbextensions\nbextensions\codefolding\main.js -> build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding
copying src\jupyter_contrib_nbextensions\nbextensions\codefolding\readme.md -> build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding
creating build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions
copying src\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions\codemirror_mode_extensions.yaml -> build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions

With uv pip install jupyter_contrib_nbextensions==0.7.0 --cache-dir asdf in C:\Users\Konsti\projects\uv\:

copying src\jupyter_contrib_nbextensions\nbextensions\codefolding\main.js -> build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding
copying src\jupyter_contrib_nbextensions\nbextensions\codefolding\readme.md -> build\lib\jupyter_contrib_nbextensions\nbextensions\codefolding
creating build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions
copying src\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions\codemirror_mode_extensions.yaml -> build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions
copying src\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions\main.js -> build\lib\jupyter_contrib_nbextensions\nbextensions\codemirror_mode_extensions
creating build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\collapsible_headings.yaml -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\icon.png -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\main.css -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\main.js -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\readme.md -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
copying src\jupyter_contrib_nbextensions\nbextensions\collapsible_headings\screenshot.png -> build\lib\jupyter_contrib_nbextensions\nbextensions\collapsible_headings
creating build\lib\jupyter_contrib_nbextensions\nbextensions\comment-uncomment
copying src\jupyter_contrib_nbextensions\nbextensions\comment-uncomment\comment-uncomment.yaml -> build\lib\jupyter_contrib_nbextensions\nbextensions\comment-uncomment
copying src\jupyter_contrib_nbextensions\nbextensions\comment-uncomment\icon.png -> build\lib\jupyter_contrib_nbextensions\nbextensions\comment-uncomment
copying src\jupyter_contrib_nbextensions\nbextensions\comment-uncomment\main.js -> build\lib\jupyter_contrib_nbextensions\nbextensions\comment-uncomment
copying src\jupyter_contrib_nbextensions\nbextensions\comment-uncomment\readme.md -> build\lib\jupyter_contrib_nbextensions\nbextensions\comment-uncomment
creating build\lib\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item
copying src\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item\README.md -> build\lib\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item
copying src\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item\contrib_nbextensions_help_item.yaml -> build\lib\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item

I can also uv build in the repo

@charliermarsh
Copy link
Member

@konstin -- You may need to use --use-pep517 in pip install (it still failed for me, but I think the behavior may be different).

@charliermarsh
Copy link
Member

Oh my guess is the problem is this huge prefix? sdists-v5\pypi\jupyter-contrib-nbextensions\0.7.0\Jk8_nRpxZF8Zdq-pjfEJr\jupyter_contrib_nbextensions-0.7.0.tar. I need to trace this.

@charliermarsh
Copy link
Member

charliermarsh commented Nov 7, 2024

So sketching this out... When we go to install that wheel:

  1. We create a new revision in the cache, like ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr.
  2. We stream-unzip the contents into a temporary directory within ${UV_CACHE_DIR}/sdists-v5, like ${UV_CACHE_DIR}/sdists-v5/.tmpyBcss8.
  3. We move the temporary directory to into the sdists-v5 bucket, e.g., we move it to ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/jupyter_contrib_nbextensions-0.7.0.tar.gz (this is a directory, despite the filename).
  4. We then build the source that has been extracted to ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/jupyter_contrib_nbextensions-0.7.0.tar.gz.
  5. To build, we create a virtual environment in a temporary directory in ${UV_CACHE_DIR}/builds-v0, like ${UV_CACHE_DIR}/builds-v0/.tmay5cs91.
  6. To build, we create a temporary directory within the target directory... So, like: ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/.tmpQWxTfb. Then we build the wheel using and into that directory (i.e., it's the output directory passed to the PEP 517 hooks).
  7. We then rename the built wheel them to, e.g., ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/interpreters_pep_734-0.4.0-py3-none-any.whl (this is a file).
  8. We then unzip the built distribution:
    • First, we create a temporary direcotry in the cache root (e.g., ${UV_CACHE_DIR}/.tmay5cs91).
    • Then we unzip into that directory.
    • Then we persist it in the archive bucket (e.g., we rename it to ${UV_CACHE_DIR}/archive-v0/5ZQyJUPRJyOe8jCGM3gql).
    • Then we create a symlink from the archive bucket to the sdists-v5 bucket (e.g., ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/interpreters_pep_734-0.4.0-py3-none-any).

@charliermarsh
Copy link
Member

I think one thing we should definitely change is that we shouldn't build the wheel into ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr/.tmpQWxTfb. That's just a huge path and there's no reason for it? I'll do that first.

@charliermarsh
Copy link
Member

We may also want to consider shortening ${UV_CACHE_DIR}/sdists-v5/pypi/jupyter-contrib-nbextensions/0.7.0/Jk8_nRpxZF8Zdq-pjfEJr. It's just a huge path. And if you use a non-PyPI index, it's even longer because the pypi segment gets expanded to, e.g., index/6934cf8789bf06c0.

@charliermarsh
Copy link
Member

Okay cool, I just got this package to build on my machine. It'll be a series of small PRs.

charliermarsh added a commit that referenced this issue Nov 8, 2024
## Summary

See: #8884. We build in a
directory that's deep within the cache; to help with file name length
limits, we should build at the top-level of the cache.
charliermarsh added a commit that referenced this issue Nov 8, 2024
## Summary

In the example outlined in #8884,
this removes an unnecessary `jupyter_contrib_nbextensions-0.7.0.tar.gz`
segment (replacing it with `src`), thereby saving 39 characters and
getting that build working on my Windows machine.

This should _not_ require a version bump because we already have logic
in place to "heal" partial cache entries that lack an unzipped
distribution.

Closes #8884.

Closes #7376.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
windows Specific to the Windows platform
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants