pyodide / micropip

A lightweight Python package installer for Pyodide
https://micropip.pyodide.org
Mozilla Public License 2.0
68 stars 16 forks source link

ValueError: Requested 'pyrate-limiter<3.0', but pyrate-limiter==3.6.1 is already installed #106

Open njzjz opened 1 month ago

njzjz commented 1 month ago

In https://jupyter.org/try-jupyter/lab/, execute

import piplite
await piplite.install(["requests-ratelimiter", "pyrate-limiter"])

Got this error.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[1], line 2
      1 import piplite
----> 2 await piplite.install(["requests-ratelimiter", "pyrate-limiter"])

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:290, in Transaction.add_requirement_inner(self, req)
    287 # Is some version of this package is already installed?
    288 req.name = canonicalize_name(req.name)
--> 290 satisfied, ver = self.check_version_satisfied(req)
    291 if satisfied:
    292     logger.info(f"Requirement already satisfied: {req} ({ver})")

File /lib/python3.11/site-packages/micropip/transaction.py:235, in Transaction.check_version_satisfied(self, req)
    231 if req.specifier.contains(ver, prereleases=True):
    232     # installed version matches, nothing to do
    233     return True, ver
--> 235 raise ValueError(
    236     f"Requested '{req}', " f"but {req.name}=={ver} is already installed"
    237 )

ValueError: Requested 'pyrate-limiter<3.0', but pyrate-limiter==3.6.1 is already installed

While requests-ratelimiter needs pyrate-limiter<3.0, I don't expect it to throw ValueError.

ryanking13 commented 1 month ago

This is because micropip uses a very simple (and somehow stupid) dependency resolver for responsiveness. The workaround would be installing pyrate-limiter<3.0.0 first before installing other packages, then install other packages.