jupyter-widgets / ipywidgets

Interactive Widgets for the Jupyter Notebook
https://ipywidgets.readthedocs.io
BSD 3-Clause "New" or "Revised" License
3.14k stars 948 forks source link

ipywidgets version 8.1.3 does not %pip install in jupyterlite #3925

Closed ManonMarchand closed 3 months ago

ManonMarchand commented 3 months ago

Hi!

Description

In jupyterlite, for example with this instance https://jtp.io/anywidget-lite/lab/index.html , executing in a cell

%pip install ipywidgets

Raises the following error:

Details

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[1], line 1 ----> 1 await __import__("piplite").install(**{'requirements': ['ipywidgets']}) File /lib/python3.11/site-packages/piplite/piplite.py:117, in _install(requirements, keep_going, deps, credentials, pre, index_urls, verbose) 115 """Invoke micropip.install with a patch to get data from local indexes""" 116 with patch("micropip.package_index.query_package", _query_package): --> 117 return await micropip.install( 118 requirements=requirements, 119 keep_going=keep_going, 120 deps=deps, 121 credentials=credentials, 122 pre=pre, 123 index_urls=index_urls, 124 verbose=verbose, 125 ) File /lib/python3.11/site-packages/micropip/_commands/install.py:142, in install(requirements, keep_going, deps, credentials, pre, index_urls, verbose) 130 index_urls = package_index.INDEX_URLS[:] 132 transaction = Transaction( 133 ctx=ctx, 134 ctx_extras=[], (...) 140 index_urls=index_urls, 141 ) --> 142 await transaction.gather_requirements(requirements) 144 if transaction.failed: 145 failed_requirements = ", ".join([f"'{req}'" for req in transaction.failed]) File /lib/python3.11/site-packages/micropip/transaction.py:204, in Transaction.gather_requirements(self, requirements) 201 for requirement in requirements: 202 requirement_promises.append(self.add_requirement(requirement)) --> 204 await asyncio.gather(*requirement_promises) File /lib/python3.11/site-packages/micropip/transaction.py:211, in Transaction.add_requirement(self, req) 208 return await self.add_requirement_inner(req) 210 if not urlparse(req).path.endswith(".whl"): --> 211 return await self.add_requirement_inner(Requirement(req)) 213 # custom download location 214 wheel = WheelInfo.from_url(req) File /lib/python3.11/site-packages/micropip/transaction.py:300, in Transaction.add_requirement_inner(self, req) 297 if self._add_requirement_from_pyodide_lock(req): 298 return --> 300 await self._add_requirement_from_package_index(req) 301 else: 302 try: File /lib/python3.11/site-packages/micropip/transaction.py:347, in Transaction._add_requirement_from_package_index(self, req) 344 if satisfied: 345 logger.info(f"Requirement already satisfied: {req} ({ver})") --> 347 await self.add_wheel(wheel, req.extras, specifier=str(req.specifier)) File /lib/python3.11/site-packages/micropip/transaction.py:385, in Transaction.add_wheel(self, wheel, extras, specifier) 383 await wheel.download(self.fetch_kwargs) 384 if self.deps: --> 385 await self.gather_requirements(wheel.requires(extras)) 387 self.wheels.append(wheel) File /lib/python3.11/site-packages/micropip/transaction.py:204, in Transaction.gather_requirements(self, requirements) 201 for requirement in requirements: 202 requirement_promises.append(self.add_requirement(requirement)) --> 204 await asyncio.gather(*requirement_promises) File /lib/python3.11/site-packages/micropip/transaction.py:208, in Transaction.add_requirement(self, req) 206 async def add_requirement(self, req: str | Requirement) -> None: 207 if isinstance(req, Requirement): --> 208 return await self.add_requirement_inner(req) 210 if not urlparse(req).path.endswith(".whl"): 211 return await self.add_requirement_inner(Requirement(req)) File /lib/python3.11/site-packages/micropip/transaction.py:300, in Transaction.add_requirement_inner(self, req) 297 if self._add_requirement_from_pyodide_lock(req): 298 return --> 300 await self._add_requirement_from_package_index(req) 301 else: 302 try: File /lib/python3.11/site-packages/micropip/transaction.py:339, in Transaction._add_requirement_from_package_index(self, req) 331 """ 332 Find requirement from package index. If the requirement is found, 333 add it to the package list and return True. Otherwise, return False. 334 """ 335 metadata = await package_index.query_package( 336 req.name, self.fetch_kwargs, index_urls=self.index_urls 337 ) --> 339 wheel = find_wheel(metadata, req) 341 # Maybe while we were downloading pypi_json some other branch 342 # installed the wheel? 343 satisfied, ver = self.check_version_satisfied(req) File /lib/python3.11/site-packages/micropip/transaction.py:431, in find_wheel(metadata, req) 428 if best_wheel is not None: 429 return wheel --> 431 raise ValueError( 432 f"Can't find a pure Python 3 wheel for '{req}'.\n" 433 f"See: {FAQ_URLS['cant_find_wheel']}\n" 434 "You can use `await micropip.install(..., keep_going=True)` " 435 "to get a list of all packages with missing wheels." 436 )

ValueError: Can't find a pure Python 3 wheel for 'widgetsnbextension~=4.0.11'.
See: https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package
You can use `await micropip.install(..., keep_going=True)` to get a list of all packages with missing wheels.

Maybe something changed with widgetsnbextension 4.0.11? The version 4.0.10 works fine. Pinning the ipywidgets version to 8.1.2 works fine too.

Context

martinRenou commented 3 months ago

Thanks for opening an issue, I believe this should go in https://github.com/jupyterlite/pyodide-kernel/issues

jtpio commented 3 months ago

We should look into fixing this in the pyodide kernel at some point since this is an issue with every ipywidgets release.